Cómo construir su propio sistema de comentarios usando Firebase
Publicado: 2022-03-10Una sección de comentarios es una excelente manera de crear una comunidad para tu blog. Recientemente, cuando comencé a escribir un blog, pensé en agregar una sección de comentarios. Sin embargo, no fue fácil. Los sistemas de comentarios alojados, como Disqus y Commento, vienen con su propio conjunto de problemas:
- Ellos son dueños de sus datos.
- No son gratis.
- No puedes personalizarlos mucho.
Entonces, decidí construir mi propio sistema de comentarios. Firebase parecía una alternativa de alojamiento perfecta para ejecutar un servidor back-end.
En primer lugar, obtienes todos los beneficios de tener tu propia base de datos: controlas los datos y puedes estructurarlos como quieras. En segundo lugar, no necesita configurar un servidor back-end. Puede controlarlo fácilmente desde el extremo frontal. Es como tener lo mejor de ambos mundos: un sistema alojado sin la molestia de un back-end.
En esta publicación, eso es lo que haremos. Aprenderemos a configurar Firebase con Gatsby, un generador de sitios estáticos. Pero los principios se pueden aplicar a cualquier generador de sitios estáticos.
¡Vamos a sumergirnos!
¿Qué es Firebase?
Firebase es un back-end como servicio que ofrece herramientas para desarrolladores de aplicaciones, como bases de datos, hospedaje, funciones en la nube, autenticación, análisis y almacenamiento.
Cloud Firestore (la base de datos de Firebase) es la funcionalidad que usaremos para este proyecto. Es una base de datos NoSQL. Esto significa que no está estructurado como una base de datos SQL con filas, columnas y tablas. Puede pensar en ello como un gran árbol JSON.
Introducción al Proyecto
Inicialicemos el proyecto clonando o descargando el repositorio de GitHub.
He creado dos ramas para cada paso (una al principio y otra al final) para facilitarle el seguimiento de los cambios a medida que avanzamos.
Ejecutemos el proyecto usando el siguiente comando:
gatsby develop
Si abre el proyecto en su navegador, verá los esqueletos básicos de un blog básico.

La sección de comentarios no funciona. Simplemente está cargando un comentario de muestra y, al enviar el comentario, registra los detalles en la consola.
Nuestra tarea principal es hacer que la sección de comentarios funcione.
Cómo funciona la sección de comentarios
Antes de hacer nada, comprendamos cómo funciona el código de la sección de comentarios.
Cuatro componentes manejan las secciones de comentarios:
-
blog-post.js
-
Comments.js
-
CommentForm.js
-
Comment.js
Primero, necesitamos identificar los comentarios de una publicación. Esto se puede hacer creando una identificación única para cada publicación de blog, o podemos usar el slug, que siempre es único.
El archivo blog-post.js
es el componente de diseño para todas las publicaciones de blog. Es el punto de entrada perfecto para obtener la babosa de una publicación de blog. Esto se hace usando una consulta GraphQL.
export const query = graphql` query($slug: String!) { markdownRemark(fields: { slug: { eq: $slug } }) { html frontmatter { title } fields { slug } } } `
Antes de enviarlo al componente Comments.js
, usemos el método substring()
para deshacernos de la barra inclinada final ( /
) que Gatsby agrega al 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> ) }
El componente Comments.js
asigna cada comentario y pasa sus datos a Comment.js
, junto con las respuestas. Para este proyecto, he decidido ir un nivel más profundo con el sistema de comentarios.
El componente también carga CommentForm.js
para capturar cualquier comentario de nivel superior.
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> ) }
Pasemos a CommentForm.js
. Este archivo es simple, presenta un formulario de comentarios y maneja su envío. El método de envío simplemente registra los detalles en la consola.
const handleCommentSubmission = async e => { e. preventDefault() let comment = { name: name, content: content, pId: parentId ∣∣ null, time: new Date(), } setName("") setContent("") console.log(comment) }
El archivo Comment.js
tiene mucho que hacer. Vamos a dividirlo en partes más pequeñas.
Primero, hay un componente SingleComment
, que genera un comentario.
Estoy usando la API Adorable para obtener un avatar genial. La biblioteca Moment.js se usa para representar el tiempo en un formato legible por humanos.
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> )
El siguiente en el archivo es el componente Comment
. Este componente muestra un comentario secundario si se le pasó algún comentario secundario. De lo contrario, muestra un cuadro de respuesta, que se puede activar y desactivar haciendo clic en el botón "Responder" o en el botón "Cancelar respuesta".
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>
Ahora que tenemos una descripción general, repasemos los pasos para crear nuestra sección de comentarios.
1. Agregar base de fuego
Primero, configuremos Firebase para nuestro proyecto.
Comience por registrarse. Vaya a Firebase y regístrese para obtener una cuenta de Google. Si no tiene uno, haga clic en "Comenzar".
Haga clic en "Agregar proyecto" para agregar un nuevo proyecto. Agregue un nombre para su proyecto y haga clic en "Crear un proyecto".

Una vez que hayamos creado un proyecto, necesitaremos configurar Cloud Firestore.
En el menú del lado izquierdo, haga clic en "Base de datos". Una vez que se abre una página que dice "Cloud Firestore", haga clic en "Crear base de datos" para crear una nueva base de datos de Cloud Firestore.

Cuando aparezca la ventana emergente, elija "Iniciar en modo de prueba". A continuación, elija la ubicación de Cloud Firestore más cercana a usted.

Una vez que vea una página como esta, significa que ha creado correctamente su base de datos de Cloud Firestore.

Terminemos configurando la lógica de la aplicación. Vuelve a la aplicación e instala Firebase:
yarn add firebase
Agregue un nuevo archivo, firebase.js
, en el directorio raíz. Pega este contenido en él:
import firebase from "firebase/app" import "firebase/firestore" var firebaseConfig = 'yourFirebaseConfig' firebase.initializeApp(firebaseConfig) export const firestore = firebase.firestore() export default firebase
Deberá reemplazar yourFirebaseConfig
con la de su proyecto. Para encontrarlo, haga clic en el ícono de ajustes junto a "Resumen del proyecto" en la aplicación Firebase.

Esto abre la página de configuración. Debajo del subtítulo de su aplicación, haga clic en el ícono web, que se ve así:

Esto abre una ventana emergente. En el campo "Apodo de la aplicación", ingrese cualquier nombre y haga clic en "Registrar aplicación". Esto le dará a su objeto 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>
Copie solo el contenido del objeto firebaseConfig
y péguelo en el archivo firebase.js
.
¿Está bien exponer su clave API de Firebase?
Si. Según lo declarado por un ingeniero de Google, exponer su clave API está bien.
El único propósito de la clave API es identificar su proyecto con la base de datos de Google. Si ha establecido reglas de seguridad sólidas para Cloud Firestore, entonces no necesita preocuparse si alguien obtiene su clave API.
Hablaremos de las reglas de seguridad en la última sección.
Por ahora, estamos ejecutando Firestore en modo de prueba, por lo que no debe revelar la clave API al público.
¿Cómo usar Firestore?
Puede almacenar datos en uno de dos tipos:
- colección
Una colección contiene documentos. Es como una matriz de documentos. - documento
Un documento contiene datos en un par de valor de campo.
Recuerde que una colección puede contener solo documentos y no otras colecciones. Pero un documento puede contener otras colecciones.
Esto significa que si queremos almacenar una colección dentro de una colección, almacenaríamos la colección en un documento y almacenaríamos ese documento en una colección, así:
{collection-1}/{document}/{collection-2}
¿Cómo estructurar los datos?
Cloud Firestore es de naturaleza jerárquica, por lo que las personas tienden a almacenar datos como estos:
blog/{blog-post-1}/content/comments/{comment-1}
Pero almacenar datos de esta manera a menudo presenta problemas.
Digamos que desea obtener un comentario. Tendrás que buscar el comentario almacenado en lo más profundo de la colección del blog. Esto hará que su código sea más propenso a errores. Chris Esplin recomienda nunca usar subcolecciones.
Recomendaría almacenar datos como un objeto aplanado:
blog-posts/{blog-post-1} comments/{comment-1}
De esta manera, puede obtener y enviar datos fácilmente.
¿Cómo obtener datos de Firestore?
Para obtener datos, Firebase te ofrece dos métodos:
-
get()
Esto es para obtener el contenido una vez. -
onSnapshot()
Este método le envía datos y luego continúa enviando actualizaciones a menos que se dé de baja.
¿Cómo enviar datos a Firestore?
Al igual que con la obtención de datos, Firebase tiene dos métodos para guardar datos:
-
set()
Se utiliza para especificar el ID de un documento. -
add()
Esto se utiliza para crear documentos con identificaciones automáticas.
Lo sé, esto ha sido mucho para comprender. Pero no se preocupe, revisaremos estos conceptos nuevamente cuando lleguemos al proyecto.
2. Crear fecha de muestra
El siguiente paso es crear algunos datos de muestra para que los consultemos. Hagámoslo yendo a Firebase.
Ve a Cloud Firestore. Haga clic en "Iniciar una colección". Ingrese comments
para el "ID de la colección", luego haga clic en "Siguiente".

Para la “ID del documento”, haga clic en “Auto-ID. Ingrese los siguientes datos y haga clic en “Guardar”.

Mientras ingresa datos, asegúrese de que los "Campos" y "Tipos" coincidan con la captura de pantalla anterior. Luego, haga clic en "Guardar".
Así es como agrega un comentario manualmente en Firestore. El proceso parece engorroso, pero no te preocupes: a partir de ahora, nuestra aplicación se encargará de agregar comentarios.
En este punto, nuestra base de datos se ve así: comments/{comment}
.
3. Obtenga los datos de los comentarios
Nuestros datos de muestra están listos para consultar. Comencemos obteniendo los datos para nuestro blog.
Vaya a blog-post.js
e importe Firestore desde el archivo de Firebase que acabamos de crear.
import {firestore} from "../../firebase.js"
Para consultar, usaremos el gancho useEffect
de React. Si aún no lo has hecho, vamos a importarlo también.
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])
El método utilizado para obtener datos es onSnapshot
. Esto se debe a que también queremos escuchar los cambios de estado. Por lo tanto, los comentarios se actualizarán sin que el usuario tenga que actualizar el navegador.
Usamos los métodos de filter
y map
para encontrar los comentarios cuyo slug coincida con el slug actual.
Una última cosa en la que tenemos que pensar es en la limpieza. Debido a que onSnapshot
continúa enviando actualizaciones, esto podría provocar una fuga de memoria en nuestra aplicación. Afortunadamente, Firebase proporciona una solución ordenada.
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 vez que haya terminado, ejecute gatsby develop
para ver los cambios. Ahora podemos ver nuestra sección de comentarios obteniendo datos de Firebase.

Trabajemos en almacenar los comentarios.
4. Comentarios de la tienda
Para almacenar comentarios, vaya al archivo CommentForm.js
. Importemos Firestore a este archivo también.
import { firestore } from "../../firebase.js"
Para guardar un comentario en Firebase, usaremos el método add()
, porque queremos que Firestore cree documentos con una identificación automática.
Hagámoslo en el método handleCommentSubmission
.
firestore .collection(`comments`) .add(comment) .catch(err => { console.error('error adding comment: ', err) })
Primero, obtenemos la referencia a la colección de comentarios y luego agregamos el comentario. También estamos usando el método catch
para detectar cualquier error al agregar comentarios.
En este punto, si abre un navegador, puede ver que la sección de comentarios funciona. Podemos añadir nuevos comentarios, así como publicar respuestas. Lo que es más sorprendente es que todo funciona sin que tengamos que actualizar la página.

También puede consultar Firestore para ver si está almacenando los datos.

Finalmente, hablemos de una cosa crucial en Firebase: las reglas de seguridad.
5. Reforzar las reglas de seguridad
Hasta ahora, hemos estado ejecutando Cloud Firestore en modo de prueba. Esto significa que cualquier persona con acceso a la URL puede agregar y leer nuestra base de datos. Eso da miedo.
Para abordar eso, Firebase nos proporciona reglas de seguridad. Podemos crear un patrón de base de datos y restringir ciertas actividades en Cloud Firestore.
Además de las dos operaciones básicas (lectura y escritura), Firebase ofrece operaciones más granulares: obtener, enumerar, crear, actualizar y eliminar.
Una operación de lectura se puede dividir como:
-
get
Obtenga un solo documento. -
list
Obtener una lista de documentos o una colección.
Una operación de escritura se puede dividir como:
-
create
Crear un nuevo documento. -
update
Actualizar un documento existente. -
delete
Eliminar un documento.
Para asegurar la aplicación, regresa a Cloud Firestore. En "Reglas", ingrese esto:
service cloud.firestore { match /databases/{database}/documents { match /comments/{id=**} { allow read, create; } } }
En la primera línea definimos el servicio, que en nuestro caso es Firestore. Las siguientes líneas le dicen a Firebase que cualquier cosa dentro de la colección de comments
se puede leer y crear.
Si hubiéramos usado esto:
allow read, write;
… eso significaría que los usuarios podrían actualizar y eliminar los comentarios existentes, lo que no queremos.
Las reglas de seguridad de Firebase son extremadamente poderosas y nos permiten restringir ciertos datos, actividades e incluso usuarios.
A la construcción de su propia sección de comentarios
¡Felicitaciones! Acabas de ver el poder de Firebase. Es una excelente herramienta para construir aplicaciones seguras y rápidas.
Hemos creado una sección de comentarios súper simple. Pero no hay nada que le impida explorar más posibilidades:
- Agregue imágenes de perfil y guárdelas en Cloud Storage para Firebase;
- Utilice Firebase para permitir a los usuarios crear una cuenta y autenticarlos mediante la autenticación de Firebase;
- Use Firebase para crear comentarios similares a Medium en línea.
Una excelente manera de comenzar sería dirigirse a la documentación de Firestore.
Finalmente, pasemos a la sección de comentarios a continuación y analicemos su experiencia con la creación de una sección de comentarios con Firebase.
Bits útiles de front-end y UX, entregados una vez a la semana.
Con herramientas para ayudarlo a hacer mejor su trabajo. Suscríbase y obtenga el PDF de listas de verificación de diseño de interfaz inteligente de Vitaly por correo electrónico.
En front-end y UX. Con la confianza de 190.000 personas.