So bauen Sie Ihr eigenes Kommentarsystem mit Firebase auf
Veröffentlicht: 2022-03-10Ein Kommentarbereich ist eine großartige Möglichkeit, eine Community für Ihr Blog aufzubauen. Als ich kürzlich mit dem Bloggen anfing, dachte ich daran, einen Kommentarbereich hinzuzufügen. Es war jedoch nicht einfach. Gehostete Kommentarsysteme wie Disqus und Commento haben ihre eigenen Probleme:
- Sie besitzen Ihre Daten.
- Sie sind nicht frei.
- Sie können sie nicht viel anpassen.
Also beschloss ich, mein eigenes Kommentarsystem aufzubauen. Firebase schien eine perfekte Hosting-Alternative zum Betrieb eines Back-End-Servers zu sein.
Zunächst einmal profitieren Sie von allen Vorteilen einer eigenen Datenbank: Sie haben die Kontrolle über die Daten und können sie beliebig strukturieren. Zweitens müssen Sie keinen Back-End-Server einrichten. Sie können es einfach vom Frontend aus steuern. Es ist, als hätte man das Beste aus beiden Welten: ein gehostetes System ohne den Aufwand eines Backends.
In diesem Beitrag werden wir das tun. Wir werden lernen, wie man Firebase mit Gatsby, einem statischen Site-Generator, einrichtet. Aber die Prinzipien können auf jeden statischen Site-Generator angewendet werden.
Tauchen wir ein!
Was ist Firebase?
Firebase ist ein Backend as a Service, das Tools für App-Entwickler wie Datenbank, Hosting, Cloud-Funktionen, Authentifizierung, Analyse und Speicherung bietet.
Cloud Firestore (Firebase-Datenbank) ist die Funktionalität, die wir für dieses Projekt verwenden werden. Es ist eine NoSQL-Datenbank. Das bedeutet, dass es nicht wie eine SQL-Datenbank mit Zeilen, Spalten und Tabellen strukturiert ist. Sie können es sich wie einen großen JSON-Baum vorstellen.
Einführung in das Projekt
Lassen Sie uns das Projekt initialisieren, indem wir das Repository von GitHub klonen oder herunterladen.
Ich habe für jeden Schritt zwei Zweige erstellt (einen am Anfang und einen am Ende), damit Sie die Änderungen leichter nachverfolgen können.
Lassen Sie uns das Projekt mit dem folgenden Befehl ausführen:
gatsby develop
Wenn Sie das Projekt in Ihrem Browser öffnen, sehen Sie die nackten Knochen eines einfachen Blogs.

Die Kommentarfunktion funktioniert nicht. Es lädt einfach einen Beispielkommentar und protokolliert nach der Übermittlung des Kommentars die Details in der Konsole.
Unsere Hauptaufgabe besteht darin, den Kommentarbereich zum Laufen zu bringen.
Wie der Kommentarbereich funktioniert
Bevor wir irgendetwas tun, wollen wir verstehen, wie der Code für den Kommentarbereich funktioniert.
Vier Komponenten verwalten die Kommentarbereiche:
-
blog-post.js
-
Comments.js
-
CommentForm.js
-
Comment.js
Zuerst müssen wir die Kommentare für einen Beitrag identifizieren. Dies kann durch die Erstellung einer eindeutigen ID für jeden Blogbeitrag erfolgen, oder wir können den Slug verwenden, der immer eindeutig ist.
Die Datei blog-post.js
ist die Layoutkomponente für alle Blogbeiträge. Es ist der perfekte Einstiegspunkt, um den Inhalt eines Blogbeitrags zu erhalten. Dies geschieht mit einer GraphQL-Abfrage.
export const query = graphql` query($slug: String!) { markdownRemark(fields: { slug: { eq: $slug } }) { html frontmatter { title } fields { slug } } } `
Bevor wir es an die Komponente Comments.js
senden, verwenden wir die substring()
-Methode, um den nachgestellten Schrägstrich ( /
) loszuwerden, den Gatsby dem Slug hinzufügt.
const slug = post.fields.slug.substring(1, post.fields.slug.length - 1) return ( <Layout> <div className="container"> <h1>{post.frontmatter.title}</h1> <div dangerouslySetInnerHTML={{ __html: post.html }} /> <Comments comments={comments} slug={slug} /> </div> </Layout> ) }
Die Komponente Comments.js
ordnet jeden Kommentar zu und übergibt seine Daten zusammen mit allen Antworten an Comment.js
. Für dieses Projekt habe ich mich entschieden, mit dem Kommentarsystem eine Ebene tiefer zu gehen.
Die Komponente lädt auch CommentForm.js
, um alle Kommentare der obersten Ebene zu erfassen.
const Comments = ({ comments, slug }) => { return ( <div> <h2>Join the discussion</h2> <CommentForm slug={slug} /> <CommentList> {comments.length > 0 && comments .filter(comment => !comment.pId) .map(comment => { let child if (comment.id) { child = comments.find(c => comment.id === c.pId) } return ( <Comment key={comment.id} child={child} comment={comment} slug={slug} /> ) })} </CommentList> </div> ) }
Gehen wir zu CommentForm.js
über. Diese Datei ist einfach, sie rendert ein Kommentarformular und handhabt dessen Übermittlung. Die Übermittlungsmethode protokolliert einfach die Details in der Konsole.
const handleCommentSubmission = async e => { e. preventDefault() let comment = { name: name, content: content, pId: parentId ∣∣ null, time: new Date(), } setName("") setContent("") console.log(comment) }
In der Datei Comment.js
ist viel los. Zerlegen wir es in kleinere Stücke.
Erstens gibt es eine SingleComment
Komponente, die einen Kommentar rendert.
Ich verwende die Adorable-API, um einen coolen Avatar zu erhalten. Die Moment.js-Bibliothek wird verwendet, um Zeit in einem für Menschen lesbaren Format zu rendern.
const SingleComment = ({ comment }) => ( <div> <div className="flex-container"> <div className="flex"> <img src="https://api.adorable.io/avazars/65/[email protected]" alt="Avatar" /> </div> <div className="flex"> <p className="comment-author"> {comment.name} <span>says</span> </p> {comment.time} &&(<time>(moment(comment.time.toDate()).calendar()}</time>)} </div> </div> </p>{comment.content}</p> </div> )
Als nächstes in der Datei ist die Comment
-Komponente. Diese Komponente zeigt einen untergeordneten Kommentar an, wenn ihr ein untergeordneter Kommentar übergeben wurde. Andernfalls wird ein Antwortfeld gerendert, das durch Klicken auf die Schaltfläche „Antworten“ oder „Antwort abbrechen“ ein- und ausgeschaltet werden kann.
const Comment = ({ comment, child, slug }) => { const [showReplyBox, setShowReplyBox] = useState(false) return ( <CommentBox> <SingleComment comment={comment} /> {child && ( <CommentBox child className=comment-reply"> <SingleComment comment={child} /> </CommentBox> )} {!child && ( <div> {showReplyBox ? ( <div> <button className="btn bare" onClick={() => setShowReplyBoy(false)} > Cancel Reply </button> <CommentForm parentId={comment.id} slug={slug} /> </div> ) : ( <button className="btn bare" onClick={() => setShowReplyBox(true)}> Reply </button> )} </div> )} </div> )} </CommentBox>
Nachdem wir nun einen Überblick haben, gehen wir die Schritte zum Verfassen unseres Kommentarbereichs durch.
1. Fügen Sie Firebase hinzu
Lassen Sie uns zunächst Firebase für unser Projekt einrichten.
Beginnen Sie mit der Anmeldung. Gehen Sie zu Firebase und melden Sie sich für ein Google-Konto an. Wenn Sie keine haben, klicken Sie auf „Erste Schritte“.
Klicken Sie auf „Projekt hinzufügen“, um ein neues Projekt hinzuzufügen. Geben Sie einen Namen für Ihr Projekt ein und klicken Sie auf „Projekt erstellen“.

Nachdem wir ein Projekt erstellt haben, müssen wir Cloud Firestore einrichten.
Klicken Sie im linken Menü auf „Datenbank“. Sobald sich eine Seite mit der Aufschrift „Cloud Firestore“ öffnet, klicken Sie auf „Datenbank erstellen“, um eine neue Cloud Firestore-Datenbank zu erstellen.

Wenn das Popup erscheint, wählen Sie „Im Testmodus starten“. Wählen Sie als Nächstes den nächstgelegenen Cloud Firestore-Standort aus.

Sobald Sie eine Seite wie diese sehen, bedeutet dies, dass Sie Ihre Cloud Firestore-Datenbank erfolgreich erstellt haben.

Lassen Sie uns mit dem Einrichten der Logik für die Anwendung abschließen. Gehen Sie zurück zur Anwendung und installieren Sie Firebase:
yarn add firebase
Fügen Sie eine neue Datei, firebase.js
, im Stammverzeichnis hinzu. Fügen Sie diesen Inhalt darin ein:
import firebase from "firebase/app" import "firebase/firestore" var firebaseConfig = 'yourFirebaseConfig' firebase.initializeApp(firebaseConfig) export const firestore = firebase.firestore() export default firebase
Sie müssen yourFirebaseConfig
durch die für Ihr Projekt ersetzen. Klicken Sie dazu in der Firebase-App auf das Zahnradsymbol neben „Projektübersicht“.

Dies öffnet die Einstellungsseite. Klicken Sie unter der Unterüberschrift Ihrer App auf das Websymbol, das so aussieht:

Dies öffnet ein Popup. Geben Sie im Feld „App-Spitzname“ einen beliebigen Namen ein und klicken Sie auf „App registrieren“. Dadurch erhalten Sie Ihr firebaseConfig
Objekt.
<!-- The core Firebase JS SDK is always required and must be listed first --> <script src="https://www.gstatic.com/firebasejs/7.15.5/firebase-app.js"></script> <!-- TODO: Add SDKs for Firebase products that you want to use https://firebase.google.com/docs/web/setup#available-libraries --> <script> // Your web app's Firebase configuration var firebaseConfig = { ... }; // Initialize Firebase firbase.initializeApp(firebaseConfig); </script>
Kopieren Sie einfach den Inhalt des firebaseConfig
-Objekts und fügen Sie ihn in die Datei firebase.js
ein.

Ist es in Ordnung, Ihren Firebase-API-Schlüssel offenzulegen?
Jawohl. Wie von einem Google-Techniker angegeben, ist die Offenlegung Ihres API-Schlüssels in Ordnung.
Der API-Schlüssel dient ausschließlich dazu, Ihr Projekt mit der Datenbank bei Google zu identifizieren. Wenn Sie strenge Sicherheitsregeln für Cloud Firestore festgelegt haben, müssen Sie sich keine Sorgen machen, wenn jemand an Ihren API-Schlüssel gelangt.
Wir werden im letzten Abschnitt über Sicherheitsregeln sprechen.
Derzeit führen wir Firestore im Testmodus aus, daher sollten Sie den API-Schlüssel nicht der Öffentlichkeit preisgeben.
Wie verwende ich Firestore?
Sie können Daten in einem von zwei Typen speichern:
- Sammlung
Eine Sammlung enthält Dokumente. Es ist wie eine Reihe von Dokumenten. - dokumentieren
Ein Dokument enthält Daten in einem Feld-Wert-Paar.
Denken Sie daran, dass eine Sammlung nur Dokumente und keine anderen Sammlungen enthalten darf. Ein Dokument kann jedoch andere Sammlungen enthalten.
Das heißt, wenn wir eine Sammlung in einer Sammlung speichern möchten, würden wir die Sammlung in einem Dokument speichern und dieses Dokument in einer Sammlung speichern, etwa so:
{collection-1}/{document}/{collection-2}
Wie strukturiert man die Daten?
Cloud Firestore ist von Natur aus hierarchisch, daher neigen die Leute dazu, Daten wie folgt zu speichern:
blog/{blog-post-1}/content/comments/{comment-1}
Das Speichern von Daten auf diese Weise führt jedoch häufig zu Problemen.
Angenommen, Sie möchten einen Kommentar erhalten. Sie müssen nach dem Kommentar suchen, der tief in der Blog-Sammlung gespeichert ist. Dadurch wird Ihr Code fehleranfälliger. Chris Esplin empfiehlt, niemals Untersammlungen zu verwenden.
Ich würde empfehlen, Daten als abgeflachtes Objekt zu speichern:
blog-posts/{blog-post-1} comments/{comment-1}
Auf diese Weise können Sie Daten einfach abrufen und senden.
Wie bekomme ich Daten von Firestore?
Um Daten abzurufen, bietet Ihnen Firebase zwei Methoden:
-
get()
Dies dient zum einmaligen Abrufen des Inhalts. -
onSnapshot()
Diese Methode sendet Ihnen Daten und sendet dann weiterhin Updates, es sei denn, Sie kündigen.
Wie sende ich Daten an Firestore?
Genau wie beim Abrufen von Daten verfügt Firebase über zwei Methoden zum Speichern von Daten:
-
set()
Hiermit wird die ID eines Dokuments angegeben. -
add()
Dies wird verwendet, um Dokumente mit automatischen IDs zu erstellen.
Ich weiß, das war eine Menge zu verstehen. Aber keine Sorge, wir werden diese Konzepte erneut aufgreifen, wenn wir das Projekt erreichen.
2. Musterdatum erstellen
Der nächste Schritt besteht darin, einige Beispieldaten zu erstellen, die wir abfragen können. Gehen wir dazu zu Firebase.
Gehen Sie zu Cloud Firestore. Klicken Sie auf „Sammlung starten“. Geben Sie comments
für die „Sammlungs-ID“ ein und klicken Sie dann auf „Weiter“.

Klicken Sie für die „Dokument-ID“ auf „Auto-ID“. Geben Sie die folgenden Daten ein und klicken Sie auf „Speichern“.

Achten Sie beim Eingeben von Daten darauf, dass die „Felder“ und „Typen“ mit dem Screenshot oben übereinstimmen. Klicken Sie dann auf „Speichern“.
So fügen Sie einen Kommentar manuell in Firestore hinzu. Der Vorgang sieht umständlich aus, aber keine Sorge: Ab sofort kümmert sich unsere App um das Hinzufügen von Kommentaren.
Zu diesem Zeitpunkt sieht unsere Datenbank wie folgt aus: comments/{comment}
.
3. Holen Sie sich die Kommentardaten
Unsere Beispieldaten können abgefragt werden. Beginnen wir damit, die Daten für unseren Blog abzurufen.
Gehen Sie zu blog-post.js
und importieren Sie den Firestore aus der Firebase-Datei, die wir gerade erstellt haben.
import {firestore} from "../../firebase.js"
Zur Abfrage verwenden wir den useEffect
Hook von React. Wenn Sie es noch nicht getan haben, lassen Sie es uns ebenfalls importieren.
useEffect(() => { firestore .collection(`comments`) .onSnapshot(snapshot => { const posts = snapshot.docs .filter(doc => doc.data().slug === slug) .map(doc => { return { id: doc.id, ...doc.data() } }) setComments(posts) }) }, [slug])
Die zum Abrufen von Daten verwendete Methode ist onSnapshot
. Das liegt daran, dass wir auch Zustandsänderungen hören wollen. Die Kommentare werden also aktualisiert, ohne dass der Benutzer den Browser aktualisieren muss.
Wir haben die filter
und map
verwendet, um die Kommentare zu finden, deren Slug mit dem aktuellen Slug übereinstimmt.
Eine letzte Sache, an die wir denken müssen, ist die Bereinigung. Da onSnapshot
weiterhin Updates sendet, könnte dies zu einem Speicherleck in unserer Anwendung führen. Glücklicherweise bietet Firebase eine ordentliche Lösung.
useEffect(() => { const cleanUp = firestore .doc(`comments/${slug}`) .collection("comments") .onSnapshot(snapshot => { const posts = snapshot.docs.map(doc => { return { id: doc.id, ...doc.data() } }) setComments(posts) }) return () => cleanUp() }, [slug])
Wenn Sie fertig sind, führen gatsby develop
um die Änderungen zu sehen. Wir können jetzt sehen, dass unser Kommentarbereich Daten von Firebase erhält.

Lassen Sie uns daran arbeiten, die Kommentare zu speichern.
4. Kommentare speichern
Navigieren Sie zum Speichern von Kommentaren zur Datei CommentForm.js
. Importieren wir Firestore auch in diese Datei.
import { firestore } from "../../firebase.js"
Um einen Kommentar in Firebase zu speichern, verwenden wir die Methode add()
, da Firestore Dokumente mit einer Auto-ID erstellen soll.
Lassen Sie uns das in der handleCommentSubmission
Methode tun.
firestore .collection(`comments`) .add(comment) .catch(err => { console.error('error adding comment: ', err) })
Zuerst erhalten wir den Verweis auf die Kommentarsammlung und fügen dann den Kommentar hinzu. Wir verwenden auch die catch
Methode, um Fehler beim Hinzufügen von Kommentaren abzufangen.
Wenn Sie an dieser Stelle einen Browser öffnen, können Sie sehen, dass der Kommentarbereich funktioniert. Wir können neue Kommentare hinzufügen und Antworten posten. Noch erstaunlicher ist, dass alles funktioniert, ohne dass wir die Seite aktualisieren müssen.

Sie können Firestore auch überprüfen, um festzustellen, ob die Daten gespeichert werden.

Lassen Sie uns abschließend über eine entscheidende Sache in Firebase sprechen: Sicherheitsregeln.
5. Sicherheitsregeln verschärfen
Bisher haben wir Cloud Firestore im Testmodus ausgeführt. Das bedeutet, dass jeder mit Zugriff auf die URL unsere Datenbank ergänzen und lesen kann. Das ist gruselig.
Um dem entgegenzuwirken, stellt uns Firebase Sicherheitsregeln zur Verfügung. Wir können ein Datenbankmuster erstellen und bestimmte Aktivitäten in Cloud Firestore einschränken.
Zusätzlich zu den beiden grundlegenden Vorgängen (Lesen und Schreiben) bietet Firebase detailliertere Vorgänge: Abrufen, Auflisten, Erstellen, Aktualisieren und Löschen.
Eine Leseoperation kann wie folgt unterteilt werden:
-
get
Holen Sie sich ein einzelnes Dokument. -
list
Holen Sie sich eine Liste von Dokumenten oder eine Sammlung.
Eine Schreiboperation kann wie folgt unterteilt werden:
-
create
Erstellen Sie ein neues Dokument. -
update
Aktualisieren Sie ein vorhandenes Dokument. -
delete
Löschen Sie ein Dokument.
Um die Anwendung zu sichern, gehen Sie zurück zu Cloud Firestore. Geben Sie unter „Regeln“ Folgendes ein:
service cloud.firestore { match /databases/{database}/documents { match /comments/{id=**} { allow read, create; } } }
In der ersten Zeile definieren wir den Dienst, in unserem Fall Firestore. Die nächsten Zeilen teilen Firebase mit, dass alles in der comments
gelesen und erstellt werden kann.
Wenn wir das benutzt hätten:
allow read, write;
… das würde bedeuten, dass Benutzer bestehende Kommentare aktualisieren und löschen könnten, was wir nicht wollen.
Die Sicherheitsregeln von Firebase sind äußerst leistungsfähig und ermöglichen es uns, bestimmte Daten, Aktivitäten und sogar Benutzer einzuschränken.
Weiter zum Aufbau Ihres eigenen Kommentarbereichs
Herzlichen Glückwunsch! Sie haben gerade die Leistungsfähigkeit von Firebase gesehen. Es ist ein hervorragendes Tool, um sichere und schnelle Anwendungen zu erstellen.
Wir haben einen supereinfachen Kommentarbereich erstellt. Aber es hält Sie nicht davon ab, weitere Möglichkeiten zu erkunden:
- Fügen Sie Profilbilder hinzu und speichern Sie sie in Cloud Storage for Firebase;
- Verwenden Sie Firebase, um Benutzern das Erstellen eines Kontos zu ermöglichen und sie mithilfe der Firebase-Authentifizierung zu authentifizieren.
- Verwenden Sie Firebase, um Medium-ähnliche Inline-Kommentare zu erstellen.
Ein guter Anfang wäre, zur Dokumentation von Firestore zu gehen.
Lassen Sie uns abschließend zum Kommentarbereich unten gehen und Ihre Erfahrungen mit dem Erstellen eines Kommentarbereichs mit Firebase besprechen.
Nützliche Frontend- und UX-Bits, die einmal pro Woche geliefert werden.
Mit Tools, die Ihnen helfen, Ihre Arbeit besser zu erledigen. Melden Sie sich an und erhalten Sie Vitalys Smart Interface Design-Checklisten im PDF -Format per E-Mail.
Auf Front-End & UX. Vertrauen von 190.000 Menschen.