Laboratorio de código web de Firebase

1. Información general

En este laboratorio de programación, aprenderá a usar Firebase para crear fácilmente aplicaciones web mediante la implementación y el despliegue de un cliente de chat con los productos y servicios de Firebase.

3b1284f5144b54f6.png

lo que aprenderás

  • Sincroniza datos usando Cloud Firestore y Cloud Storage para Firebase.
  • Autentica a tus usuarios usando Firebase Authentication.
  • Implementa tu aplicación web en Firebase Hosting.
  • Envía notificaciones con Firebase Cloud Messaging.
  • Recopile los datos de rendimiento de su aplicación web.

Lo que necesitarás

  • El IDE/editor de texto de su elección, como WebStorm , Atom , Sublime o VS Code
  • El administrador de paquetes npm , que generalmente viene con Node.js
  • Una terminal/consola
  • Un navegador de su elección, como Chrome
  • El código de muestra del laboratorio de programación (Consulte el siguiente paso del laboratorio de programación para saber cómo obtener el código).

2. Obtenga el código de muestra

Clona el repositorio de GitHub del codelab desde la línea de comando:

git clone https://github.com/firebase/codelab-friendlychat-web

Alternativamente, si no tiene git instalado, puede descargar el repositorio como un archivo ZIP .

Importar la aplicación de inicio

Usando su IDE, abra o importe el directorio de web-start 📁 desde el repositorio clonado. Este 📁 directorio web-start contiene el código de inicio para el laboratorio de código, que será una aplicación web de chat completamente funcional.

3. Crea y configura 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 y luego nombre su proyecto de Firebase como FriendlyChat . Recuerde el ID del proyecto para su proyecto de Firebase.
  3. Desmarque Habilitar Google Analytics para este proyecto
  4. Haga clic en Crear proyecto .

La aplicación que vamos a compilar utiliza productos de Firebase que están disponibles para aplicaciones web:

  • Firebase Authentication 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.
  • Cloud Storage para Firebase para guardar archivos en la nube.
  • Firebase Hosting para alojar y servir sus activos.
  • Firebase Cloud Messaging para enviar notificaciones automáticas y mostrar notificaciones emergentes del navegador.
  • Firebase Performance Monitoring para recopilar datos de rendimiento del usuario para su aplicación.

Algunos de estos productos necesitan una configuración especial o deben habilitarse mediante la consola Firebase.

Agregar una aplicación web de Firebase al proyecto

  1. Haga clic en el icono de la web 58d6543a156e56f9.png para crear una nueva aplicación web de Firebase.
  2. Registre la aplicación con el apodo Friendly Chat , luego marque la casilla junto a Configurar también Firebase Hosting para esta aplicación . Haga clic en Registrar aplicación .
  3. En el siguiente paso, verá un objeto de configuración. Copie solo el objeto JS (no el HTML circundante) en firebase-config.js

Registrar captura de pantalla de la aplicación web

Habilitar el inicio de sesión de Google para la autenticación de Firebase

Para permitir que los usuarios inicien sesión en la aplicación web con sus cuentas de Google, utilizaremos el método de inicio de sesión de Google .

Deberá habilitar el inicio de sesión de Google :

  1. En Firebase console, busque la sección Build en el panel izquierdo.
  2. Haga clic en Autenticación , luego haga clic en la pestaña Método de inicio de sesión (o haga clic aquí para ir directamente allí).
  3. Habilite el proveedor de inicio de sesión de Google , luego haga clic en Guardar .
  4. Establezca el nombre público de su aplicación en Friendly Chat y elija un correo electrónico de soporte del proyecto en el menú desplegable.
  5. Configure su pantalla de consentimiento de OAuth en Google Cloud Console y agregue un logotipo:

d89fb3873b5d36ae.png

Habilitar Cloud Firestore

La aplicación web usa Cloud Firestore para guardar mensajes de chat y recibir nuevos mensajes de chat.

Deberá habilitar Cloud Firestore:

  1. En la sección Crear de la consola Firebase, haga clic en Base de datos de Firestore .
  2. Haga clic en Crear base de datos en el panel de Cloud Firestore.

729991a081e7cd5.png

  1. Seleccione la opción Iniciar en modo de prueba , luego haga clic en Siguiente después de leer el descargo de responsabilidad sobre las reglas de seguridad.

El modo de prueba garantiza que podamos escribir libremente en la base de datos durante el desarrollo. Haremos que nuestra base de datos sea más segura más adelante en este codelab.

77e4986cbeaf9dee.png

  1. Establezca la ubicación donde se almacenan sus datos de Cloud Firestore. Puede dejar esto como predeterminado o elegir una región cercana a usted. Haga clic en Listo para aprovisionar Firestore.

9f2bb0d4e7ca49c7.png

Habilitar almacenamiento en la nube

La aplicación web usa Cloud Storage para Firebase para almacenar, cargar y compartir imágenes.

Deberá habilitar el almacenamiento en la nube:

  1. En la sección Compilación de la consola Firebase , haga clic en Almacenamiento .
  2. Si no hay un botón Comenzar , significa que el almacenamiento en la nube ya está habilitado y no necesita seguir los pasos a continuación.
  3. Haga clic en Comenzar .
  4. Lea el descargo de responsabilidad sobre las reglas de seguridad para su proyecto de Firebase y luego haga clic en Siguiente .

Con las reglas de seguridad predeterminadas, cualquier usuario autenticado puede escribir cualquier cosa en Cloud Storage. Haremos que nuestro almacenamiento sea más seguro más adelante en este laboratorio de código.

62f1afdcd1260127.png

  1. La ubicación de Cloud Storage está preseleccionada con la misma región que eligió para su base de datos de Cloud Firestore. Haga clic en Listo para completar la configuración.

1d7f49ebaddb32fc.png

4. Instala la interfaz de línea de comandos de Firebase

La interfaz de línea de comandos (CLI) de Firebase le permite usar Firebase Hosting para servir su aplicación web localmente, así como para implementar su aplicación web en su proyecto de Firebase.

  1. Instale la CLI ejecutando el siguiente comando npm:
npm -g install firebase-tools
  1. Verifique que la CLI se haya instalado correctamente ejecutando el siguiente comando:
firebase --version

Asegúrese de que la versión de Firebase CLI sea v4.1.0 o posterior.

  1. Autorice Firebase CLI ejecutando el siguiente comando:
firebase login

Configuramos la plantilla de la aplicación web para extraer la configuración de su aplicación para Firebase Hosting desde el directorio local de su aplicación (el repositorio que clonó anteriormente en el laboratorio de código). Pero para obtener la configuración, debemos asociar su aplicación con su proyecto de Firebase.

  1. Asegúrese de que su línea de comando esté accediendo al directorio web-start local de su aplicación.
  2. Asocie su aplicación con su proyecto de Firebase ejecutando el siguiente comando:
firebase use --add
  1. Cuando se le solicite, seleccione su ID de proyecto , luego asigne un alias a su proyecto de Firebase.

Un alias es útil si tiene varios entornos (producción, puesta en escena, etc.). Sin embargo, para este laboratorio de código, solo usemos el alias de default .

  1. Siga las instrucciones restantes en su línea de comando.

5. Ejecute la aplicación de inicio localmente

Ahora que ha importado y configurado su proyecto, está listo para ejecutar la aplicación web por primera vez.

  1. En una consola desde el directorio web-start , ejecute el siguiente comando de Firebase CLI:
firebase serve --only hosting
  1. Su línea de comando debería mostrar la siguiente respuesta:
✔  hosting: Local server: http://localhost:5000

Usamos el emulador de Firebase Hosting para servir nuestra aplicación localmente. La aplicación web ahora debería estar disponible en http://localhost:5000 . Se sirven todos los archivos que se encuentran en el subdirectorio public .

  1. Usando su navegador, abra su aplicación en http://localhost:5000 .

Debería ver la interfaz de usuario de su aplicación FriendlyChat, que (¡todavía!) no funciona:

4c23f9475228cef4.png

La aplicación no puede hacer nada en este momento, ¡pero con tu ayuda lo hará pronto! Hasta ahora, solo hemos presentado la interfaz de usuario para usted.

¡Ahora construyamos un chat en tiempo real!

6. Importar y configurar Firebase

Importar el SDK de Firebase

Necesitamos importar el SDK de Firebase a la aplicación. Hay varias formas de hacer esto, como se describe en nuestra documentación . Por ejemplo, puede importar la biblioteca desde nuestro CDN. O puede instalarlo localmente usando npm, luego empaquetarlo en su aplicación si está usando Browserify.

Obtendremos el SDK de Firebase de npm y usaremos Webpack para agrupar nuestro código. Estamos haciendo esto para que Webpack pueda eliminar cualquier código innecesario, manteniendo el tamaño de nuestro paquete JS pequeño para asegurarnos de que nuestra aplicación se cargue lo más rápido posible. Para este laboratorio de código, ya creamos un archivo web-start/package.json que incluye el SDK de Firebase como una dependencia, además de importar las funciones necesarias en la parte superior de web-start/src/index.js .

paquete.json

"dependencies": {
  "firebase": "^9.0.0"
}

índice.js

import { initializeApp } from 'firebase/app';
import {
  getAuth,
  onAuthStateChanged,
  GoogleAuthProvider,
  signInWithPopup,
  signOut,
} from 'firebase/auth';
import {
  getFirestore,
  collection,
  addDoc,
  query,
  orderBy,
  limit,
  onSnapshot,
  setDoc,
  updateDoc,
  doc,
  serverTimestamp,
} from 'firebase/firestore';
import {
  getStorage,
  ref,
  uploadBytesResumable,
  getDownloadURL,
} from 'firebase/storage';
import { getMessaging, getToken, onMessage } from 'firebase/messaging';
import { getPerformance } from 'firebase/performance';

Durante este laboratorio de programación, usaremos Firebase Authentication, Cloud Firestore, Cloud Storage, Cloud Messaging y Performance Monitoring, por lo que importaremos todas sus bibliotecas. En sus aplicaciones futuras, asegúrese de importar solo las partes de Firebase que necesita para acortar el tiempo de carga de su aplicación.

Instale el SDK de Firebase e inicie la compilación de su Webpack

Necesitamos ejecutar algunos comandos para que la compilación de nuestra aplicación funcione.

  1. Abrir una nueva ventana de terminal
  2. Asegúrate de estar en el directorio web-start
  3. Ejecute npm install para descargar el SDK de Firebase
  4. Ejecute npm run start para iniciar Webpack. Webpack ahora reconstruirá continuamente nuestro código fuente para el resto del laboratorio de código.

Configurar base de fuego

También necesitamos configurar el SDK de Firebase para indicarle qué proyecto de Firebase estamos usando.

  1. Vaya a la configuración de su proyecto en la consola de Firebase
  2. En la tarjeta "Tus aplicaciones", selecciona el apodo de la aplicación para la que necesitas un objeto de configuración.
  3. Seleccione "Configuración" en el panel de fragmentos del SDK de Firebase.
  4. Copie el fragmento del objeto de configuración y luego agréguelo a web-start/src/firebase-config.js .

firebase-config.js

const config = {
  apiKey: "API_KEY",
  authDomain: "PROJECT_ID.firebaseapp.com",
  databaseURL: "https://PROJECT_ID.firebaseio.com",
  projectId: "PROJECT_ID",
  storageBucket: "PROJECT_ID.appspot.com",
  messagingSenderId: "SENDER_ID",
  appId: "APP_ID",
  measurementId: "G-MEASUREMENT_ID",
};

Ahora, ve al final de web-start/src/index.js e inicializa Firebase:

índice.js

const firebaseAppConfig = getFirebaseConfig();
initializeApp(firebaseAppConfig);

7. Configurar el inicio de sesión de usuario

El SDK de Firebase ahora debería estar listo para usarse, ya que se importó e inicializó en index.html . Ahora vamos a implementar el inicio de sesión de usuario mediante Firebase Authentication .

Autentica a tus usuarios con Google Sign-In

En la aplicación, cuando un usuario hace clic en el botón Iniciar sesión con Google , se signIn la función de inicio de sesión. (¡Ya lo configuramos para usted!) Para este laboratorio de código, queremos autorizar a Firebase a usar Google como proveedor de identidad. Usaremos una ventana emergente, pero hay varios otros métodos disponibles en Firebase.

  1. En el directorio web-start , en el subdirectorio src/ , abra index.js .
  2. Encuentra la función signIn .
  3. Reemplace toda la función con el siguiente código.

índice.js

// Signs-in Friendly Chat.
async function signIn() {
  // Sign in Firebase using popup auth and Google as the identity provider.
  var provider = new GoogleAuthProvider();
  await signInWithPopup(getAuth(), provider);
}

La función signOut se activa cuando el usuario hace clic en el botón Cerrar sesión .

  1. Vuelva al archivo src/index.js .
  2. Busque la función signOutUser .
  3. Reemplace toda la función con el siguiente código.

índice.js

// Signs-out of Friendly Chat.
function signOutUser() {
  // Sign out of Firebase.
  signOut(getAuth());
}

Seguimiento del estado de autenticación

Para actualizar nuestra interfaz de usuario en consecuencia, necesitamos una forma de verificar si el usuario inició o cerró sesión. Con Firebase Authentication, puede registrar un observador en el estado de autenticación que se activará cada vez que cambie el estado de autenticación.

  1. Vuelva al archivo src/index.js .
  2. Encuentra la función initFirebaseAuth .
  3. Reemplace toda la función con el siguiente código.

índice.js

// Initialize firebase auth
function initFirebaseAuth() {
  // Listen to auth state changes.
  onAuthStateChanged(getAuth(), authStateObserver);
}

El código anterior registra la función authStateObserver como observador del estado de autenticación. Se activará cada vez que cambie el estado de autenticación (cuando el usuario inicie o cierre sesión). Es en este punto que actualizaremos la interfaz de usuario para mostrar u ocultar el botón de inicio de sesión, el botón de cierre de sesión, la imagen de perfil del usuario que inició sesión, etc. Todas estas partes de la interfaz de usuario ya se han implementado.

Mostrar la información del usuario registrado

Queremos mostrar la imagen de perfil y el nombre de usuario del usuario que inició sesión en la barra superior de nuestra aplicación. En Firebase, los datos del usuario que inició sesión siempre están disponibles en el objeto currentUser . Anteriormente, configuramos la función authStateObserver para que se active cuando el usuario inicia sesión para que nuestra interfaz de usuario se actualice en consecuencia. Llamará a getProfilePicUrl y getUserName cuando se active.

  1. Vuelva al archivo src/index.js .
  2. Busque las funciones getProfilePicUrl y getUserName .
  3. Reemplace ambas funciones con el siguiente código.

índice.js

// Returns the signed-in user's profile Pic URL.
function getProfilePicUrl() {
  return getAuth().currentUser.photoURL || '/images/profile_placeholder.png';
}

// Returns the signed-in user's display name.
function getUserName() {
  return getAuth().currentUser.displayName;
}

Mostramos un mensaje de error si el usuario intenta enviar mensajes cuando el usuario no ha iniciado sesión. (¡Sin embargo, puede intentarlo!) Por lo tanto, debemos detectar si el usuario realmente ha iniciado sesión.

  1. Vuelva al archivo src/index.js .
  2. Busque la función isUserSignedIn .
  3. Reemplace toda la función con el siguiente código.

índice.js

// Returns true if a user is signed-in.
function isUserSignedIn() {
  return !!getAuth().currentUser;
}

Probar el inicio de sesión en la aplicación

  1. Si su aplicación todavía se está sirviendo, actualice su aplicación en el navegador. De lo contrario, ejecute firebase serve --only hosting en la línea de comando para comenzar a servir la aplicación desde http://localhost:5000 y luego ábrala en su navegador.
  2. Inicie sesión en la aplicación utilizando el botón de inicio de sesión y su cuenta de Google. Si ve un mensaje de error que indica auth/operation-not-allowed , verifique que haya habilitado Google Sign-in como proveedor de autenticación en Firebase console.
  3. Después de iniciar sesión, se debe mostrar su foto de perfil y nombre de usuario: c7401b3d44d0d78b.png

8. Escribe mensajes en Cloud Firestore

En esta sección, escribiremos algunos datos en Cloud Firestore para que podamos completar la interfaz de usuario de la aplicación. Esto se puede hacer manualmente con la consola de Firebase , pero lo haremos en la propia aplicación para demostrar una escritura básica de Cloud Firestore.

Modelo de datos

Los datos de Cloud Firestore se dividen en colecciones, documentos, campos y subcolecciones. Almacenaremos cada mensaje del chat como un documento en una colección de nivel superior llamada messages .

688d7bc5fb662b57.png

Agregar mensajes a Cloud Firestore

Para almacenar los mensajes de chat que escriben los usuarios, usaremos Cloud Firestore .

En esta sección, agregará la funcionalidad para que los usuarios escriban nuevos mensajes en su base de datos. Un usuario que haga clic en el botón ENVIAR activará el fragmento de código a continuación. Agrega un objeto de mensaje con el contenido de los campos de mensaje a su instancia de Cloud Firestore en la colección de messages . El método add() agrega un nuevo documento con una ID generada automáticamente a la colección.

  1. Vuelva al archivo src/index.js .
  2. Encuentra la función saveMessage .
  3. Reemplace toda la función con el siguiente código.

índice.js

// Saves a new message to Cloud Firestore.
async function saveMessage(messageText) {
  // Add a new message entry to the Firebase database.
  try {
    await addDoc(collection(getFirestore(), 'messages'), {
      name: getUserName(),
      text: messageText,
      profilePicUrl: getProfilePicUrl(),
      timestamp: serverTimestamp()
    });
  }
  catch(error) {
    console.error('Error writing new message to Firebase Database', error);
  }
}

Probar el envío de mensajes

  1. Si su aplicación todavía se está sirviendo, actualice su aplicación en el navegador. De lo contrario, ejecute firebase serve --only hosting en la línea de comando para comenzar a servir la aplicación desde http://localhost:5000 y luego ábrala en su navegador.
  2. Después de iniciar sesión, ingrese un mensaje como "¡Hola!" y luego haga clic en ENVIAR . Esto escribirá el mensaje en Cloud Firestore. Sin embargo, aún no verá los datos en su aplicación web real porque todavía tenemos que implementar la recuperación de datos (la siguiente sección del laboratorio de código).
  3. Puede ver el mensaje recién agregado en su Firebase Console. Abra su consola Firebase. En la sección Crear , haga clic en Firestore Database (o haga clic aquí y seleccione su proyecto) y debería ver la colección de mensajes con su mensaje recién agregado:

6812efe7da395692.png

9. Leer mensajes

Sincronizar mensajes

Para leer mensajes en la aplicación, necesitaremos agregar oyentes que se activen cuando cambien los datos y luego crear un elemento de interfaz de usuario que muestre mensajes nuevos.

Agregaremos un código que escuche los mensajes recién agregados desde la aplicación. En este código, registraremos el oyente que escucha los cambios realizados en los datos. Solo mostraremos los últimos 12 mensajes del chat para evitar mostrar un historial muy largo al cargar.

  1. Vuelva al archivo src/index.js .
  2. Encuentra la función loadMessages .
  3. Reemplace toda la función con el siguiente código.

índice.js

// Loads chat messages history and listens for upcoming ones.
function loadMessages() {
  // Create the query to load the last 12 messages and listen for new ones.
  const recentMessagesQuery = query(collection(getFirestore(), 'messages'), orderBy('timestamp', 'desc'), limit(12));
  
  // Start listening to the query.
  onSnapshot(recentMessagesQuery, function(snapshot) {
    snapshot.docChanges().forEach(function(change) {
      if (change.type === 'removed') {
        deleteMessage(change.doc.id);
      } else {
        var message = change.doc.data();
        displayMessage(change.doc.id, message.timestamp, message.name,
                      message.text, message.profilePicUrl, message.imageUrl);
      }
    });
  });
}

Para escuchar mensajes en la base de datos, creamos una consulta en una colección usando la función de collection para especificar en qué colección están los datos que queremos escuchar. En el código anterior, estamos escuchando los cambios dentro de los messages . colección, que es donde se almacenan los mensajes de chat. También estamos aplicando un límite escuchando solo los últimos 12 mensajes usando .limit(12) y ordenando los mensajes por fecha usando orderBy('timestamp', 'desc') para obtener los 12 mensajes más nuevos.

La función onSnapshot toma una consulta como primer parámetro y una función de devolución de llamada como segundo. La función de devolución de llamada se activará cuando haya cambios en los documentos que coincidan con la consulta. Esto podría ser si un mensaje se elimina, modifica o agrega. Puede leer más sobre esto en la documentación de Cloud Firestore .

Prueba sincronizando mensajes

  1. Si su aplicación todavía se está sirviendo, actualice su aplicación en el navegador. De lo contrario, ejecute firebase serve --only hosting en la línea de comando para comenzar a servir la aplicación desde http://localhost:5000 y luego ábrala en su navegador.
  2. Los mensajes que creó anteriormente en la base de datos deben mostrarse en la interfaz de usuario de FriendlyChat (consulte a continuación). Siéntete libre de escribir nuevos mensajes; deberían aparecer al instante.
  3. (Opcional) Puede intentar eliminar, modificar o agregar nuevos mensajes manualmente directamente en la sección Base de datos de Firebase console; cualquier cambio debe reflejarse en la interfaz de usuario.

¡Felicidades! ¡Está leyendo documentos de Cloud Firestore en su aplicación!

2168dic79b573d07.png

10. Enviar imágenes

Ahora agregaremos una característica que comparte imágenes.

Si bien Cloud Firestore es bueno para almacenar datos estructurados, Cloud Storage es más adecuado para almacenar archivos. Cloud Storage para Firebase es un servicio de almacenamiento de archivos/blobs, y lo usaremos para almacenar cualquier imagen que un usuario comparta usando nuestra aplicación.

Guardar imágenes en el almacenamiento en la nube

Para este laboratorio de código, ya hemos agregado para usted un botón que activa un cuadro de diálogo de selección de archivos. Después de seleccionar un archivo, se llama a la función saveImageMessage y puede obtener una referencia al archivo seleccionado. La función saveImageMessage logra lo siguiente:

  1. Crea un mensaje de chat de "marcador de posición" en el feed de chat, para que los usuarios vean una animación de "Cargando" mientras cargamos la imagen.
  2. Carga el archivo de imagen en Cloud Storage a esta ruta: /<uid>/<messageId>/<file_name>
  3. Genera una URL legible públicamente para el archivo de imagen.
  4. Actualiza el mensaje de chat con la URL del archivo de imagen recién cargado en lugar de la imagen de carga temporal.

Ahora agregará la funcionalidad para enviar una imagen:

  1. Vuelva al archivo src/index.js .
  2. Encuentra la función saveImageMessage .
  3. Reemplace toda la función con el siguiente código.

índice.js

// Saves a new message containing an image in Firebase.
// This first saves the image in Firebase storage.
async function saveImageMessage(file) {
  try {
    // 1 - We add a message with a loading icon that will get updated with the shared image.
    const messageRef = await addDoc(collection(getFirestore(), 'messages'), {
      name: getUserName(),
      imageUrl: LOADING_IMAGE_URL,
      profilePicUrl: getProfilePicUrl(),
      timestamp: serverTimestamp()
    });

    // 2 - Upload the image to Cloud Storage.
    const filePath = `${getAuth().currentUser.uid}/${messageRef.id}/${file.name}`;
    const newImageRef = ref(getStorage(), filePath);
    const fileSnapshot = await uploadBytesResumable(newImageRef, file);
    
    // 3 - Generate a public URL for the file.
    const publicImageUrl = await getDownloadURL(newImageRef);

    // 4 - Update the chat message placeholder with the image's URL.
    await updateDoc(messageRef,{
      imageUrl: publicImageUrl,
      storageUri: fileSnapshot.metadata.fullPath
    });
  } catch (error) {
    console.error('There was an error uploading a file to Cloud Storage:', error);
  }
}

Prueba de envío de imágenes

  1. Si su aplicación todavía se está sirviendo, actualice su aplicación en el navegador. De lo contrario, ejecute firebase serve --only hosting en la línea de comando para comenzar a servir la aplicación desde http://localhost:5000 y luego ábrala en su navegador.
  2. Después de iniciar sesión, haga clic en el botón de carga de imágenes 13734cb66773e5a3.png y seleccione un archivo de imagen usando el selector de archivos. Si está buscando una imagen, siéntase libre de usar esta bonita imagen de una taza de café .
  3. Debería aparecer un nuevo mensaje en la interfaz de usuario de la aplicación con la imagen seleccionada: 3b1284f5144b54f6.png

Si intenta agregar una imagen sin iniciar sesión, debería ver una notificación de Toast que le indica que debe iniciar sesión para agregar imágenes.

11. Mostrar notificaciones

Ahora agregaremos soporte para las notificaciones del navegador. La aplicación notificará a los usuarios cuando se publiquen nuevos mensajes en el chat. Firebase Cloud Messaging (FCM) es una solución de mensajería multiplataforma que le permite entregar mensajes y notificaciones de manera confiable sin costo alguno.

Agregar el trabajador de servicio de FCM

La aplicación web necesita un trabajador de servicio que reciba y muestre notificaciones web.

  1. Desde el directorio web-start , en el directorio src , abra firebase-messaging-sw.js .
  2. Agregue el siguiente contenido a ese archivo.

firebase-messaging-sw.js

// Import and configure the Firebase SDK
import { initializeApp } from 'firebase/app';
import { getMessaging } from 'firebase/messaging/sw';
import { getFirebaseConfig } from './firebase-config';

const firebaseApp = initializeApp(getFirebaseConfig());
getMessaging(firebaseApp);
console.info('Firebase messaging service worker is set up');

El trabajador del servicio simplemente necesita cargar e inicializar el SDK de Firebase Cloud Messaging, que se encargará de mostrar las notificaciones.

Obtener tokens de dispositivo FCM

Cuando se han habilitado las notificaciones en un dispositivo o navegador, se le otorgará un token de dispositivo . Este token de dispositivo es lo que usamos para enviar una notificación a un dispositivo o navegador en particular.

Cuando el usuario inicia sesión, llamamos a la función saveMessagingDeviceToken . Ahí es donde obtendremos el token del dispositivo FCM del navegador y lo guardaremos en Cloud Firestore.

  1. Vuelva al archivo src/index.js .
  2. Busque la función saveMessagingDeviceToken .
  3. Reemplace toda la función con el siguiente código.

índice.js

// Saves the messaging device token to Cloud Firestore.
async function saveMessagingDeviceToken() {
  try {
    const currentToken = await getToken(getMessaging());
    if (currentToken) {
      console.log('Got FCM device token:', currentToken);
      // Saving the Device Token to Cloud Firestore.
      const tokenRef = doc(getFirestore(), 'fcmTokens', currentToken);
      await setDoc(tokenRef, { uid: getAuth().currentUser.uid });

      // This will fire when a message is received while the app is in the foreground.
      // When the app is in the background, firebase-messaging-sw.js will receive the message instead.
      onMessage(getMessaging(), (message) => {
        console.log(
          'New foreground notification from Firebase Messaging!',
          message.notification
        );
      });
    } else {
      // Need to request permissions to show notifications.
      requestNotificationsPermissions();
    }
  } catch(error) {
    console.error('Unable to get messaging token.', error);
  };
}

Sin embargo, este código no funcionará inicialmente. Para que su aplicación pueda recuperar el token del dispositivo, el usuario debe otorgarle permiso a su aplicación para mostrar notificaciones (siguiente paso del laboratorio de programación).

Solicitar permisos para mostrar notificaciones

Cuando el usuario aún no haya otorgado permiso a su aplicación para mostrar notificaciones, no se le otorgará un token de dispositivo. En este caso, llamamos al firebase.messaging().requestPermission() , que mostrará un cuadro de diálogo del navegador solicitando este permiso ( en los navegadores compatibles ).

8b9d0c66dc36153d.png

  1. Vuelva al archivo src/index.js .
  2. Busque la función requestNotificationsPermissions .
  3. Reemplace toda la función con el siguiente código.

índice.js

// Requests permissions to show notifications.
async function requestNotificationsPermissions() {
  console.log('Requesting notifications permission...');
  const permission = await Notification.requestPermission();
  
  if (permission === 'granted') {
    console.log('Notification permission granted.');
    // Notification permission granted.
    await saveMessagingDeviceToken();
  } else {
    console.log('Unable to get permission to notify.');
  }
}

Consigue tu token de dispositivo

  1. Si su aplicación todavía se está sirviendo, actualice su aplicación en el navegador. De lo contrario, ejecute firebase serve --only hosting en la línea de comando para comenzar a servir la aplicación desde http://localhost:5000 y luego ábrala en su navegador.
  2. Después de iniciar sesión, debería aparecer el cuadro de diálogo de permiso de notificaciones: bd3454e6dbfb6723.png
  3. Haga clic en Permitir .
  4. Abra la consola JavaScript de su navegador. Debería ver el siguiente mensaje Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
  5. Copie el token de su dispositivo. Lo necesitará para la siguiente etapa del laboratorio de programación.

Envía una notificación a tu dispositivo

Ahora que tiene el token de su dispositivo, puede enviar una notificación.

  1. Abra la pestaña Cloud Messaging de Firebase console .
  2. Haga clic en "Nueva Notificación"
  3. Ingrese un título de notificación y un texto de notificación.
  4. En el lado derecho de la pantalla, haga clic en "enviar un mensaje de prueba"
  5. Ingrese el token del dispositivo que copió de la consola de JavaScript de su navegador, luego haga clic en el signo más ("+")
  6. Haga clic en "prueba"

Si su aplicación está en primer plano, verá la notificación en la consola de JavaScript.

Si su aplicación está en segundo plano, debería aparecer una notificación en su navegador, como en este ejemplo:

de79e8638a45864c.png

12. Reglas de seguridad de Cloud Firestore

Ver las reglas de seguridad de la base de datos

Cloud Firestore utiliza un lenguaje de reglas específico para definir los derechos de acceso, la seguridad y las validaciones de datos.

Al configurar el proyecto de Firebase al comienzo de este laboratorio de programación, elegimos usar las reglas de seguridad predeterminadas del "modo de prueba" para no restringir el acceso al almacén de datos. En Firebase console , en la pestaña Reglas de la sección Base de datos, puede ver y modificar estas reglas.

En este momento, debería ver las reglas predeterminadas, que no restringen el acceso al almacén de datos. Esto significa que cualquier usuario puede leer y escribir en cualquier colección de su almacén de datos.

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write;
    }
  }
}

Actualizaremos las reglas para restringir las cosas usando las siguientes reglas:

firestore.reglas

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    // Messages:
    //   - Anyone can read.
    //   - Authenticated users can add and edit messages.
    //   - Validation: Check name is same as auth token and text length below 300 char or that imageUrl is a URL.
    //   - Deletes are not allowed.
    match /messages/{messageId} {
      allow read;
      allow create, update: if request.auth != null
                    && request.resource.data.name == request.auth.token.name
                    && (request.resource.data.text is string
                      && request.resource.data.text.size() <= 300
                      || request.resource.data.imageUrl is string
                      && request.resource.data.imageUrl.matches('https?://.*'));
      allow delete: if false;
    }
    // FCM Tokens:
    //   - Anyone can write their token.
    //   - Reading list of tokens is not allowed.
    match /fcmTokens/{token} {
      allow read: if false;
      allow write;
    }
  }
}

Actualizar las reglas de seguridad de la base de datos

Hay dos formas de editar las reglas de seguridad de su base de datos, ya sea en Firebase console o desde un archivo de reglas local implementado mediante Firebase CLI.

Para actualizar las reglas de seguridad en Firebase console:

  1. Vaya a la sección Base de datos del panel izquierdo y luego haga clic en la pestaña Reglas .
  2. Reemplace las reglas predeterminadas que ya están en la consola con las reglas que se muestran arriba.
  3. Haz clic en Publicar .

Para actualizar las reglas de seguridad desde un archivo local:

  1. Desde el directorio web-start , abra firestore.rules .
  2. Reemplace las reglas predeterminadas que ya están en el archivo con las reglas que se muestran arriba.
  3. Desde el directorio web-start , abra firebase.json .
  4. Agregue el atributo firestore.rules que apunte a firestore.rules , como se muestra a continuación. (El atributo hosting ya debería estar en el archivo).

base de fuego.json

{
  // Add this!
  "firestore": {
    "rules": "firestore.rules"
  },
  "hosting": {
    "public": "./public"
  }
}
  1. Implemente las reglas de seguridad mediante Firebase CLI ejecutando el siguiente comando:
firebase deploy --only firestore
  1. Su línea de comando debería mostrar la siguiente respuesta:
=== Deploying to 'friendlychat-1234'...

i  deploying firestore
i  firestore: checking firestore.rules for compilation errors...
✔  firestore: rules file firestore.rules compiled successfully
i  firestore: uploading rules firestore.rules...
✔  firestore: released rules firestore.rules to cloud.firestore

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview

13. Reglas de seguridad del almacenamiento en la nube

Ver las reglas de seguridad de Cloud Storage

Cloud Storage para Firebase usa un lenguaje de reglas específico para definir los derechos de acceso, la seguridad y las validaciones de datos.

Al configurar el proyecto de Firebase al comienzo de este laboratorio de código, elegimos usar la regla de seguridad predeterminada de Cloud Storage que solo permite que los usuarios autenticados usen Cloud Storage. En Firebase console , en la pestaña Reglas de la sección Almacenamiento , puede ver y modificar las reglas. Debería ver la regla predeterminada que permite que cualquier usuario que haya iniciado sesión lea y escriba cualquier archivo en su depósito de almacenamiento.

rules_version = '2';

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Actualizaremos las reglas para hacer lo siguiente:

  • Permita que cada usuario escriba solo en sus propias carpetas específicas
  • Permitir que cualquier persona lea desde Cloud Storage
  • Asegúrate de que los archivos subidos sean imágenes.
  • Restrinja el tamaño de las imágenes que se pueden cargar a un máximo de 5 MB

Esto se puede implementar usando las siguientes reglas:

reglas.de.almacenamiento

rules_version = '2';

// Returns true if the uploaded file is an image and its size is below the given number of MB.
function isImageBelowMaxSize(maxSizeMB) {
  return request.resource.size < maxSizeMB * 1024 * 1024
      && request.resource.contentType.matches('image/.*');
}

service firebase.storage {
  match /b/{bucket}/o {
    match /{userId}/{messageId}/{fileName} {
      allow write: if request.auth != null && request.auth.uid == userId && isImageBelowMaxSize(5);
      allow read;
    }
  }
}

Actualizar las reglas de seguridad de Cloud Storage

Hay dos formas de editar sus reglas de seguridad de almacenamiento: ya sea en la consola de Firebase o desde un archivo de reglas local implementado mediante la CLI de Firebase.

Para actualizar las reglas de seguridad en Firebase console:

  1. Vaya a la sección Almacenamiento desde el panel izquierdo y luego haga clic en la pestaña Reglas .
  2. Reemplace la regla predeterminada que ya está en la consola con las reglas que se muestran arriba.
  3. Haz clic en Publicar .

Para actualizar las reglas de seguridad desde un archivo local:

  1. Desde el directorio web-start , abra storage.rules .
  2. Reemplace las reglas predeterminadas que ya están en el archivo con las reglas que se muestran arriba.
  3. Desde el directorio web-start , abra firebase.json .
  4. Agregue el atributo storage.rules que apunta al archivo storage.rules , como se muestra a continuación. (El atributo de hosting y database de datos ya debería estar en el archivo).

base de fuego.json

{
  // If you went through the "Cloud Firestore Security Rules" step.
  "firestore": {
    "rules": "firestore.rules"
  },
  // Add this!
  "storage": {
    "rules": "storage.rules"
  },
  "hosting": {
    "public": "./public"
  }
}
  1. Implemente las reglas de seguridad mediante Firebase CLI ejecutando el siguiente comando:
firebase deploy --only storage
  1. Su línea de comando debería mostrar la siguiente respuesta:
=== Deploying to 'friendlychat-1234'...

i  deploying storage
i  storage: checking storage.rules for compilation errors...
✔  storage: rules file storage.rules compiled successfully
i  storage: uploading rules storage.rules...
✔  storage: released rules storage.rules to firebase.storage/friendlychat-1234.appspot.com

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview

14. Recopilar datos de rendimiento

Puede usar el SDK de Performance Monitoring para recopilar datos de rendimiento del mundo real de su aplicación y luego revisar y analizar esos datos en Firebase console. Performance Monitoring lo ayuda a comprender dónde y cuándo se puede mejorar el rendimiento de su aplicación para que pueda usar esa información para solucionar problemas de rendimiento.

Hay varias formas de integrarse con el SDK de JavaScript de Firebase Performance Monitoring. En este laboratorio de código, habilitamos la supervisión del rendimiento de las URL de alojamiento . Consulte la documentación para ver otros métodos para habilitar el SDK.

Seguimientos automáticos

Dado que ya importamos getPerformance en la parte superior de web-start/src/index.js , solo necesitamos agregar una línea para decirle a Performance Monitoring que recopile automáticamente las métricas de carga de página y solicitud de red cuando los usuarios visitan su sitio implementado.

  1. En web-start/src/index.js , agregue la siguiente línea debajo de TODO existente para inicializar Performance Monitoring.

índice.js

// TODO: Enable Firebase Performance Monitoring.
getPerformance();

Medir el primer retardo de entrada (opcional)

El retraso de la primera entrada es útil ya que el navegador que responde a una interacción del usuario les brinda a sus usuarios sus primeras impresiones sobre la capacidad de respuesta de su aplicación.

El primer retraso de entrada comienza cuando el usuario interactúa por primera vez con un elemento en la página, como hacer clic en un botón o hipervínculo. Se detiene inmediatamente después de que el navegador puede responder a la entrada, lo que significa que el navegador no está ocupado cargando o analizando el contenido de su página.

Si desea medir el retraso de la primera entrada, deberá incluir el siguiente código directamente.

  1. Abra public/index.html .
  2. Quite el comentario de la etiqueta del script en la siguiente línea.

índice.html

<!-- TODO: Enable First Input Delay polyfill library. -->
<script type="text/javascript">!function(n,e){var t,o,i,c=[],f={passive:!0,capture:!0},r=new Date,a="pointerup",u="pointercancel";function p(n,c){t||(t=c,o=n,i=new Date,w(e),s())}function s(){o>=0&&o<i-r&&(c.forEach(function(n){n(o,t)}),c=[])}function l(t){if(t.cancelable){var o=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,o){function i(){p(t,o),r()}function c(){r()}function r(){e(a,i,f),e(u,c,f)}n(a,i,f),n(u,c,f)}(o,t):p(o,t)}}function w(n){["click","mousedown","keydown","touchstart","pointerdown"].forEach(function(e){n(e,l,f)})}w(n),self.perfMetrics=self.perfMetrics||{},self.perfMetrics.onFirstInputDelay=function(n){c.push(n),s()}}(addEventListener,removeEventListener);</script>

Para leer más sobre el primer polyfill de retraso de entrada, echa un vistazo a la documentación .

Ver datos de rendimiento

Como aún no ha implementado su sitio (lo implementará en el siguiente paso), aquí hay una captura de pantalla que muestra las métricas sobre el rendimiento de carga de la página que verá en la consola de Firebase dentro de los 30 minutos posteriores a la interacción de los usuarios con su sitio implementado. :

29389131150f33d7.png

Cuando integra el SDK de Monitoreo de rendimiento en su aplicación, no necesita escribir ningún otro código antes de que su aplicación comience a monitorear automáticamente varios aspectos críticos del rendimiento. Para las aplicaciones web, el SDK registra aspectos como la primera pintura con contenido, la capacidad de los usuarios para interactuar con su aplicación y más.

También puede configurar seguimientos, métricas y atributos personalizados para medir aspectos específicos de su aplicación. Visite la documentación para obtener más información sobre seguimientos personalizados, métricas y atributos personalizados .

15. Implementa tu aplicación usando Firebase Hosting

Firebase ofrece un servicio de alojamiento para servir sus activos y aplicaciones web. Puede implementar sus archivos en Firebase Hosting mediante Firebase CLI. Antes de implementar, debe especificar en su archivo firebase.json qué archivos locales deben implementarse. Para este laboratorio de código, ya hicimos esto por usted porque este paso fue necesario para servir nuestros archivos durante este laboratorio de código. La configuración de alojamiento se especifica en el atributo de hosting :

base de fuego.json

{
  // If you went through the "Cloud Firestore Security Rules" step.
  "firestore": {
    "rules": "firestore.rules"
  },
  // If you went through the "Storage Security Rules" step.
  "storage": {
    "rules": "storage.rules"
  },
  "hosting": {
    "public": "./public"
  }
}

Esta configuración le dice a la CLI que queremos implementar todos los archivos en el directorio ./public ( "public": "./public" ).

  1. Asegúrese de que su línea de comando esté accediendo al directorio web-start local de su aplicación.
  2. Implemente sus archivos en su proyecto de Firebase ejecutando el siguiente comando:
firebase deploy --except functions
  1. La consola debe mostrar lo siguiente:
=== Deploying to 'friendlychat-1234'...

i  deploying firestore, storage, hosting
i  storage: checking storage.rules for compilation errors...
✔  storage: rules file storage.rules compiled successfully
i  firestore: checking firestore.rules for compilation errors...
✔  firestore: rules file firestore.rules compiled successfully
i  storage: uploading rules storage.rules...
i  firestore: uploading rules firestore.rules...
i  hosting[friendlychat-1234]: beginning deploy...
i  hosting[friendlychat-1234]: found 8 files in ./public
✔  hosting[friendlychat-1234]: file upload complete
✔  storage: released rules storage.rules to firebase.storage/friendlychat-1234.appspot.com
✔  firestore: released rules firestore.rules to cloud.firestore
i  hosting[friendlychat-1234]: finalizing version...
✔  hosting[friendlychat-1234]: version finalized
i  hosting[friendlychat-1234]: releasing new version...
✔  hosting[friendlychat-1234]: release complete

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview
Hosting URL: https://friendlychat-1234.firebaseapp.com
  1. Visite su aplicación web que ahora está completamente alojada en una CDN global mediante Firebase Hosting en dos de sus propios subdominios de Firebase:
  • https://<firebase-projectId>.firebaseapp.com
  • https://<firebase-projectId>.web.app

Como alternativa, puede ejecutar firebase open hosting:site en la línea de comandos.

Visite la documentación para obtener más información sobre cómo funciona Firebase Hosting .

Vaya a la sección Hospedaje de Firebase console de su proyecto para ver información y herramientas de hospedaje útiles, incluido el historial de sus implementaciones, la funcionalidad para revertir a versiones anteriores de su aplicación y el flujo de trabajo para configurar un dominio personalizado.

16. ¡Felicitaciones!

¡Utilizó Firebase para crear una aplicación web de chat en tiempo real!

Lo que hemos cubierto

  • Autenticación de base de fuego
  • Tienda de fuego en la nube
  • SDK de Firebase para almacenamiento en la nube
  • Mensajería en la nube de Firebase
  • Supervisión del rendimiento de Firebase
  • Alojamiento de base de fuego

Próximos pasos

Learn more