Conozca Firebase para la Web

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.

captura de pantalla de este paso

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.

  1. Vaya a esta URL para obtener el código de inicio: https://stackblitz.com/edit/firebase-gtk-web-start
  2. En la parte superior de la página de StackBlitz, haz clic en Fork :

captura de pantalla de este paso

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.

  1. En StackBlitz, abra el archivo index.html .
  2. Localice event-details-container y description-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

captura de pantalla de este paso

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

  1. Inicie sesión en Firebase .
  2. 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 .

    captura de pantalla de este paso

  3. 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:

  1. 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.

    captura de pantalla de este paso

  2. Seleccione la pestaña Método de inicio de sesión (o haga clic aquí para ir directamente a la pestaña).

    captura de pantalla de este paso

  3. Haga clic en Correo electrónico/Contraseña en las opciones del proveedor, cambie el interruptor a Habilitar y luego haga clic en Guardar .

    captura de pantalla de este paso

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:

  1. En el panel del lado izquierdo de Firebase console, haga clic en Build > Firestore Database . Luego haga clic en Crear base de datos .
  2. Haga clic en Crear base de datos .

    captura de pantalla de este paso

  3. 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 .

    captura de pantalla de este paso

  4. 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.

    captura de pantalla de este paso

  5. 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

  1. 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.
  2. En el centro de la página de descripción general de su proyecto, haga clic en el ícono web icono de la aplicación web para crear una nueva aplicación web de Firebase.

    captura de pantalla de este paso

  3. Registre la aplicación con el apodo Web App .
  4. 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.
  5. Haga clic en Registrar aplicación .

    captura de pantalla de este paso

  6. Copie el objeto de configuración de Firebase en su portapapeles.

    captura de pantalla de este paso

  7. Haga clic en Continuar a la consola . Agregue el objeto de configuración de Firebase a su aplicación:
  8. De vuelta en StackBlitz, vaya al archivo index.js .
  9. Ubique el Add Firebase project configuration object here , luego pegue su fragmento de configuración justo debajo del comentario.
  10. 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

  1. En StackBlitz, ve al archivo index.js .
  2. En la parte superior, ubique la instrucción de importación firebase/auth , luego agregue getAuth y EmailAuthProvider , así:
    // ...
    // Add the Firebase products and methods that you want to use
    import { getAuth, EmailAuthProvider } from 'firebase/auth';
    
    import {} from 'firebase/firestore';
    
  3. Guarde una referencia al objeto de autenticación justo después initializeApp , así:
    initializeApp(firebaseConfig);
    auth = getAuth();
    
  4. 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.
  5. En la parte inferior de la función main() en index.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

  1. En StackBlitz, ve al archivo index.html .
  2. 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 valores id que se muestran a continuación porque, para este laboratorio de programación, ya hay enlaces para estas identificaciones específicas en el archivo index.js .

    Tenga en cuenta que en el archivo index.html hay un contenedor con el ID firebaseui-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>
    <!-- ... -->
    


    captura de pantalla de este paso

  3. 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ón main() en index.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

  1. 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 o The 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.
    Vista previa de la aplicación

    captura de pantalla de este paso

  2. 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.

    captura de pantalla de este paso

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".

  1. En StackBlitz, ve al archivo index.js .
  2. En la parte superior, ubique la declaración de importación firebase/auth , luego agregue signOut y onAuthStateChanged , así:
    // ...
    // Add the Firebase products and methods that you want to use
    import {
      getAuth,
      EmailAuthProvider,
      signOut,
      onAuthStateChanged
    } from 'firebase/auth';
    
    import {} from 'firebase/firestore';
    
  3. 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();
    
  4. 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

captura de pantalla de este paso

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 .

Gráfico del modelo de datos de Firestore que muestra una colección de libros de visitas con varios documentos de mensajes

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:

  1. En StackBlitz, ve al archivo index.html .
  2. 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

captura de pantalla de este paso

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 .

  1. En StackBlitz, ve al archivo index.js .
  2. En la parte superior, ubique la declaración de importación firebase/firestore , luego agregue getFirestore , addDoc y collection , 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';
    
  3. Ahora guardaremos una referencia al objeto db de Firestore justo después de initializeApp :
    initializeApp(firebaseConfig);
    auth = getAuth();
    db = getFirestore();
    
  4. En la parte inferior de la función main() , agregue el siguiente código.

    Tenga en cuenta que auth.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).

  1. En StackBlitz, ve al archivo index.js .
  2. 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

  1. Asegúrate de haber iniciado sesión en la aplicación.
  2. 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

captura de pantalla de este paso

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:

  1. En StackBlitz, ve al archivo index.html .
  2. En guestbook-container , agregue una nueva sección con el ID de guestbook .
    <!-- ... -->
    
      <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:

  1. En StackBlitz, vaya al archivo index.js .
  2. En la parte superior, ubique la declaración de importación firebase/firestore , luego agregue query , orderBy y onSnapshot , así:
    // ...
    import {
      getFirestore,
      addDoc,
      collection,
      query,
      orderBy,
      onSnapshot
    } from 'firebase/firestore';
    
  3. 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

captura de pantalla de este paso

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:

  1. 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 ).
  2. 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.

captura de pantalla de este paso

Identificar colecciones

Primero, identifique las colecciones en las que la aplicación escribe datos.

  1. Elimine la cláusula match /{document=**} existente, para que sus reglas se vean así:
    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
      }
    }
    
  2. 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.

  1. 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;
        }
      }
    }
    
  2. 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

  1. 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;
        }
      }
    }
    
  2. 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.

  1. En StackBlitz, vaya al archivo index.js .
  2. Tire de la colección de libros de visitas en el oyente onSnapshot en una nueva función llamada subscribeGuestbook . Además, asigne los resultados de la función onSnapshot a la variable guestbookListener .

    El oyente de Firestore onSnapshot 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);
        });
      });
    }
    
  3. Agregue una nueva función debajo llamada unsubscribeGuestbook . Verifique si la variable guestbookListener 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 .

  1. Agregue subscribeGuestbook() en la parte inferior de if (user) .
  2. Agregue unsubscribeGuestbook() en la parte inferior de la instrucción else .
    // ...
    // 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.

  1. En StackBlitz, ve al archivo index.html .
  2. En guestbook-container , agregue un conjunto de botones 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

captura de pantalla de este paso

A continuación, registre el oyente para los clics de botón. Si el usuario hace clic en , use su UID de autenticación para guardar la respuesta en la base de datos.

  1. En StackBlitz, ve al archivo index.js .
  2. En la parte superior, ubique la declaración de importación firebase/firestore , luego agregue doc , setDoc y where , 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';
    
  3. 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();
    
    
  4. 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 en true o false según el botón en el que se haga clic.

    Primero, para rsvpYes :
    // ...
    // 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);
      }
    };
    
    Luego, lo mismo para rsvpNo , pero con el valor false :
    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 .

  1. Para la recopilación attendees , como usó el UID de autenticación como nombre del documento, puede tomarlo y verificar que el uid 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;
        }
      }
    }
    
  2. Haga clic en Publicar para implementar sus nuevas reglas.

Agregar reglas de validación

  1. 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;
    
        }
      }
    }
    
  2. ¡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.

  1. En StackBlitz, ve al archivo index.html .
  2. En description-container , agregue un nuevo elemento con el ID de number-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 :

  1. En StackBlitz, ve al archivo index.js .
  2. En la parte inferior de la función main() , agregue el siguiente código para escuchar el estado de RSVP y contar los clics .
    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.

  1. 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 en clicked .
    // ...
    // 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';
          }
        }
      });
    }
    
  2. 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 = '';
    }
    
  3. 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();
        }
      });
    
  4. Intente iniciar sesión como varios usuarios y vea cómo aumenta el conteo con cada clic adicional en el botón .

Vista previa de la aplicación

captura de pantalla de este paso

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

¿Como le fue?

Nos encantaría recibir tus comentarios! Complete un (muy) breve formulario aquí .