Come creare il tuo sistema di commenti utilizzando Firebase
Pubblicato: 2022-03-10Una sezione commenti è un ottimo modo per creare una community per il tuo blog. Di recente, quando ho iniziato a bloggare, ho pensato di aggiungere una sezione commenti. Tuttavia, non è stato facile. I sistemi di commenti ospitati, come Disqus e Commento, sono dotati di una propria serie di problemi:
- Possiedono i tuoi dati.
- Non sono gratuiti.
- Non puoi personalizzarli molto.
Quindi, ho deciso di creare il mio sistema di commenti. Firebase sembrava un'alternativa di hosting perfetta all'esecuzione di un server back-end.
Prima di tutto, ottieni tutti i vantaggi di avere il tuo database: controlli i dati e puoi strutturarli come preferisci. In secondo luogo, non è necessario configurare un server back-end. Puoi facilmente controllarlo dall'estremità anteriore. È come avere il meglio di entrambi i mondi: un sistema ospitato senza il fastidio di un back-end.
In questo post, è quello che faremo. Impareremo come configurare Firebase con Gatsby, un generatore di siti statici. Ma i principi possono essere applicati a qualsiasi generatore di siti statici.
Immergiamoci!
Cos'è Firebase?
Firebase è un servizio back-end che offre strumenti per gli sviluppatori di app come database, hosting, funzioni cloud, autenticazione, analisi e archiviazione.
Cloud Firestore (il database di Firebase) è la funzionalità che utilizzeremo per questo progetto. È un database NoSQL. Ciò significa che non è strutturato come un database SQL con righe, colonne e tabelle. Puoi pensarlo come un grande albero JSON.
Introduzione al progetto
Inizializziamo il progetto clonando o scaricando il repository da GitHub.
Ho creato due rami per ogni passaggio (uno all'inizio e uno alla fine) per semplificare il monitoraggio delle modifiche man mano che procediamo.
Eseguiamo il progetto usando il seguente comando:
gatsby develop
Se apri il progetto nel tuo browser, vedrai le ossa nude di un blog di base.
La sezione commenti non funziona. Sta semplicemente caricando un commento di esempio e, dopo l'invio del commento, registra i dettagli sulla console.
Il nostro compito principale è far funzionare la sezione commenti.
Come funziona la sezione commenti
Prima di fare qualsiasi cosa, cerchiamo di capire come funziona il codice per la sezione commenti.
Quattro componenti gestiscono le sezioni dei commenti:
-
blog-post.js
-
Comments.js
-
CommentForm.js
-
Comment.js
Innanzitutto, dobbiamo identificare i commenti per un post. Questo può essere fatto creando un ID univoco per ogni post del blog, oppure possiamo usare lo slug, che è sempre univoco.
Il file blog-post.js
è il componente di layout per tutti i post del blog. È il punto di ingresso perfetto per ottenere lo slug di un post sul blog. Questo viene fatto usando una query GraphQL.
export const query = graphql` query($slug: String!) { markdownRemark(fields: { slug: { eq: $slug } }) { html frontmatter { title } fields { slug } } } `
Prima di inviarlo al componente Comments.js
, utilizziamo il metodo substring()
per eliminare la barra finale ( /
) che Gatsby aggiunge allo slug.
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> ) }
Il componente Comments.js
mappa ogni commento e passa i suoi dati a Comment.js
, insieme a tutte le risposte. Per questo progetto, ho deciso di andare un livello in profondità con il sistema di commenti.
Il componente carica anche CommentForm.js
per acquisire eventuali commenti di primo livello.
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> ) }
Passiamo a CommentForm.js
. Questo file è semplice, esegue il rendering di un modulo di commento e ne gestisce l'invio. Il metodo di invio registra semplicemente i dettagli sulla console.
const handleCommentSubmission = async e => { e. preventDefault() let comment = { name: name, content: content, pId: parentId ∣∣ null, time: new Date(), } setName("") setContent("") console.log(comment) }
Il file Comment.js
ha molte cose da fare. Dividiamolo in pezzi più piccoli.
Innanzitutto, c'è un componente SingleComment
, che esegue il rendering di un commento.
Sto usando l'Adorable API per ottenere un fantastico avatar. La libreria Moment.js viene utilizzata per eseguire il rendering del tempo in un formato leggibile dall'uomo.
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> )
Il prossimo nel file è il componente Comment
. Questo componente mostra un commento figlio se gli è stato passato un commento figlio. In caso contrario, viene visualizzata una casella di risposta, che può essere attivata e disattivata facendo clic sul pulsante "Rispondi" o sul pulsante "Annulla risposta".
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>
Ora che abbiamo una panoramica, esaminiamo i passaggi per creare la nostra sezione commenti.
1. Aggiungi Firebase
Per prima cosa, configuriamo Firebase per il nostro progetto.
Inizia registrandoti. Vai su Firebase e crea un account Google. Se non ne hai uno, fai clic su "Inizia".
Fare clic su "Aggiungi progetto" per aggiungere un nuovo progetto. Aggiungi un nome per il tuo progetto e fai clic su "Crea un progetto".
Una volta creato un progetto, dovremo configurare Cloud Firestore.
Nel menu a sinistra, fai clic su "Database". Una volta aperta una pagina che dice "Cloud Firestore", fai clic su "Crea database" per creare un nuovo database Cloud Firestore.
Quando viene visualizzato il popup, scegli "Avvia in modalità test". Quindi, scegli la posizione di Cloud Firestore più vicina a te.
Quando vedi una pagina come questa, significa che hai creato correttamente il tuo database Cloud Firestore.
Concludiamo impostando la logica per l'applicazione. Torna all'applicazione e installa Firebase:
yarn add firebase
Aggiungi un nuovo file, firebase.js
, nella directory principale. Incolla questo contenuto al suo interno:
import firebase from "firebase/app" import "firebase/firestore" var firebaseConfig = 'yourFirebaseConfig' firebase.initializeApp(firebaseConfig) export const firestore = firebase.firestore() export default firebase
Dovrai sostituire yourFirebaseConfig
con quello per il tuo progetto. Per trovarlo, fai clic sull'icona a forma di ingranaggio accanto a "Panoramica del progetto" nell'app Firebase.
Questo apre la pagina delle impostazioni. Sotto il sottotitolo della tua app, fai clic sull'icona web, che assomiglia a questa:
Questo apre un popup. Nel campo "Nome app", inserisci un nome qualsiasi e fai clic su "Registra app". Questo darà il tuo oggetto firebaseConfig
.
<!-- 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>
Copia solo il contenuto dell'oggetto firebaseConfig
e incollalo nel file firebase.js
.
Va bene esporre la tua chiave API Firebase?
Sì. Come affermato da un ingegnere di Google, esporre la tua chiave API è OK.
L'unico scopo della chiave API è identificare il tuo progetto con il database di Google. Se hai impostato regole di sicurezza rigorose per Cloud Firestore, non devi preoccuparti se qualcuno si impossessa della tua chiave API.
Parleremo delle regole di sicurezza nell'ultima sezione.
Per ora, stiamo eseguendo Firestore in modalità test, quindi non dovresti rivelare la chiave API al pubblico.
Come utilizzare Firestore?
È possibile memorizzare i dati in uno di due tipi:
- collezione
Una collezione contiene documenti. È come una serie di documenti. - documento
Un documento contiene dati in una coppia campo-valore.
Ricorda che una collezione può contenere solo documenti e non altre collezioni. Ma un documento può contenere altre raccolte.
Ciò significa che se vogliamo archiviare una raccolta all'interno di una raccolta, memorizzeremo la raccolta in un documento e memorizzeremo quel documento in una raccolta, in questo modo:
{collection-1}/{document}/{collection-2}
Come strutturare i dati?
Cloud Firestore è di natura gerarchica, quindi le persone tendono a archiviare dati in questo modo:
blog/{blog-post-1}/content/comments/{comment-1}
Ma archiviare i dati in questo modo spesso introduce problemi.
Supponi di voler ricevere un commento. Dovrai cercare il commento archiviato in profondità nella raccolta del blog. Questo renderà il tuo codice più soggetto a errori. Chris Esplin consiglia di non utilizzare mai raccolte secondarie.
Consiglierei di archiviare i dati come oggetto appiattito:
blog-posts/{blog-post-1} comments/{comment-1}
In questo modo puoi ottenere e inviare dati facilmente.
Come ottenere dati da Firestore?
Per ottenere i dati, Firebase offre due metodi:
-
get()
Questo è per ottenere il contenuto una volta. -
onSnapshot()
Questo metodo ti invia i dati e poi continua a inviare gli aggiornamenti a meno che tu non annulli l'iscrizione.
Come inviare dati a Firestore?
Proprio come per il recupero dei dati, Firebase ha due metodi per salvare i dati:
-
set()
Viene utilizzato per specificare l'ID di un documento. -
add()
Viene utilizzato per creare documenti con ID automatici.
Lo so, è stato molto da capire. Ma non preoccuparti, rivisiteremo di nuovo questi concetti quando raggiungeremo il progetto.
2. Crea data di esempio
Il passaggio successivo consiste nel creare alcuni dati di esempio da interrogare. Facciamolo andando su Firebase.
Vai su Cloud Firestore. Fai clic su "Avvia una raccolta". Immettere i comments
per l'"ID raccolta", quindi fare clic su "Avanti".
Per "ID documento", fare clic su "Auto-ID. Immettere i seguenti dati e fare clic su "Salva".
Durante l'inserimento dei dati, assicurati che "Campi" e "Tipi" corrispondano allo screenshot sopra. Quindi, fai clic su "Salva".
È così che aggiungi manualmente un commento in Firestore. Il processo sembra macchinoso, ma non preoccuparti: d'ora in poi, la nostra app si occuperà di aggiungere commenti.
A questo punto, il nostro database si presenta così: comments/{comment}
.
3. Ottieni i dati dei commenti
I nostri dati di esempio sono pronti per essere interrogati. Iniziamo ottenendo i dati per il nostro blog.
Vai su blog-post.js
e importa il Firestore dal file Firebase che abbiamo appena creato.
import {firestore} from "../../firebase.js"
Per interrogare, useremo l'hook useEffect
di React. Se non l'hai già fatto, importiamolo anche tu.
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])
Il metodo utilizzato per ottenere i dati è onSnapshot
. Questo perché vogliamo anche ascoltare i cambiamenti di stato. Quindi, i commenti verranno aggiornati senza che l'utente debba aggiornare il browser.
Abbiamo usato i metodi filter
e map
per trovare i commenti il cui slug corrisponde allo slug corrente.
Un'ultima cosa a cui dobbiamo pensare è la pulizia. Poiché onSnapshot
continua a inviare aggiornamenti, ciò potrebbe introdurre una perdita di memoria nella nostra applicazione. Fortunatamente, Firebase fornisce una soluzione accurata.
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])
Una volta terminato, esegui gatsby develop
per vedere le modifiche. Ora possiamo vedere la nostra sezione commenti che ottiene dati da Firebase.
Lavoriamo per memorizzare i commenti.
4. Memorizza i commenti
Per archiviare i commenti, vai al file CommentForm.js
. Importiamo anche Firestore in questo file.
import { firestore } from "../../firebase.js"
Per salvare un commento su Firebase, useremo il metodo add()
, perché vogliamo che Firestore crei documenti con un ID automatico.
Facciamolo nel metodo handleCommentSubmission
.
firestore .collection(`comments`) .add(comment) .catch(err => { console.error('error adding comment: ', err) })
Innanzitutto, otteniamo il riferimento alla raccolta di commenti, quindi aggiungiamo il commento. Utilizziamo anche il metodo catch
per rilevare eventuali errori durante l'aggiunta di commenti.
A questo punto, se apri un browser, puoi vedere la sezione commenti funzionante. Possiamo aggiungere nuovi commenti e pubblicare risposte. La cosa più sorprendente è che tutto funziona senza dover aggiornare la pagina.
Puoi anche controllare Firestore per vedere che sta memorizzando i dati.
Infine, parliamo di una cosa cruciale in Firebase: le regole di sicurezza.
5. Inasprire le regole di sicurezza
Finora abbiamo eseguito Cloud Firestore in modalità test. Ciò significa che chiunque abbia accesso all'URL può aggiungere e leggere il nostro database. Questo è spaventoso.
Per affrontarlo, Firebase ci fornisce regole di sicurezza. Possiamo creare un modello di database e limitare determinate attività in Cloud Firestore.
Oltre alle due operazioni di base (lettura e scrittura), Firebase offre operazioni più granulari: ottenere, elencare, creare, aggiornare ed eliminare.
Un'operazione di lettura può essere suddivisa in:
-
get
Ottieni un unico documento. -
list
Ottieni un elenco di documenti o una raccolta.
Un'operazione di scrittura può essere suddivisa in:
-
create
Crea un nuovo documento. -
update
Aggiorna un documento esistente. -
delete
Elimina un documento.
Per proteggere l'applicazione, torna su Cloud Firestore. In "Regole", inserisci questo:
service cloud.firestore { match /databases/{database}/documents { match /comments/{id=**} { allow read, create; } } }
Sulla prima riga, definiamo il servizio, che, nel nostro caso, è Firestore. Le righe successive dicono a Firebase che qualsiasi cosa all'interno della raccolta di comments
può essere letta e creata.
Se avessimo usato questo:
allow read, write;
... ciò significherebbe che gli utenti potrebbero aggiornare ed eliminare i commenti esistenti, cosa che non vogliamo.
Le regole di sicurezza di Firebase sono estremamente potenti e ci consentono di limitare determinati dati, attività e persino utenti.
Sulla creazione della tua sezione commenti
Congratulazioni! Hai appena visto il potere di Firebase. È uno strumento così eccellente per creare applicazioni sicure e veloci.
Abbiamo creato una sezione commenti semplicissima. Ma non c'è modo di impedirti di esplorare ulteriori possibilità:
- Aggiungi le immagini del profilo e salvale in Cloud Storage per Firebase;
- Utilizza Firebase per consentire agli utenti di creare un account e autenticarli utilizzando l'autenticazione Firebase;
- Usa Firebase per creare commenti in linea di tipo Medio.
Un ottimo modo per iniziare sarebbe andare alla documentazione di Firestore.
Infine, andiamo alla sezione commenti qui sotto e discutiamo della tua esperienza con la creazione di una sezione commenti utilizzando Firebase.
Utili bit di front-end e UX, forniti una volta alla settimana.
Con strumenti per aiutarti a svolgere meglio il tuo lavoro. Iscriviti e ricevi le liste di controllo per la progettazione dell'interfaccia intelligente di Vitaly in PDF via e-mail.
Sul front-end e UX. Scelto da 190.000 persone.