1. Información general
En este laboratorio de código, aprenderá algunos de los conceptos básicos de Firebase para crear aplicaciones web interactivas. Creará una aplicación de chat RSVP para eventos y libro de visitas con varios productos de Firebase.
lo que aprenderás
- Autentica a los usuarios con Firebase Authentication y FirebaseUI.
- Sincroniza datos usando Cloud Firestore.
- Escriba reglas de seguridad de Firebase para proteger una base de datos.
Lo que necesitarás
- Un navegador de su elección, como Chrome.
- Acceso a stackblitz.com (no es necesario iniciar sesión ni tener una cuenta).
- Una cuenta de Google, como una cuenta de gmail. Recomendamos la cuenta de correo electrónico que ya usa para su cuenta de GitHub. Esto le permite utilizar funciones avanzadas en StackBlitz.
- El código de muestra del codelab. Consulte el siguiente paso para saber cómo obtener el código.
2. Obtenga el código de inicio
En este laboratorio de programación, crea una aplicación con StackBlitz , un editor en línea que tiene varios flujos de trabajo de Firebase integrados. Stackblitz no requiere instalación de software ni una cuenta especial de StackBlitz.
StackBlitz te permite compartir proyectos con otros. Otras personas que tienen la URL de su proyecto StackBlitz pueden ver su código y bifurcar su proyecto, pero no pueden editar su proyecto StackBlitz.
- Vaya a esta URL para obtener el código de inicio: https://stackblitz.com/edit/firebase-gtk-web-start
- En la parte superior de la página de StackBlitz, haz clic en Fork :
Ahora tiene una copia del código inicial como su propio proyecto StackBlitz, que tiene un nombre único, junto con una URL única. Todos sus archivos y cambios se guardan en este proyecto StackBlitz.
3. Editar información del evento
Los materiales iniciales para este laboratorio de programación brindan cierta estructura para la aplicación web, incluidas algunas hojas de estilo y un par de contenedores HTML para la aplicación. Más adelante en este laboratorio de programación, conectará estos contenedores a Firebase.
Para comenzar, familiaricémonos un poco más con la interfaz de StackBlitz.
- En StackBlitz, abra el archivo
index.html
. - Localice
event-details-container
ydescription-container
, luego intente editar algunos detalles del evento.
A medida que edita el texto, la recarga automática de la página en StackBlitz muestra los detalles del nuevo evento. Genial, ¿sí?
<!-- ... -->
<div id="app">
<img src="..." />
<section id="event-details-container">
<h1>Firebase Meetup</h1>
<p><i class="material-icons">calendar_today</i> October 30</p>
<p><i class="material-icons">location_city</i> San Francisco</p>
</section>
<hr>
<section id="firebaseui-auth-container"></section>
<section id="description-container">
<h2>What we'll be doing</h2>
<p>Join us for a day full of Firebase Workshops and Pizza!</p>
</section>
</div>
<!-- ... -->
La vista previa de su aplicación debería verse así:
Vista previa de la aplicación
4. Crea y configura un proyecto de Firebase
Mostrar la información del evento es excelente para sus invitados, pero solo mostrar los eventos no es muy útil para nadie. Agreguemos algunas funciones dinámicas a esta aplicación. Para esto, deberá conectar Firebase a su aplicación. Para comenzar con Firebase, deberá crear y configurar un proyecto de Firebase.
Crear un proyecto de Firebase
- Inicie sesión en Firebase .
- En la consola de Firebase, haga clic en Agregar proyecto (o Crear un proyecto ) y, luego, nombre su proyecto de Firebase como Firebase-Web-Codelab .
- Haga clic en las opciones de creación de proyectos. Acepte los términos de Firebase si se le solicita. En la pantalla de Google Analytics, haga clic en "No habilitar", porque no usará Analytics para esta aplicación.
Para obtener más información sobre los proyectos de Firebase, consulte Comprender los proyectos de Firebase .
Habilitar y configurar productos de Firebase en la consola
La aplicación que estás creando usa varios productos de Firebase que están disponibles para aplicaciones web:
- Firebase Authentication y Firebase UI para permitir que sus usuarios inicien sesión fácilmente en su aplicación.
- Cloud Firestore para guardar datos estructurados en la nube y recibir notificaciones instantáneas cuando cambien los datos.
- Reglas de seguridad de Firebase para proteger su base de datos.
Algunos de estos productos necesitan una configuración especial o deben habilitarse mediante la consola Firebase.
Habilitar el inicio de sesión por correo electrónico para la autenticación de Firebase
Para permitir que los usuarios inicien sesión en la aplicación web, utilizará el método de inicio de sesión de correo electrónico/contraseña para este laboratorio de código:
- En el panel del lado izquierdo de Firebase console, haga clic en Build > Authentication . Luego haga clic en Comenzar . Ahora se encuentra en el panel de Autenticación, donde puede ver los usuarios registrados, configurar los proveedores de inicio de sesión y administrar la configuración.
- Seleccione la pestaña Método de inicio de sesión (o haga clic aquí para ir directamente a la pestaña).
- Haga clic en Correo electrónico/Contraseña en las opciones del proveedor, cambie el interruptor a Habilitar y luego haga clic en Guardar .
Configurar Cloud Firestore
La aplicación web usa Cloud Firestore para guardar mensajes de chat y recibir nuevos mensajes de chat.
Aquí se explica cómo configurar Cloud Firestore:
- En el panel del lado izquierdo de Firebase console, haga clic en Build > Firestore Database . Luego haga clic en Crear base de datos .
- Haga clic en Crear base de datos .
- Seleccione la opción Iniciar en modo de prueba . Lea el descargo de responsabilidad sobre las reglas de seguridad. El modo de prueba garantiza que pueda escribir libremente en la base de datos durante el desarrollo. Haga clic en Siguiente .
- Seleccione la ubicación de su base de datos (puede usar la predeterminada). Tenga en cuenta, sin embargo, que esta ubicación no se puede cambiar más adelante.
- Haga clic en Listo.
5. Agregar y configurar Firebase
Ahora que ha creado su proyecto de Firebase y algunos servicios están habilitados, debe indicarle al código que desea usar Firebase, así como qué proyecto de Firebase usar.
Agregar las bibliotecas de Firebase
Para que su aplicación use Firebase, debe agregar las bibliotecas de Firebase a la aplicación. Hay varias formas de hacer esto, como se describe en la documentación de Firebase . Por ejemplo, puede agregar las bibliotecas desde la CDN de Google, o puede instalarlas localmente usando npm y luego empaquetarlas en su aplicación si está usando Browserify.
StackBlitz proporciona agrupación automática, por lo que puede agregar las bibliotecas de Firebase mediante declaraciones de importación. Utilizará las versiones modulares (v9) de las bibliotecas, que ayudan a reducir el tamaño total de la página web a través de un proceso llamado "sacudida del árbol". Puede obtener más información sobre los SDK modulares en los documentos .
Para compilar esta aplicación, usa las bibliotecas Firebase Authentication, FirebaseUI y Cloud Firestore. Para este laboratorio de código, las siguientes declaraciones de importación ya están incluidas en la parte superior del archivo index.js
, e importaremos más métodos de cada biblioteca de Firebase a medida que avanzamos:
// Import stylesheets
import './style.css';
// Firebase App (the core Firebase SDK) is always required
import { initializeApp } from 'firebase/app';
// Add the Firebase products and methods that you want to use
import {} from 'firebase/auth';
import {} from 'firebase/firestore';
import * as firebaseui from 'firebaseui';
Agregue una aplicación web de Firebase a su proyecto de Firebase
- De vuelta en la consola de Firebase, navegue a la página de descripción general de su proyecto haciendo clic en Descripción general del proyecto en la parte superior izquierda.
- En el centro de la página de descripción general de su proyecto, haga clic en el ícono web
para crear una nueva aplicación web de Firebase.
- Registre la aplicación con el apodo Web App .
- Para este laboratorio de programación, NO marque la casilla junto a Configurar también Firebase Hosting para esta aplicación . Por ahora, usará el panel de vista previa de StackBlitz.
- Haga clic en Registrar aplicación .
- Copie el objeto de configuración de Firebase en su portapapeles.
- Haga clic en Continuar a la consola . Agregue el objeto de configuración de Firebase a su aplicación:
- De vuelta en StackBlitz, vaya al archivo
index.js
. - Ubique el
Add Firebase project configuration object here
, luego pegue su fragmento de configuración justo debajo del comentario. - Agrega la llamada a la función
initializeApp
para configurar Firebase usando tu configuración única de proyecto de Firebase.// ... // Add Firebase project configuration object here const firebaseConfig = { apiKey: "random-unique-string", authDomain: "your-projectId.firebaseapp.com", databaseURL: "https://your-projectId.firebaseio.com", projectId: "your-projectId", storageBucket: "your-projectId.appspot.com", messagingSenderId: "random-unique-string", appId: "random-unique-string", }; // Initialize Firebase initializeApp(firebaseConfig);
6. Agregar inicio de sesión de usuario (RSVP)
Ahora que agregó Firebase a la aplicación, puede configurar un botón RSVP que registre a las personas que usan la autenticación de Firebase .
Autentica a tus usuarios con el inicio de sesión por correo electrónico y FirebaseUI
Necesitará un botón de RSVP que solicite al usuario que inicie sesión con su dirección de correo electrónico. Puede hacerlo conectando FirebaseUI a un botón RSVP. FirebaseUI es una biblioteca que le brinda una interfaz de usuario prediseñada además de Firebase Auth.
FirebaseUI requiere una configuración (consulte las opciones en la documentación ) que hace dos cosas:
- Le dice a FirebaseUI que desea usar el método de inicio de sesión con correo electrónico/contraseña .
- Maneja la devolución de llamada para un inicio de sesión exitoso y devuelve falso para evitar una redirección. No desea que la página se actualice porque está creando una aplicación web de una sola página.
Agregue el código para inicializar FirebaseUI Auth
- En StackBlitz, ve al archivo
index.js
. - En la parte superior, ubique la instrucción de importación
firebase/auth
, luego agreguegetAuth
yEmailAuthProvider
, así:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider } from 'firebase/auth'; import {} from 'firebase/firestore';
- Guarde una referencia al objeto de autenticación justo después
initializeApp
, así:initializeApp(firebaseConfig); auth = getAuth();
- Tenga en cuenta que la configuración de FirebaseUI ya se proporciona en el código inicial. Ya está configurado para usar el proveedor de autenticación de correo electrónico.
- En la parte inferior de la función
main()
enindex.js
, agregue la declaración de inicialización de FirebaseUI, así:async function main() { // ... // Initialize the FirebaseUI widget using Firebase const ui = new firebaseui.auth.AuthUI(auth); } main();
Agregar un botón RSVP al HTML
- En StackBlitz, ve al archivo
index.html
. - Agregue el HTML para un botón RSVP dentro del
event-details-container
como se muestra en el ejemplo a continuación.
Tenga cuidado de usar los mismos valoresid
que se muestran a continuación porque, para este laboratorio de programación, ya hay enlaces para estas identificaciones específicas en el archivoindex.js
.
Tenga en cuenta que en el archivoindex.html
hay un contenedor con el IDfirebaseui-auth-container
. Esta es la identificación que pasará a FirebaseUI para mantener su inicio de sesión. Vista previa de la aplicación<!-- ... --> <section id="event-details-container"> <!-- ... --> <!-- ADD THE RSVP BUTTON HERE --> <button id="startRsvp">RSVP</button> </section> <hr> <section id="firebaseui-auth-container"></section> <!-- ... -->
- Configure un oyente en el botón RSVP y llame a la función de inicio de FirebaseUI. Esto le indica a FirebaseUI que desea ver la ventana de inicio de sesión.
Agregue el siguiente código al final de la funciónmain()
enindex.js
:async function main() { // ... // Listen to RSVP button clicks startRsvpButton.addEventListener("click", () => { ui.start("#firebaseui-auth-container", uiConfig); }); } main();
Probar el inicio de sesión en la aplicación
- En la ventana de vista previa de StackBlitz, haga clic en el botón RSVP para iniciar sesión en la aplicación.
- Para este laboratorio de código, puede usar cualquier dirección de correo electrónico, incluso una dirección de correo electrónico falsa, ya que no está configurando un paso de verificación de correo electrónico para este laboratorio de código.
- Si ve un mensaje de error que indica
auth/operation-not-allowed
oThe given sign-in provider is disabled for this Firebase project
, asegúrese de haber habilitado Correo electrónico/Contraseña como proveedor de inicio de sesión en la consola de Firebase.
- Vaya al panel de Autenticación en Firebase console. En la pestaña Usuarios , debería ver la información de la cuenta que ingresó para iniciar sesión en la aplicación.
Agregar estado de autenticación a la interfaz de usuario
A continuación, asegúrese de que la interfaz de usuario refleje el hecho de que ha iniciado sesión.
Utilizará la devolución de llamada del detector de estado de autenticación de Firebase, que recibe una notificación cada vez que cambia el estado de inicio de sesión del usuario. Si actualmente hay un usuario que inició sesión, su aplicación cambiará el botón "RSVP" a un botón "cerrar sesión".
- En StackBlitz, ve al archivo
index.js
. - En la parte superior, ubique la declaración de importación
firebase/auth
, luego agreguesignOut
yonAuthStateChanged
, así:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider, signOut, onAuthStateChanged } from 'firebase/auth'; import {} from 'firebase/firestore';
- Agregue el siguiente código en la parte inferior de la función
main()
:async function main() { // ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; } else { startRsvpButton.textContent = 'RSVP'; } }); } main();
- En el detector de botones, verifique si hay un usuario actual y cierre la sesión. Para hacer esto, reemplace el
startRsvpButton.addEventListener
actual con lo siguiente:// ... // Called when the user clicks the RSVP button startRsvpButton.addEventListener('click', () => { if (auth.currentUser) { // User is signed in; allows user to sign out signOut(auth); } else { // No user is signed in; allows user to sign in ui.start('#firebaseui-auth-container', uiConfig); } });
Ahora, el botón en su aplicación debería mostrar LOGOUT y debería volver a RSVP cuando se haga clic en él.
Vista previa de la aplicación
7. Escribir mensajes en Cloud Firestore
Saber que los usuarios van a venir es genial, pero démosles a los invitados algo más que hacer en la aplicación. ¿Y si pudieran dejar mensajes en un libro de visitas? Pueden compartir por qué están emocionados de venir oa quién esperan conocer.
Para almacenar los mensajes de chat que los usuarios escriben en la aplicación, utilizará Cloud Firestore .
Modelo de datos
Cloud Firestore es una base de datos NoSQL y los datos almacenados en la base de datos se dividen en colecciones, documentos, campos y subcolecciones. Almacenará cada mensaje del chat como un documento en una colección de nivel superior llamada guestbook
.
Agregar mensajes a Firestore
En esta sección, agregará la funcionalidad para que los usuarios escriban nuevos mensajes en la base de datos. Primero, agrega el HTML para los elementos de la interfaz de usuario (campo de mensaje y botón de envío). Luego, agrega el código que conecta estos elementos a la base de datos.
Para agregar los elementos de la interfaz de usuario de un campo de mensaje y un botón de envío:
- En StackBlitz, ve al archivo
index.html
. - Ubique el
guestbook-container
, luego agregue el siguiente código HTML para crear un formulario con el campo de entrada del mensaje y el botón de enviar.<!-- ... --> <section id="guestbook-container"> <h2>Discussion</h2> <form id="leave-message"> <label>Leave a message: </label> <input type="text" id="message"> <button type="submit"> <i class="material-icons">send</i> <span>SEND</span> </button> </form> </section> <!-- ... -->
Vista previa de la aplicación
Un usuario que haga clic en el botón ENVIAR activará el fragmento de código a continuación. Agrega el contenido del campo de entrada del mensaje a la colección guestbook
de la base de datos. Específicamente, el método addDoc
agrega el contenido del mensaje a un nuevo documento (con una identificación generada automáticamente) a la colección guestbook
.
- En StackBlitz, ve al archivo
index.js
. - En la parte superior, ubique la declaración de importación
firebase/firestore
, luego agreguegetFirestore
,addDoc
ycollection
, así:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider, signOut, onAuthStateChanged } from 'firebase/auth'; import { getFirestore, addDoc, collection } from 'firebase/firestore';
- Ahora guardaremos una referencia al objeto
db
de Firestore justo después deinitializeApp
:initializeApp(firebaseConfig); auth = getAuth(); db = getFirestore();
- En la parte inferior de la función
main()
, agregue el siguiente código.
Tenga en cuenta queauth.currentUser.uid
es una referencia a la ID única generada automáticamente que Firebase Authentication brinda a todos los usuarios que iniciaron sesión.async function main() { // ... // Listen to the form submission form.addEventListener('submit', async e => { // Prevent the default form redirect e.preventDefault(); // Write a new message to the database collection "guestbook" addDoc(collection(db, 'guestbook'), { text: input.value, timestamp: Date.now(), name: auth.currentUser.displayName, userId: auth.currentUser.uid }); // clear message input field input.value = ''; // Return false to avoid redirect return false; }); } main();
Mostrar el libro de visitas solo a los usuarios registrados
No querrás que cualquiera vea el chat de los invitados. Una cosa que puede hacer para proteger el chat es permitir que solo los usuarios registrados vean el libro de visitas. Dicho esto, para sus propias aplicaciones, también querrá proteger su base de datos con las reglas de seguridad de Firebase . (Hay más información sobre las reglas de seguridad más adelante en el laboratorio de código).
- En StackBlitz, ve al archivo
index.js
. - Edite el oyente
onAuthStateChanged
para ocultar y mostrar el libro de visitas.// ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none'; } });
Probar el envío de mensajes
- Asegúrate de haber iniciado sesión en la aplicación.
- Ingresa un mensaje como "¡Hola!", luego haz clic en ENVIAR .
Esta acción escribe el mensaje en su base de datos de Cloud Firestore. Sin embargo, aún no verá el mensaje en su aplicación web real porque aún necesita implementar la recuperación de datos. Lo harás a continuación.
Pero puede ver el mensaje recién agregado en la consola de Firebase.
En la consola de Firebase, en el panel de la base de datos de Firestore , debería ver la colección guestbook
con su mensaje recién agregado. Si continúa enviando mensajes, su colección de libros de visitas contendrá muchos documentos, como este:
consola base de fuego
8. Leer mensajes
Sincronizar mensajes
Es genial que los invitados puedan escribir mensajes en la base de datos, pero aún no pueden verlos en la aplicación.
Para mostrar mensajes, deberá agregar oyentes que se activen cuando cambien los datos y luego crear un elemento de interfaz de usuario que muestre nuevos mensajes.
Agregará código que escuche los mensajes recién agregados desde la aplicación. Primero, agregue una sección en el HTML para mostrar mensajes:
- En StackBlitz, ve al archivo
index.html
. - En
guestbook-container
, agregue una nueva sección con el ID deguestbook
.<!-- ... --> <section id="guestbook-container"> <h2>Discussion</h2> <form><!-- ... --></form> <section id="guestbook"></section> </section> <!-- ... -->
A continuación, registre el oyente que escucha los cambios realizados en los datos:
- En StackBlitz, vaya al archivo
index.js
. - En la parte superior, ubique la declaración de importación
firebase/firestore
, luego agreguequery
,orderBy
yonSnapshot
, así:// ... import { getFirestore, addDoc, collection, query, orderBy, onSnapshot } from 'firebase/firestore';
- En la parte inferior de la función
main()
, agregue el siguiente código para recorrer todos los documentos (mensajes del libro de visitas) en la base de datos. Para obtener más información sobre lo que sucede en este código, lea la información debajo del fragmento.async function main() { // ... // Create query for messages const q = query(collection(db, 'guestbook'), orderBy('timestamp', 'desc')); onSnapshot(q, snaps => { // Reset page guestbook.innerHTML = ''; // Loop through documents in database snaps.forEach(doc => { // Create an HTML entry for each document and add it to the chat const entry = document.createElement('p'); entry.textContent = doc.data().name + ': ' + doc.data().text; guestbook.appendChild(entry); }); }); } main();
Para escuchar los mensajes en la base de datos, ha creado una consulta en una colección específica mediante la función collection
. El código anterior escucha los cambios en la colección del guestbook
, que es donde se almacenan los mensajes de chat. Los mensajes también están ordenados por fecha, utilizando orderBy('timestamp', 'desc')
para mostrar los mensajes más recientes en la parte superior.
La función onSnapshot
toma dos parámetros: la consulta a usar y una función de devolución de llamada. La función de devolución de llamada se activa cuando hay cambios en los documentos que coinciden con la consulta. Esto podría ser si un mensaje se elimina, modifica o agrega. Para obtener más información, consulte la documentación de Cloud Firestore .
Prueba sincronizando mensajes
Cloud Firestore sincroniza de forma automática e instantánea los datos con los clientes suscritos a la base de datos.
- Los mensajes que creó anteriormente en la base de datos deben mostrarse en la aplicación. Siéntete libre de escribir nuevos mensajes; deberían aparecer al instante.
- Si abre su espacio de trabajo en varias ventanas o pestañas, los mensajes se sincronizarán en tiempo real en todas las pestañas.
- (Opcional) Puede intentar eliminar, modificar o agregar nuevos mensajes manualmente directamente en la sección Base de datos de Firebase console; cualquier cambio debería aparecer en la interfaz de usuario.
¡Felicidades! ¡Está leyendo documentos de Cloud Firestore en su aplicación!
Vista previa de la aplicación
9. Establezca reglas básicas de seguridad
Inicialmente configuró Cloud Firestore para usar el modo de prueba, lo que significa que su base de datos está abierta para lecturas y escrituras. Sin embargo, solo debe usar el modo de prueba durante las primeras etapas de desarrollo. Como práctica recomendada, debe configurar reglas de seguridad para su base de datos a medida que desarrolla su aplicación. La seguridad debe ser parte integral de la estructura y el comportamiento de su aplicación.
Las reglas de seguridad le permiten controlar el acceso a documentos y colecciones en su base de datos. La sintaxis de reglas flexibles le permite crear reglas que coincidan con cualquier cosa, desde todas las escrituras en toda la base de datos hasta operaciones en un documento específico.
Puedes escribir reglas de seguridad para Cloud Firestore en Firebase console:
- En la sección Crear de la consola Firebase, haga clic en Base de datos de Firestore y luego seleccione la pestaña Reglas (o haga clic aquí para ir directamente a la pestaña Reglas ).
- Debería ver las siguientes reglas de seguridad predeterminadas, con un límite de tiempo de acceso público dentro de un par de semanas a partir de hoy.
Identificar colecciones
Primero, identifique las colecciones en las que la aplicación escribe datos.
- Elimine la cláusula
match /{document=**}
existente, para que sus reglas se vean así:rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { } }
- En
match /databases/{database}/documents
, identifique la colección que desea proteger:rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { // You'll add rules here in the next step. } }
Agregar reglas de seguridad
Debido a que usó el UID de autenticación como un campo en cada documento del libro de visitas, puede obtener el UID de autenticación y verificar que cualquier persona que intente escribir en el documento tenga un UID de autenticación coincidente.
- Agregue las reglas de lectura y escritura a su conjunto de reglas como se muestra a continuación:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { allow read: if request.auth.uid != null; allow create: if request.auth.uid == request.resource.data.userId; } } }
- Haga clic en Publicar para implementar sus nuevas reglas. Ahora, para el libro de visitas, solo los usuarios registrados pueden leer mensajes (¡cualquier mensaje!), pero solo puede crear un mensaje con su ID de usuario. Tampoco permitimos que los mensajes se editen o eliminen.
Agregar reglas de validación
- Agregue validación de datos para asegurarse de que todos los campos esperados estén presentes en el documento:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { allow read: if request.auth.uid != null; allow create: if request.auth.uid == request.resource.data.userId && "name" in request.resource.data && "text" in request.resource.data && "timestamp" in request.resource.data; } } }
- Haga clic en Publicar para implementar sus nuevas reglas.
Restablecer oyentes
Debido a que su aplicación ahora solo permite que los usuarios autenticados inicien sesión, debe mover la consulta firestore
del libro de visitas dentro del oyente de autenticación. De lo contrario, se producirán errores de permisos y la aplicación se desconectará cuando el usuario cierre la sesión.
- En StackBlitz, vaya al archivo
index.js
. - Tire de la colección de libros de visitas en el oyente
onSnapshot
en una nueva función llamadasubscribeGuestbook
. Además, asigne los resultados de la funciónonSnapshot
a la variableguestbookListener
.
El oyente de FirestoreonSnapshot
devuelve una función de cancelación de suscripción que podrá usar para cancelar el oyente de instantáneas más adelante.// ... // Listen to guestbook updates function subscribeGuestbook() { const q = query(collection(db, 'guestbook'), orderBy('timestamp', 'desc')); guestbookListener = onSnapshot(q, snaps => { // Reset page guestbook.innerHTML = ''; // Loop through documents in database snaps.forEach(doc => { // Create an HTML entry for each document and add it to the chat const entry = document.createElement('p'); entry.textContent = doc.data().name + ': ' + doc.data().text; guestbook.appendChild(entry); }); }); }
- Agregue una nueva función debajo llamada
unsubscribeGuestbook
. Verifique si la variableguestbookListener
no es nula, luego llame a la función para cancelar el oyente.// ... // Unsubscribe from guestbook updates function unsubscribeGuestbook() { if (guestbookListener != null) { guestbookListener(); guestbookListener = null; } }
Finalmente, agregue las nuevas funciones a la devolución de llamada onAuthStateChanged
.
- Agregue
subscribeGuestbook()
en la parte inferior deif (user)
. - Agregue
unsubscribeGuestbook()
en la parte inferior de la instrucciónelse
.// ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; // Subscribe to the guestbook collection subscribeGuestbook(); } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none'; // Unsubscribe from the guestbook collection unsubscribeGuestbook(); } });
10. Paso de bonificación: practica lo que has aprendido
Registrar el estado de RSVP de un asistente
En este momento, su aplicación solo permite que las personas comiencen a chatear si están interesadas en el evento. Además, la única forma de saber si alguien va a venir es si lo publican en el chat. Organicémonos y hagámosle saber a la gente cuántas personas vienen.
Agregará un conmutador para registrar a las personas que desean asistir al evento, luego recopilará un recuento de cuántas personas asistirán.
- En StackBlitz, ve al archivo
index.html
. - En
guestbook-container
, agregue un conjunto de botones SÍ y NO , así:<!-- ... --> <section id="guestbook-container"> <h2>Are you attending?</h2> <button id="rsvp-yes">YES</button> <button id="rsvp-no">NO</button> <h2>Discussion</h2> <!-- ... --> </section> <!-- ... -->
Vista previa de la aplicación
A continuación, registre el oyente para los clics de botón. Si el usuario hace clic en SÍ , use su UID de autenticación para guardar la respuesta en la base de datos.
- En StackBlitz, ve al archivo
index.js
. - En la parte superior, ubique la declaración de importación
firebase/firestore
, luego agreguedoc
,setDoc
ywhere
, así:// ... // Add the Firebase products and methods that you want to use import { getFirestore, addDoc, collection, query, orderBy, onSnapshot, doc, setDoc, where } from 'firebase/firestore';
- En la parte inferior de la función
main()
, agregue el siguiente código para escuchar el estado de RSVP:async function main() { // ... // Listen to RSVP responses rsvpYes.onclick = async () => { }; rsvpNo.onclick = async () => { }; } main();
- Luego, cree una nueva colección llamada
attendees
, luego registre una referencia de documento si se hace clic en cualquiera de los botones RSVP. Establezca esa referencia entrue
ofalse
según el botón en el que se haga clic.
Primero, pararsvpYes
:
Luego, lo mismo para// ... // Listen to RSVP responses rsvpYes.onclick = async () => { // Get a reference to the user's document in the attendees collection const userRef = doc(db, 'attendees', auth.currentUser.uid); // If they RSVP'd yes, save a document with attendi()ng: true try { await setDoc(userRef, { attending: true }); } catch (e) { console.error(e); } };
rsvpNo
, pero con el valorfalse
:rsvpNo.onclick = async () => { // Get a reference to the user's document in the attendees collection const userRef = doc(db, 'attendees', auth.currentUser.uid); // If they RSVP'd yes, save a document with attending: true try { await setDoc(userRef, { attending: false }); } catch (e) { console.error(e); } };
Actualice sus reglas de seguridad
Debido a que ya tiene algunas reglas configuradas, los nuevos datos que está agregando con los botones serán rechazados.
Permitir adiciones a la colección attendees
Deberá actualizar las reglas para permitir agregar a la colección attendees
.
- Para la recopilación
attendees
, como usó el UID de autenticación como nombre del documento, puede tomarlo y verificar que eluid
del remitente sea el mismo que el del documento que está escribiendo. Permitirá que todos lean la lista de asistentes (ya que no hay datos privados allí), pero solo el creador debería poder actualizarla.rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // ... // match /attendees/{userId} { allow read: if true; allow write: if request.auth.uid == userId; } } }
- Haga clic en Publicar para implementar sus nuevas reglas.
Agregar reglas de validación
- Agregue algunas reglas de validación de datos para asegurarse de que todos los campos esperados estén presentes en el documento:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // ... // match /attendees/{userId} { allow read: if true; allow write: if request.auth.uid == userId && "attending" in request.resource.data; } } }
- ¡No olvide hacer clic en Publicar para implementar sus reglas!
(Opcional) Ahora puede ver los resultados de hacer clic en los botones. Vaya a su panel de control de Cloud Firestore en la consola de Firebase.
Leer el estado de RSVP
Ahora que ha registrado las respuestas, veamos quién viene y reflejémoslo en la interfaz de usuario.
- En StackBlitz, ve al archivo
index.html
. - En
description-container
, agregue un nuevo elemento con el ID denumber-attending
.<!-- ... --> <section id="description-container"> <!-- ... --> <p id="number-attending"></p> </section> <!-- ... -->
A continuación, registre el oyente para la colección attendees
y cuente el número de respuestas SÍ :
- En StackBlitz, ve al archivo
index.js
. - En la parte inferior de la función
main()
, agregue el siguiente código para escuchar el estado de RSVP y contar los clics SÍ .async function main() { // ... // Listen for attendee list const attendingQuery = query( collection(db, 'attendees'), where('attending', '==', true) ); const unsubscribe = onSnapshot(attendingQuery, snap => { const newAttendeeCount = snap.docs.length; numberAttending.innerHTML = newAttendeeCount + ' people going'; }); } main();
Finalmente, resaltemos el botón correspondiente al estado actual.
- Cree una función que verifique si el UID de autenticación actual tiene una entrada en la colección
attendees
, luego establezca la clase de botón enclicked
.// ... // Listen for attendee list function subscribeCurrentRSVP(user) { const ref = doc(db, 'attendees', user.uid); rsvpListener = onSnapshot(ref, doc => { if (doc && doc.data()) { const attendingResponse = doc.data().attending; // Update css classes for buttons if (attendingResponse) { rsvpYes.className = 'clicked'; rsvpNo.className = ''; } else { rsvpYes.className = ''; rsvpNo.className = 'clicked'; } } }); }
- Además, hagamos una función para darse de baja. Esto se utilizará cuando el usuario cierre la sesión.
// ... function unsubscribeCurrentRSVP() { if (rsvpListener != null) { rsvpListener(); rsvpListener = null; } rsvpYes.className = ''; rsvpNo.className = ''; }
- Llame a las funciones desde el oyente de autenticación.
// ... // Listen to the current Auth state // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; // Subscribe to the guestbook collection subscribeGuestbook(); // Subcribe to the user's RSVP subscribeCurrentRSVP(user); } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none' ; // Unsubscribe from the guestbook collection unsubscribeGuestbook(); // Unsubscribe from the guestbook collection unsubscribeCurrentRSVP(); } });
- Intente iniciar sesión como varios usuarios y vea cómo aumenta el conteo con cada clic adicional en el botón SÍ .
Vista previa de la aplicación
11. ¡Felicitaciones!
Ha utilizado Firebase para crear una aplicación web interactiva en tiempo real.
Lo que hemos cubierto
- Autenticación de base de fuego
- FirebaseUI
- Tienda de fuego en la nube
- Reglas de seguridad de Firebase
Próximos pasos
- ¿Quieres obtener más información sobre el flujo de trabajo para desarrolladores de Firebase? Consulte el laboratorio de código del emulador de Firebase para obtener información sobre cómo probar y ejecutar su aplicación de forma completamente local.
- ¿Quieres obtener más información sobre otros productos de Firebase? ¿Quizás desee almacenar archivos de imagen que cargan los usuarios? ¿O enviar notificaciones a tus usuarios? Consulte el laboratorio de código web de Firebase para ver un laboratorio de código que profundiza en muchos más productos de Firebase para la web.
- ¿Quieres saber más sobre Cloud Firestore? ¿Quizás quiera aprender sobre subcolecciones y transacciones? Diríjase al laboratorio de código web de Cloud Firestore para ver un laboratorio de código que profundiza en Cloud Firestore. ¡O echa un vistazo a esta serie de YouTube para conocer Cloud Firestore !
Aprende más
- Sitio de Firebase: firebase.google.com
- Canal de YouTube de Firebase
¿Como le fue?
Nos encantaría recibir tus comentarios! Complete un (muy) breve formulario aquí .