Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Laboratorio de código web de Firebase

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

3b1284f5144b54f6.png

Lo que aprenderás

  • Sincroniza datos con Cloud Firestore y Cloud Storage para Firebase.
  • Autentica a tus usuarios mediante Firebase Authentication.
  • Implemente su 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 editor de texto / IDE de su elección, como WebStorm , Atom , Sublime o VS Code
  • El administrador de paquetes npm , que normalmente viene con Node.js
  • Una terminal / consola
  • Un navegador de su elección, como Chrome
  • El código de muestra del laboratorio de código (consulte el siguiente paso del laboratorio de código para saber cómo obtener el código).

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 web-start desde el repositorio clonado. Este directorio de web-start contiene el código de inicio para el laboratorio de códigos, que será una aplicación web de chat completamente funcional.

Crea un proyecto de Firebase

  1. Inicie sesión en Firebase .
  2. En Firebase console, haz clic en Agregar proyecto y, luego, asigna el nombre FriendlyChat a tu proyecto de Firebase. 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 crear utiliza productos de Firebase que están disponibles para aplicaciones web:

  • Firebase Authentication para permitir que sus usuarios inicien sesión en su aplicación fácilmente.
  • Cloud Firestore para guardar datos estructurados en la nube y recibir notificaciones instantáneas cuando los datos cambian.
  • Cloud Storage para Firebase para guardar archivos en la nube.
  • Firebase Hosting para alojar y servir sus activos.
  • Firebase Cloud Messaging para enviar notificaciones push 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 de Firebase.

Agrega una aplicación web de Firebase al proyecto

  1. Haga clic en el icono web 58d6543a156e56f9.png para crear una nueva aplicación web de Firebase.
  2. Registre la aplicación con el sobrenombre de Friendly Chat , luego marque la casilla junto a Configurar Firebase Hosting para esta aplicación . Haga clic en Registrar aplicación .
  3. Haga clic en los pasos restantes. No es necesario que siga las instrucciones ahora; estos serán cubiertos en pasos posteriores de este codelab.

ea9ab0db531a104c.png

Habilite 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, usaremos el método de inicio de sesión de Google .

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

  1. En Firebase console, ubica la sección Compilar 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 y luego haga clic en Guardar .
  4. Establezca el nombre público de su aplicación en Chat amistoso 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 de compilación de la consola de Firebase, haga clic en Firestore Database .
  2. Haz 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 asegura 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 laboratorio de código.

77e4986cbeaf9dee.png

  1. Configura la ubicación donde se almacenan tus 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 Cloud Storage:

  1. En la sección Compilación de Firebase console, haz clic en Almacenamiento .
  2. Si no hay un botón Comenzar , significa que el almacenamiento en la nube ya está habilitado y no es necesario que siga 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, 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 elegiste para tu base de datos de Cloud Firestore. Haga clic en Listo para completar la configuración.

1d7f49ebaddb32fc.png

La interfaz de línea de comandos (CLI) de Firebase te permite usar Firebase Hosting para entregar tu aplicación web de forma local, así como para implementar tu aplicación web en tu 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

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

  1. Asegúrese de que su línea de comando acceda al directorio de 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, preparación, etc.). Sin embargo, para este laboratorio de código, usemos el alias default .

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

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

  1. En una consola del directorio de 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

Estamos usando el emulador de Firebase Hosting para entregar 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 no está funcionando (¡todavía!):

4c23f9475228cef4.png

La aplicación no puede hacer nada en este momento, ¡pero con su ayuda lo hará pronto! Hasta ahora, solo hemos diseñado la interfaz de usuario.

¡Construyamos ahora un chat en tiempo real!

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.

Como usamos Firebase Hosting para servir nuestra aplicación, vamos a importar las URL locales que se encuentran en el archivo index.html (ubicado en su directorio web-start/public/ ). Para este codelab, ya hemos agregado las siguientes líneas al final del archivo index.html , pero puede verificar que estén allí.

index.html

<script src="/__/firebase/8.6.7/firebase-app.js"></script>
<script src="/__/firebase/8.6.7/firebase-auth.js"></script>
<script src="/__/firebase/8.6.7/firebase-storage.js"></script>
<script src="/__/firebase/8.6.7/firebase-messaging.js"></script>
<script src="/__/firebase/8.6.7/firebase-firestore.js"></script>
<script src="/__/firebase/8.6.7/firebase-performance.js"></script>

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

Configurar Firebase

También necesitamos configurar el SDK de Firebase para indicarle qué proyecto de Firebase estamos usando. Como usamos Firebase Hosting, puede importar un script especial que hará esta configuración por usted. Nuevamente, para este laboratorio de código, ya hemos agregado la siguiente línea al final del archivo public/index.html , pero verifique que esté allí.

index.html

<script src="/__/firebase/init.js"></script>

Esta secuencia de comandos contiene la configuración de su proyecto de Firebase según el proyecto de Firebase que especificó anteriormente cuando ejecutó firebase use --add .

Siéntase libre de inspeccionar el archivo init.js para ver cómo se ve la configuración de su proyecto. Para hacer esto, abra http: // localhost: 5000 / __ / firebase / init.js en su navegador. Debería ver algo parecido a lo siguiente:

/__/firebase/init.js

if (typeof firebase === 'undefined') throw new Error('hosting/init-error: Firebase SDK not detected. You must include it before /__/firebase/init.js');
firebase.initializeApp({
  "apiKey": "qwertyuiop_asdfghjklzxcvbnm1234568_90",
  "databaseURL": "https://friendlychat-1234.firebaseio.com",
  "storageBucket": "friendlychat-1234.appspot.com",
  "authDomain": "friendlychat-1234.firebaseapp.com",
  "messagingSenderId": "1234567890",
  "projectId": "friendlychat-1234",
  "appId": "1:1234567890:web:123456abcdef"
});

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 del usuario mediante Firebase Authentication .

Autentica a tus usuarios con el inicio de sesión de Google

En la aplicación, cuando un usuario hace clic en el botón Iniciar sesión con Google , se signIn función de signIn . (¡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 public/scripts/ , abra main.js
  2. Encuentra la función signIn .
  3. Reemplace toda la función con el siguiente código.

main.js

// Signs-in Friendly Chat.
function signIn() {
  // Sign into Firebase using popup auth & Google as the identity provider.
  var provider = new firebase.auth.GoogleAuthProvider();
  firebase.auth().signInWithPopup(provider);
}

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

  1. Regrese al archivo public/scripts/main.js
  2. Busque la función signOut .
  3. Reemplace toda la función con el siguiente código.

main.js

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

Seguimiento del estado de autenticación

Para actualizar nuestra interfaz de usuario en consecuencia, necesitamos una forma de verificar si el usuario ha iniciado sesión o no. 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. Regrese al archivo public/scripts/main.js
  2. Busque la función initFirebaseAuth .
  3. Reemplace toda la función con el siguiente código.

main.js

// Initiate Firebase Auth.
function initFirebaseAuth() {
  // Listen to auth state changes.
  firebase.auth().onAuthStateChanged(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 sesión o cierre sesión). En este punto, 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 que inició sesión

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 firebase.auth().currentUser siempre están disponibles en el objeto firebase.auth().currentUser . Anteriormente, configuramos la función authStateObserver para que se active cuando el usuario authStateObserver para que nuestra interfaz de usuario se actualice en consecuencia. getProfilePicUrl a getProfilePicUrl y getUserName cuando se getUserName .

  1. Regrese al archivo public/scripts/main.js
  2. Busque las funciones getProfilePicUrl y getUserName .
  3. Reemplace ambas funciones con el siguiente código.

main.js

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

// Returns the signed-in user's display name.
function getUserName() {
  return firebase.auth().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 inició sesión.

  1. Regrese al archivo public/scripts/main.js
  2. Busque la función isUserSignedIn .
  3. Reemplace toda la función con el siguiente código.

main.js

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

Prueba de iniciar sesión en la aplicación

  1. Si su aplicación aún 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 con 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 el inicio de sesión de Google como proveedor de autenticación en la consola de Firebase.
  3. Después de iniciar sesión, se debe mostrar su foto de perfil y nombre de usuario: c7401b3d44d0d78b.png

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 del mensaje a su instancia de Cloud Firestore en la colección de messages . El método add() agrega un nuevo documento con un ID generado automáticamente a la colección.

  1. Regrese al archivo public/scripts/main.js
  2. Busque la función saveMessage .
  3. Reemplace toda la función con el siguiente código.

main.js

// Saves a new message to your Cloud Firestore database.
function saveMessage(messageText) {
  // Add a new message entry to the database.
  return firebase.firestore().collection('messages').add({
    name: getUserName(),
    text: messageText,
    profilePicUrl: getProfilePicUrl(),
    timestamp: firebase.firestore.FieldValue.serverTimestamp()
  }).catch(function(error) {
    console.error('Error writing new message to database', error);
  });
}

Prueba de envío de mensajes

  1. Si su aplicación aún 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, todavía no verá los datos en su aplicación web real porque todavía necesitamos implementar la recuperación de datos (la siguiente sección del laboratorio de código).
  3. Puedes ver el mensaje recién agregado en tu Firebase Console. Abre tu consola de Firebase. En la sección Crear , haga clic en Base de datos (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

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 nuevos mensajes.

Agregaremos 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. Regrese al archivo public/scripts/main.js
  2. Busque la función loadMessages .
  3. Reemplace toda la función con el siguiente código.

main.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.
  var query = firebase.firestore()
                  .collection('messages')
                  .orderBy('timestamp', 'desc')
                  .limit(12);
  
  // Start listening to the query.
  query.onSnapshot(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 los mensajes en la base de datos, creamos una consulta en una colección usando la función .collection para especificar en qué colección están los datos que queremos escuchar. En el código anterior, estamos escuchando los cambios dentro del colección de messages , que es donde se almacenan los mensajes de chat. También aplicamos 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 un parámetro: una función de devolución de llamada. La función de devolución de llamada se activará cuando haya cambios en los documentos que coincidan con la consulta. Esto podría ocurrir si un mensaje se elimina, modifica o agrega. Puedes leer más sobre esto en la documentación de Cloud Firestore .

Probar la sincronización de mensajes

  1. Si su aplicación aún 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 (ver más abajo). Siéntete libre de escribir nuevos mensajes; deberían aparecer instantáneamente.
  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ás leyendo documentos de Cloud Firestore en tu aplicación!

2168dec79b573d07.png

Ahora agregaremos una función 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 con nuestra aplicación.

Guardar imágenes en el almacenamiento en la nube

Para este laboratorio de código, ya hemos agregado un botón que activa un cuadro de diálogo de selector de archivos. Después de seleccionar un archivo, se saveImageMessage 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. Sube el archivo de imagen a Cloud Storage en 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 subido en lugar de la imagen de carga temporal.

Ahora agregará la funcionalidad para enviar una imagen:

  1. Regrese al archivo public/scripts/main.js
  2. Busque la función saveImageMessage .
  3. Reemplace toda la función con el siguiente código.

main.js

// Saves a new message containing an image in Firebase.
// This first saves the image in Firebase storage.
function saveImageMessage(file) {
  // 1 - We add a message with a loading icon that will get updated with the shared image.
  firebase.firestore().collection('messages').add({
    name: getUserName(),
    imageUrl: LOADING_IMAGE_URL,
    profilePicUrl: getProfilePicUrl(),
    timestamp: firebase.firestore.FieldValue.serverTimestamp()
  }).then(function(messageRef) {
    // 2 - Upload the image to Cloud Storage.
    var filePath = firebase.auth().currentUser.uid + '/' + messageRef.id + '/' + file.name;
    return firebase.storage().ref(filePath).put(file).then(function(fileSnapshot) {
      // 3 - Generate a public URL for the file.
      return fileSnapshot.ref.getDownloadURL().then((url) => {
        // 4 - Update the chat message placeholder with the image's URL.
        return messageRef.update({
          imageUrl: url,
          storageUri: fileSnapshot.metadata.fullPath
        });
      });
    });
  }).catch(function(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 aún 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 ábralo en su navegador.
  2. Después de iniciar sesión, haga clic en el botón de carga de la imagen 13734cb66773e5a3.png y seleccione un archivo de imagen con el selector de archivos. Si está buscando una imagen, no dude en utilizar 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.

Ahora agregaremos soporte para 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 te permite entregar mensajes y notificaciones de manera confiable y sin costo.

Incluir en la lista blanca el ID de remitente de GCM

En el manifiesto de la aplicación web , debe especificar el gcm_sender_id , que es un valor codificado que indica que FCM está autorizado para enviar mensajes a esta aplicación.

  1. Desde el directorio de web-start , en el directorio public , abra manifest.json .
  2. Agregue el valor de ID del remitente del navegador en el atributo gcm_sender_id exactamente como se muestra a continuación. No cambie el valor de lo que se muestra a continuación.

manifest.json

{
  "name": "Friendly Chat",
  "short_name": "Friendly Chat",
  "start_url": "/index.html",
  "display": "standalone",
  "orientation": "portrait",
  "gcm_sender_id": "103953800507"
}

Agregar el trabajador del servicio de FCM

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

  1. Desde el directorio de web-start , en el directorio public , cree un nuevo archivo llamado firebase-messaging-sw.js .
  2. Agregue el siguiente contenido a ese nuevo archivo.

firebase-messaging-sw.js

importScripts('/__/firebase/6.0.4/firebase-app.js');
importScripts('/__/firebase/6.0.4/firebase-messaging.js');
importScripts('/__/firebase/init.js');

firebase.messaging();

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

Obtén tokens de dispositivo de FCM

Cuando se hayan habilitado las notificaciones en un dispositivo o navegador, se le entregará 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 saveMessagingDeviceToken , llamamos a la función saveMessagingDeviceToken . Ahí es donde obtendremos el token de dispositivo FCM del navegador y lo guardaremos en Cloud Firestore.

  1. Regrese al archivo public/scripts/main.js
  2. Busque la función saveMessagingDeviceToken .
  3. Reemplace toda la función con el siguiente código.

main.js

// Saves the messaging device token to the datastore.
function saveMessagingDeviceToken() {
  firebase.messaging().getToken().then(function(currentToken) {
    if (currentToken) {
      console.log('Got FCM device token:', currentToken);
      // Saving the Device Token to the datastore.
      firebase.firestore().collection('fcmTokens').doc(currentToken)
          .set({uid: firebase.auth().currentUser.uid});
    } else {
      // Need to request permissions to show notifications.
      requestNotificationsPermissions();
    }
  }).catch(function(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 código).

Solicitar permisos para mostrar notificaciones

Cuando el usuario aún no le ha otorgado permiso a su aplicación para mostrar notificaciones, no se le dará 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. Regrese al archivo public/scripts/main.js
  2. Busque la función requestNotificationsPermissions .
  3. Reemplace toda la función con el siguiente código.

main.js

// Requests permission to show notifications.
function requestNotificationsPermissions() {
  console.log('Requesting notifications permission...');
  firebase.messaging().requestPermission().then(function() {
    // Notification permission granted.
    saveMessagingDeviceToken();
  }).catch(function(error) {
    console.error('Unable to get permission to notify.', error);
  });
}

Obtén el token de tu dispositivo

  1. Si su aplicación aún 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 permisos de notificaciones: bd3454e6dbfb6723.png
  3. Haz 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 código.

Envía una notificación a tu dispositivo

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

  1. Además del token del dispositivo, también necesitará la clave del servidor de su aplicación Firebase. Para obtener esta clave, vaya a Firebase Console> Configuración del proyecto> Mensajería en la nube , luego copie la clave del servidor .

Para enviar una notificación, deberá enviar la siguiente solicitud HTTP:

POST /fcm/send HTTP/1.1
Host: fcm.googleapis.com
Content-Type: application/json
Authorization: key=YOUR_SERVER_KEY

{
  "notification": {
    "title": "New chat message!",
    "body": "There is a new message in FriendlyChat",
    "icon": "/images/profile_placeholder.png",
    "click_action": "http://localhost:5000"
  },
  "to":"YOUR_DEVICE_TOKEN"
}
  1. En la línea de comando, ejecute el siguiente comando cURL .
curl -H "Content-Type: application/json" \
     -H "Authorization: key=YOUR_SERVER_KEY" \
     -d '{
           "notification": {
             "title": "New chat message!",
             "body": "There is a new message in FriendlyChat",
             "icon": "/images/profile_placeholder.png",
             "click_action": "http://localhost:5000"
           },
           "to": "YOUR_DEVICE_TOKEN"
         }' \
     https://fcm.googleapis.com/fcm/send

Tenga en cuenta que la notificación solo aparecerá si la aplicación FriendlyChat está en segundo plano. Debe navegar fuera o mostrar otra pestaña para que se muestre la notificación. Cuando la aplicación está en primer plano, hay una forma de captar los mensajes enviados por FCM .

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

de79e8638a45864c.png

Ver las reglas de seguridad de la base de datos

Cloud Firestore 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 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 , puedes 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 cosas usando las siguientes reglas:

firestore.rules

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 tu base de datos, ya sea en Firebase console o desde un archivo de reglas local implementado con Firebase CLI.

Para actualizar las reglas de seguridad en Firebase console:

  1. Vaya a la sección Base de datos en el 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 de 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 de web-start , abra firebase.json .
  4. Agregue el atributo firestore.rules apunta a firestore.rules , como se muestra a continuación. (El atributo de hosting ya debería estar en el archivo).

firebase.json

{
  // Add this!
  "firestore": {
    "rules": "firestore.rules"
  },
  "hosting": {
    "public": "./public"
  }
}
  1. Implemente las reglas de seguridad con 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

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 a los usuarios autenticados usar Cloud Storage. En Firebase console , en la pestaña Reglas de la sección Almacenamiento , puedes ver y modificar reglas. Debería ver la regla predeterminada que permite a cualquier usuario que haya iniciado sesión leer y escribir 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 cualquiera lea desde Cloud Storage
  • Asegúrese de que los archivos cargados 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 las reglas de seguridad de almacenamiento: ya sea en Firebase console o desde un archivo de reglas local implementado con Firebase CLI.

Para actualizar las reglas de seguridad en Firebase console:

  1. Vaya a la sección Almacenamiento del 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 de 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 de web-start , abra firebase.json .
  4. Agregue el atributo storage.rules apunta al archivo storage.rules , como se muestra a continuación. (El atributo de hosting y database ya debería estar en el archivo).

firebase.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 con 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

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 te ayuda a comprender dónde y cuándo se puede mejorar el rendimiento de tu aplicación para que puedas 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 desde las URL de alojamiento . Consulte la documentación para ver otros métodos para habilitar el SDK.

Rastreos automáticos

Dado que incluimos firebase-performance.js e init.js en un paso anterior del laboratorio de código, solo necesitamos agregar una línea para indicarle a Performance Monitoring que recopile automáticamente las métricas de carga de página y solicitud de red cuando los usuarios visiten su sitio implementado.

  1. En public/scripts/main.js , agregue la siguiente línea debajo del TODO existente para inicializar Performance Monitoring.

main.js

// TODO: Enable Firebase Performance Monitoring.
firebase.performance();

Medir el retardo de la primera entrada (opcional)

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

La primera demora de entrada comienza cuando el usuario interactúa por primera vez con un elemento de 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 de script en la siguiente línea.

index.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 polyfill de primer retardo de entrada, eche 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 Performance Monitoring 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 y métricas personalizados y atributos personalizados .

Firebase ofrece un servicio de alojamiento para sus activos y aplicaciones web. Puedes implementar tus archivos en Firebase Hosting usando Firebase CLI. Antes de la implementación, debe especificar en su archivo firebase.json qué archivos locales deben implementarse. Para este codelab, ya lo hemos hecho por usted porque este paso fue necesario para entregar nuestros archivos durante este codelab. La configuración de alojamiento se especifica en el atributo de hosting :

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

Estas configuraciones le dicen 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 acceda al directorio de web-start local de su aplicación.
  2. Deploy your files to your Firebase project by running the following command:
firebase deploy --except functions
  1. The console should display the following:
=== 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. Visit your web app that's now fully hosted using Firebase Hosting at two of your very own Firebase subdomains:
  • https://<firebase-projectId>.firebaseapp.com
  • https://<firebase-projectId>.web.app .

Alternatively, you can run firebase open hosting:site in the command line.

Visit the documentation to learn more about how Firebase Hosting works .

Go to your project's Firebase console Hosting section to view useful hosting information and tools, including the history of your deploys, the functionality to roll back to previous versions of your app, and the workflow to set up a custom domain.

You've used Firebase to build a real-time chat web application!

What we've covered

  • Firebase Authentication
  • Cloud Firestore
  • Firebase SDK for Cloud Storage
  • Firebase Cloud Messaging
  • Firebase Performance Monitoring
  • Firebase Hosting

Próximos pasos

Learn more