Codelab web di Firebase

1. Panoramica

In questo codelab imparerai come utilizzare Firebase per creare facilmente applicazioni Web implementando e distribuendo un client di chat utilizzando prodotti e servizi Firebase.

3b1284f5144b54f6.png

Cosa imparerai

  • Sincronizza i dati utilizzando Cloud Firestore e Cloud Storage for Firebase.
  • Autentica i tuoi utenti utilizzando l'autenticazione Firebase.
  • Distribuisci la tua app web su Firebase Hosting.
  • Invia notifiche con Firebase Cloud Messaging.
  • Raccogli i dati sulle prestazioni della tua app web.

Di cosa avrai bisogno

  • L'IDE/editor di testo di tua scelta, come WebStorm , Atom , Sublime o VS Code
  • Il gestore di pacchetti npm , che in genere viene fornito con Node.js
  • Un terminale/console
  • Un browser di tua scelta, come Chrome
  • Il codice di esempio del codelab (vedere il passaggio successivo del codelab per sapere come ottenere il codice).

2. Ottieni il codice di esempio

Clona il repository GitHub del codelab dalla riga di comando:

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

In alternativa, se non hai git installato, puoi scaricare il repository come file ZIP .

Importa l'app iniziale

Usando il tuo IDE, apri o importa la 📁 directory web-start dal repository clonato. Questa 📁 directory web-start contiene il codice iniziale per il codelab, che sarà un'app web di chat completamente funzionante.

3. Crea e imposta un progetto Firebase

Crea un progetto Firebase

  1. Accedi a Firebase .
  2. Nella console Firebase, fai clic su Aggiungi progetto , quindi assegna un nome al tuo progetto Firebase FriendlyChat . Ricorda l'ID progetto per il tuo progetto Firebase.
  3. Deseleziona Abilita Google Analytics per questo progetto
  4. Fare clic su Crea progetto .

L'applicazione che costruiremo utilizza i prodotti Firebase disponibili per le app Web:

  • Autenticazione Firebase per consentire facilmente agli utenti di accedere alla tua app.
  • Cloud Firestore per salvare i dati strutturati sul cloud e ricevere notifiche istantanee quando i dati cambiano.
  • Cloud Storage per Firebase per salvare i file nel cloud.
  • Firebase Hosting per ospitare e servire le tue risorse.
  • Firebase Cloud Messaging per inviare notifiche push e visualizzare le notifiche popup del browser.
  • Firebase Performance Monitoring per raccogliere dati sulle prestazioni degli utenti per la tua app.

Alcuni di questi prodotti richiedono una configurazione speciale o devono essere abilitati utilizzando la console Firebase.

Aggiungi un'app Web Firebase al progetto

  1. Fare clic sull'icona web 58d6543a156e56f9.png per creare una nuova app Web Firebase.
  2. Registra l'app con il nickname Friendly Chat , quindi seleziona la casella accanto a Configura anche Firebase Hosting per questa app . Fai clic su Registra app .
  3. Nel passaggio successivo, vedrai un oggetto di configurazione. Copia solo l'oggetto JS (non l'HTML circostante) in firebase-config.js

Registra lo screenshot dell'app web

Abilita l'accesso a Google per l'autenticazione Firebase

Per consentire agli utenti di accedere all'app Web con i propri account Google, utilizzeremo il metodo di accesso di Google .

Dovrai abilitare l'accesso a Google :

  1. Nella console Firebase, individua la sezione Build nel pannello di sinistra.
  2. Fai clic su Autenticazione , quindi fai clic sulla scheda Metodo di accesso (o fai clic qui per andare direttamente lì).
  3. Attiva il provider di accesso a Google , quindi fai clic su Salva .
  4. Imposta il nome pubblico della tua app su Friendly Chat e scegli un'e -mail di supporto del progetto dal menu a discesa.
  5. Configura la tua schermata di consenso OAuth in Google Cloud Console e aggiungi un logo:

d89fb3873b5d36ae.png

Abilita Cloud Firestore

L'app Web utilizza Cloud Firestore per salvare i messaggi di chat e ricevere nuovi messaggi di chat.

Dovrai abilitare Cloud Firestore:

  1. Nella sezione Build della console Firebase, fai clic su Firestore Database .
  2. Fai clic su Crea database nel riquadro Cloud Firestore.

729991a081e7cd5.png

  1. Selezionare l'opzione Avvia in modalità test , quindi fare clic su Avanti dopo aver letto l'esclusione di responsabilità sulle regole di sicurezza.

La modalità di test garantisce la possibilità di scrivere liberamente nel database durante lo sviluppo. Renderemo il nostro database più sicuro più avanti in questo codelab.

77e4986cbeaf9dee.png

  1. Imposta la posizione in cui vengono archiviati i dati di Cloud Firestore. Puoi lasciarlo come predefinito o scegliere una regione vicina a te. Fai clic su Fine per eseguire il provisioning di Firestore.

9f2bb0d4e7ca49c7.png

Abilita l'archiviazione cloud

L'app Web utilizza Cloud Storage per Firebase per archiviare, caricare e condividere immagini.

Dovrai abilitare Cloud Storage:

  1. Nella sezione Build della console Firebase, fai clic su Archiviazione .
  2. Se non è presente il pulsante Inizia , significa che l'archiviazione cloud è già abilitata e non è necessario seguire i passaggi seguenti.
  3. Fai clic su Inizia .
  4. Leggi il disclaimer sulle regole di sicurezza per il tuo progetto Firebase, quindi fai clic su Avanti .

Con le regole di sicurezza predefinite, qualsiasi utente autenticato può scrivere qualsiasi cosa su Cloud Storage. Renderemo il nostro spazio di archiviazione più sicuro più avanti in questo codelab.

62f1afdcd1260127.png

  1. La posizione di Cloud Storage è preselezionata con la stessa regione che hai scelto per il tuo database Cloud Firestore. Fare clic su Fine per completare la configurazione.

1d7f49ebaddb32fc.png

4. Installa l'interfaccia della riga di comando di Firebase

L'interfaccia della riga di comando (CLI) di Firebase ti consente di utilizzare Firebase Hosting per servire la tua app Web localmente, nonché per distribuire la tua app Web nel tuo progetto Firebase.

  1. Installa la CLI eseguendo il seguente comando npm:
npm -g install firebase-tools
  1. Verificare che la CLI sia stata installata correttamente eseguendo il seguente comando:
firebase --version

Assicurati che la versione dell'interfaccia a riga di comando di Firebase sia v4.1.0 o successiva.

  1. Autorizza l'interfaccia a riga di comando di Firebase eseguendo il seguente comando:
firebase login

Abbiamo impostato il modello di app Web per estrarre la configurazione della tua app per Firebase Hosting dalla directory locale della tua app (il repository che hai clonato in precedenza nel codelab). Ma per eseguire il pull della configurazione, dobbiamo associare la tua app al tuo progetto Firebase.

  1. Assicurati che la riga di comando acceda alla directory web-start locale dell'app.
  2. Associa la tua app al tuo progetto Firebase eseguendo il seguente comando:
firebase use --add
  1. Quando richiesto, seleziona il tuo ID progetto , quindi assegna un alias al tuo progetto Firebase.

Un alias è utile se hai più ambienti (produzione, staging, ecc.). Tuttavia, per questo codelab, usiamo semplicemente l'alias di default .

  1. Segui le istruzioni rimanenti sulla riga di comando.

5. Eseguire l'app iniziale in locale

Ora che hai importato e configurato il tuo progetto, sei pronto per eseguire l'app Web per la prima volta.

  1. In una console dalla directory web-start , esegui il seguente comando Firebase CLI:
firebase serve --only hosting
  1. La riga di comando dovrebbe visualizzare la seguente risposta:
✔  hosting: Local server: http://localhost:5000

Stiamo utilizzando l'emulatore Firebase Hosting per servire la nostra app localmente. L'app Web dovrebbe ora essere disponibile da http://localhost:5000 . Vengono serviti tutti i file che si trovano nella sottodirectory public .

  1. Usando il tuo browser, apri la tua app su http://localhost:5000 .

Dovresti vedere l'interfaccia utente della tua app FriendlyChat, che non funziona (ancora!):

4c23f9475228cef4.png

L'app non può fare nulla in questo momento, ma con il tuo aiuto lo farà presto! Finora abbiamo preparato solo l'interfaccia utente.

Costruiamo ora una chat in tempo reale!

6. Importa e configura Firebase

Importa l'SDK di Firebase

Dobbiamo importare l'SDK Firebase nell'app. Esistono diversi modi per farlo, come descritto nella nostra documentazione . Ad esempio, puoi importare la libreria dal nostro CDN. Oppure puoi installarlo localmente usando npm, quindi impacchettarlo nella tua app se stai usando Browserify.

Otterremo l'SDK Firebase da npm e utilizzeremo Webpack per raggruppare il nostro codice. Lo stiamo facendo in modo che Webpack possa rimuovere qualsiasi codice non necessario, mantenendo piccole le dimensioni del nostro pacchetto JS per assicurarci che la nostra app si carichi il più rapidamente possibile. Per questo codelab, abbiamo già creato un file web-start/package.json che include l'SDK Firebase come dipendenza, oltre a importare le funzioni necessarie nella parte superiore di web-start/src/index.js .

pacchetto.json

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

index.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 questo codelab, utilizzeremo Firebase Authentication, Cloud Firestore, Cloud Storage, Cloud Messaging e Performance Monitoring, quindi importeremo tutte le loro librerie. Nelle tue app future, assicurati di importare solo le parti di Firebase di cui hai bisogno, per ridurre il tempo di caricamento della tua app.

Installa l'SDK Firebase e avvia la build del Webpack

Dobbiamo eseguire alcuni comandi per avviare la build della nostra app.

  1. Apri una nuova finestra di terminale
  2. Assicurati di essere nella directory web-start
  3. Esegui npm install per scaricare l'SDK di Firebase
  4. Esegui npm run start per avviare Webpack. Webpack ora ricostruirà continuamente il nostro codice sorgente per il resto del codelab.

Configura Firebase

Dobbiamo anche configurare l'SDK Firebase per dirgli quale progetto Firebase stiamo utilizzando.

  1. Vai alle impostazioni del tuo progetto nella console Firebase
  2. Nella scheda "Le tue app", seleziona il nickname dell'app per la quale hai bisogno di un oggetto di configurazione.
  3. Seleziona "Config" dal riquadro dello snippet dell'SDK di Firebase.
  4. Copia lo snippet dell'oggetto di configurazione, quindi aggiungilo 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",
};

Ora vai in fondo a web-start/src/index.js e inizializza Firebase:

index.js

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

7. Configurare l'accesso utente

L'SDK Firebase ora dovrebbe essere pronto per l'uso poiché è importato e inizializzato in index.js . Ora implementeremo l'accesso dell'utente utilizzando Firebase Authentication .

Autentica i tuoi utenti con Google Sign-In

Nell'app, quando un utente fa clic sul pulsante Accedi con Google , viene attivata la funzione signIn . (L'abbiamo già configurato per te!) Per questo codelab, vogliamo autorizzare Firebase a utilizzare Google come provider di identità. Useremo un popup, ma sono disponibili molti altri metodi da Firebase.

  1. Nella directory web-start , nella sottodirectory src/ , apri index.js .
  2. Trova la funzione signIn .
  3. Sostituire l'intera funzione con il seguente codice.

index.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 funzione signOut viene attivata quando l'utente fa clic sul pulsante Esci .

  1. Torna al file src/index.js .
  2. Trova la funzione signOutUser .
  3. Sostituire l'intera funzione con il seguente codice.

index.js

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

Tieni traccia dello stato di autenticazione

Per aggiornare la nostra interfaccia utente di conseguenza, abbiamo bisogno di un modo per verificare se l'utente è connesso o disconnesso. Con Firebase Authentication, puoi registrare un osservatore sullo stato di autenticazione che verrà attivato ogni volta che lo stato di autenticazione cambia.

  1. Torna al file src/index.js .
  2. Trova la funzione initFirebaseAuth .
  3. Sostituire l'intera funzione con il seguente codice.

index.js

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

Il codice precedente registra la funzione authStateObserver come osservatore dello stato di autenticazione. Si attiverà ogni volta che cambia lo stato di autenticazione (quando l'utente accede o si disconnette). È a questo punto che aggiorneremo l'interfaccia utente per visualizzare o nascondere il pulsante di accesso, il pulsante di disconnessione, l'immagine del profilo dell'utente connesso e così via. Tutte queste parti dell'interfaccia utente sono già state implementate.

Visualizza le informazioni dell'utente che ha effettuato l'accesso

Vogliamo visualizzare l'immagine del profilo e il nome utente dell'utente connesso nella barra superiore della nostra app. In Firebase, i dati dell'utente che ha eseguito l'accesso sono sempre disponibili nell'oggetto currentUser . In precedenza, abbiamo impostato la funzione authStateObserver in modo che si attivi quando l'utente accede in modo che la nostra interfaccia utente si aggiorni di conseguenza. Chiamerà getProfilePicUrl e getUserName quando attivato.

  1. Torna al file src/index.js .
  2. Trova le funzioni getProfilePicUrl e getUserName .
  3. Sostituire entrambe le funzioni con il codice seguente.

index.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;
}

Visualizziamo un messaggio di errore se l'utente tenta di inviare messaggi quando l'utente non è connesso. (Puoi provare, però!) Quindi, dobbiamo rilevare se l'utente è effettivamente connesso.

  1. Torna al file src/index.js .
  2. Trova la funzione isUserSignedIn .
  3. Sostituire l'intera funzione con il seguente codice.

index.js

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

Verifica l'accesso all'app

  1. Se la tua app viene ancora pubblicata, aggiorna l'app nel browser. In caso contrario, esegui firebase serve --only hosting sulla riga di comando per iniziare a servire l'app da http://localhost:5000 , quindi aprila nel browser.
  2. Accedi all'app utilizzando il pulsante di accesso e il tuo account Google. Se viene visualizzato un messaggio di errore che indica auth/operation-not-allowed , verifica di aver abilitato Accedi con Google come provider di autenticazione nella console Firebase.
  3. Dopo l'accesso, la tua immagine del profilo e il tuo nome utente dovrebbero essere visualizzati: c7401b3d44d0d78b.png

8. Scrivi messaggi a Cloud Firestore

In questa sezione, scriveremo alcuni dati in Cloud Firestore in modo da poter popolare l'interfaccia utente dell'app. Questa operazione può essere eseguita manualmente con la console Firebase , ma lo faremo nell'app stessa per dimostrare una scrittura di base di Cloud Firestore.

Modello dati

I dati di Cloud Firestore sono suddivisi in raccolte, documenti, campi e sottoraccolte. Memorizzeremo ogni messaggio della chat come documento in una raccolta di primo livello chiamata messages .

688d7bc5fb662b57.png

Aggiungi messaggi a Cloud Firestore

Per archiviare i messaggi di chat scritti dagli utenti, utilizzeremo Cloud Firestore .

In questa sezione, aggiungerai la funzionalità per consentire agli utenti di scrivere nuovi messaggi nel tuo database. Un utente che fa clic sul pulsante INVIA attiverà lo snippet di codice riportato di seguito. Aggiunge un oggetto messaggio con i contenuti dei campi del messaggio alla tua istanza Cloud Firestore nella raccolta messages . Il metodo add() aggiunge alla raccolta un nuovo documento con un ID generato automaticamente.

  1. Torna al file src/index.js .
  2. Trova la funzione saveMessage .
  3. Sostituire l'intera funzione con il seguente codice.

index.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);
  }
}

Testare l'invio di messaggi

  1. Se la tua app viene ancora pubblicata, aggiorna l'app nel browser. In caso contrario, esegui firebase serve --only hosting sulla riga di comando per iniziare a servire l'app da http://localhost:5000 , quindi aprila nel browser.
  2. Dopo aver effettuato l'accesso, inserisci un messaggio come "Ciao!", quindi fai clic su INVIA . Questo scriverà il messaggio in Cloud Firestore. Tuttavia, non vedrai ancora i dati nella tua app Web effettiva perché dobbiamo ancora implementare il recupero dei dati (la sezione successiva del codelab).
  3. Puoi vedere il messaggio appena aggiunto nella tua console Firebase. Apri la tua console Firebase. Nella sezione Crea , fai clic su Firestore Database (o fai clic qui e seleziona il tuo progetto) e dovresti vedere la raccolta di messaggi con il tuo messaggio appena aggiunto:

6812efe7da395692.png

9. Leggi i messaggi

Sincronizza i messaggi

Per leggere i messaggi nell'app, dovremo aggiungere listener che si attivano quando i dati cambiano e quindi creare un elemento dell'interfaccia utente che mostri i nuovi messaggi.

Aggiungeremo il codice che ascolta i nuovi messaggi aggiunti dall'app. In questo codice, registreremo il listener che ascolta le modifiche apportate ai dati. Visualizzeremo solo gli ultimi 12 messaggi della chat per evitare di visualizzare una cronologia molto lunga al momento del caricamento.

  1. Torna al file src/index.js .
  2. Trova la funzione loadMessages .
  3. Sostituire l'intera funzione con il seguente codice.

index.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);
      }
    });
  });
}

Per ascoltare i messaggi nel database, creiamo una query su una raccolta utilizzando la funzione collection per specificare in quale raccolta si trovano i dati che vogliamo ascoltare. Nel codice sopra, ascoltiamo le modifiche all'interno dei messages raccolta, che è dove vengono archiviati i messaggi di chat. Stiamo anche applicando un limite ascoltando solo gli ultimi 12 messaggi usando .limit(12) e ordinando i messaggi per data usando orderBy('timestamp', 'desc') per ottenere i 12 messaggi più recenti.

La funzione onSnapshot accetta una query come primo parametro e una funzione di callback come secondo. La funzione di callback verrà attivata quando ci sono modifiche ai documenti che corrispondono alla query. Questo potrebbe accadere se un messaggio viene eliminato, modificato o aggiunto. Puoi leggere ulteriori informazioni in merito nella documentazione di Cloud Firestore .

Testare la sincronizzazione dei messaggi

  1. Se la tua app viene ancora pubblicata, aggiorna l'app nel browser. In caso contrario, esegui firebase serve --only hosting sulla riga di comando per iniziare a servire l'app da http://localhost:5000 , quindi aprila nel browser.
  2. I messaggi che hai creato in precedenza nel database dovrebbero essere visualizzati nell'interfaccia utente di FriendlyChat (vedi sotto). Sentiti libero di scrivere nuovi messaggi; dovrebbero apparire all'istante.
  3. (Facoltativo) Puoi provare a eliminare, modificare o aggiungere manualmente nuovi messaggi direttamente nella sezione Database della console Firebase; eventuali modifiche dovrebbero riflettersi nell'interfaccia utente.

Congratulazioni! Stai leggendo i documenti di Cloud Firestore nella tua app!

2168dec79b573d07.png

10. Invia immagini

Ora aggiungeremo una funzione che condivide le immagini.

Mentre Cloud Firestore è utile per l'archiviazione di dati strutturati, Cloud Storage è più adatto per l'archiviazione di file. Cloud Storage for Firebase è un servizio di archiviazione di file/blob e lo utilizzeremo per archiviare tutte le immagini che un utente condivide utilizzando la nostra app.

Salva le immagini su Cloud Storage

Per questo codelab, abbiamo già aggiunto per te un pulsante che attiva una finestra di selezione file. Dopo aver selezionato un file, viene chiamata la funzione saveImageMessage e puoi ottenere un riferimento al file selezionato. La funzione saveImageMessage realizza quanto segue:

  1. Crea un messaggio di chat "segnaposto" nel feed della chat, in modo che gli utenti vedano un'animazione "Caricamento in corso" mentre carichiamo l'immagine.
  2. Carica il file immagine in Cloud Storage in questo percorso: /<uid>/<messageId>/<file_name>
  3. Genera un URL leggibile pubblicamente per il file di immagine.
  4. Aggiorna il messaggio di chat con l'URL del file di immagine appena caricato al posto dell'immagine di caricamento temporanea.

Ora aggiungerai la funzionalità per inviare un'immagine:

  1. Torna al file src/index.js .
  2. Trova la funzione saveImageMessage .
  3. Sostituire l'intera funzione con il seguente codice.

index.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);
  }
}

Prova l'invio di immagini

  1. Se la tua app viene ancora pubblicata, aggiorna l'app nel browser. In caso contrario, esegui firebase serve --only hosting sulla riga di comando per iniziare a servire l'app da http://localhost:5000 , quindi aprila nel browser.
  2. Dopo aver effettuato l'accesso, fai clic sul pulsante di caricamento dell'immagine 13734cb66773e5a3.png e selezionare un file immagine utilizzando il selettore di file. Se stai cercando un'immagine, sentiti libero di usare questa bella immagine di una tazza di caffè .
  3. Dovrebbe apparire un nuovo messaggio nell'interfaccia utente dell'app con l'immagine selezionata: 3b1284f5144b54f6.png

Se provi ad aggiungere un'immagine mentre non hai effettuato l'accesso, dovresti vedere una notifica di Toast che ti dice che devi accedere per aggiungere immagini.

11. Mostra notifiche

Ora aggiungeremo il supporto per le notifiche del browser. L'app avviserà gli utenti quando vengono pubblicati nuovi messaggi nella chat. Firebase Cloud Messaging (FCM) è una soluzione di messaggistica multipiattaforma che ti consente di inviare in modo affidabile messaggi e notifiche senza alcun costo.

Aggiungi il lavoratore di servizio FCM

L'app Web necessita di un service worker che riceverà e visualizzerà le notifiche Web.

  1. Dalla directory web-start , nella directory src , apri firebase-messaging-sw.js .
  2. Aggiungi il seguente contenuto a quel file.

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');

L'addetto all'assistenza deve semplicemente caricare e inizializzare l'SDK di Firebase Cloud Messaging, che si occuperà della visualizzazione delle notifiche.

Ottieni i token del dispositivo FCM

Quando le notifiche sono state abilitate su un dispositivo o un browser, ti verrà assegnato un token del dispositivo . Questo token del dispositivo è ciò che utilizziamo per inviare una notifica a un particolare dispositivo o a un particolare browser.

Quando l'utente accede, chiamiamo la funzione saveMessagingDeviceToken . È qui che otterremo il token del dispositivo FCM dal browser e lo salveremo in Cloud Firestore.

  1. Torna al file src/index.js .
  2. Trova la funzione saveMessagingDeviceToken .
  3. Sostituire l'intera funzione con il seguente codice.

index.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);
  };
}

Tuttavia, questo codice inizialmente non funzionerà. Affinché la tua app sia in grado di recuperare il token del dispositivo, l'utente deve concedere all'app l'autorizzazione a mostrare le notifiche (passaggio successivo del codelab).

Richiedi le autorizzazioni per mostrare le notifiche

Se l'utente non ha ancora concesso all'app l'autorizzazione a mostrare le notifiche, non ti verrà fornito un token del dispositivo. In questo caso, chiamiamo il metodo firebase.messaging().requestPermission() , che visualizzerà una finestra di dialogo del browser che richiede questa autorizzazione ( nei browser supportati ).

8b9d0c66dc36153d.png

  1. Torna al file src/index.js .
  2. Trova la funzione requestNotificationsPermissions .
  3. Sostituire l'intera funzione con il seguente codice.

index.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.');
  }
}

Ottieni il token del tuo dispositivo

  1. Se la tua app viene ancora pubblicata, aggiorna l'app nel browser. In caso contrario, esegui firebase serve --only hosting sulla riga di comando per iniziare a servire l'app da http://localhost:5000 , quindi aprila nel browser.
  2. Dopo l'accesso, dovrebbe essere visualizzata la finestra di dialogo di autorizzazione delle notifiche: bd3454e6dbfb6723.png
  3. Fai clic su Consenti .
  4. Apri la console JavaScript del tuo browser. Dovresti visualizzare il seguente messaggio: Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
  5. Copia il token del tuo dispositivo. Ti servirà per la fase successiva del codelab.

Invia una notifica al tuo dispositivo

Ora che hai il token del tuo dispositivo, puoi inviare una notifica.

  1. Apri la scheda Cloud Messaging della console Firebase .
  2. Fai clic su "Nuova notifica"
  3. Immettere un titolo e un testo per la notifica.
  4. Sul lato destro dello schermo, fai clic su "invia un messaggio di prova"
  5. Inserisci il token del dispositivo che hai copiato dalla console JavaScript del tuo browser, quindi fai clic sul segno più ("+").
  6. Fai clic su "prova"

Se la tua app è in primo piano, vedrai la notifica nella console JavaScript.

Se la tua app è in background, dovrebbe apparire una notifica nel tuo browser, come in questo esempio:

de79e8638a45864c.png

12. Regole di sicurezza di Cloud Firestore

Visualizza le regole di sicurezza del database

Cloud Firestore utilizza un linguaggio di regole specifico per definire i diritti di accesso, la sicurezza e le convalide dei dati.

Durante la configurazione del progetto Firebase all'inizio di questo codelab, abbiamo scelto di utilizzare le regole di sicurezza predefinite "Modalità test" in modo da non limitare l'accesso al datastore. Nella console di Firebase , nella scheda Regole della sezione Database , puoi visualizzare e modificare queste regole.

In questo momento, dovresti vedere le regole predefinite, che non limitano l'accesso al datastore. Ciò significa che qualsiasi utente può leggere e scrivere su qualsiasi raccolta nel tuo datastore.

rules_version = '2';

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

Aggiorneremo le regole per limitare le cose utilizzando le seguenti regole:

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;
    }
  }
}

Aggiorna le regole di sicurezza del database

Esistono due modi per modificare le regole di sicurezza del database, nella console di Firebase o da un file di regole locale distribuito utilizzando l'interfaccia a riga di comando di Firebase.

Per aggiornare le regole di sicurezza nella console Firebase:

  1. Vai alla sezione Database dal pannello di sinistra, quindi fai clic sulla scheda Regole .
  2. Sostituisci le regole predefinite che sono già nella console con le regole mostrate sopra.
  3. Fai clic su Pubblica .

Per aggiornare le regole di sicurezza da un file locale:

  1. Dalla directory web-start , apri firestore.rules .
  2. Sostituisci le regole predefinite che sono già nel file con le regole mostrate sopra.
  3. Dalla directory web-start , apri firebase.json .
  4. Aggiungi l'attributo firestore.rules che punta a firestore.rules , come mostrato di seguito. (L'attributo hosting dovrebbe essere già nel file.)

firebase.json

{
  // Add this!
  "firestore": {
    "rules": "firestore.rules"
  },
  "hosting": {
    "public": "./public"
  }
}
  1. Distribuisci le regole di sicurezza utilizzando l'interfaccia a riga di comando di Firebase eseguendo il seguente comando:
firebase deploy --only firestore
  1. La riga di comando dovrebbe visualizzare la seguente risposta:
=== 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. Regole di sicurezza di Cloud Storage

Visualizza le regole di sicurezza di Cloud Storage

Cloud Storage for Firebase utilizza un linguaggio di regole specifico per definire i diritti di accesso, la sicurezza e le convalide dei dati.

Durante la configurazione del progetto Firebase all'inizio di questo codelab, abbiamo scelto di utilizzare la regola di sicurezza predefinita di Cloud Storage che consente solo agli utenti autenticati di utilizzare Cloud Storage. Nella console di Firebase , nella scheda Regole della sezione Archiviazione , puoi visualizzare e modificare le regole. Dovresti vedere la regola predefinita che consente a qualsiasi utente che ha eseguito l'accesso di leggere e scrivere qualsiasi file nel tuo bucket di archiviazione.

rules_version = '2';

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

Aggiorneremo le regole per fare quanto segue:

  • Consenti a ciascun utente di scrivere solo nelle proprie cartelle specifiche
  • Consenti a chiunque di leggere da Cloud Storage
  • Assicurati che i file caricati siano immagini
  • Limita la dimensione delle immagini che possono essere caricate a un massimo di 5 MB

Questo può essere implementato utilizzando le seguenti regole:

storage.rules

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;
    }
  }
}

Aggiorna le regole di sicurezza di Cloud Storage

Esistono due modi per modificare le regole di sicurezza dello storage: nella console di Firebase o da un file di regole locale distribuito utilizzando l'interfaccia a riga di comando di Firebase.

Per aggiornare le regole di sicurezza nella console Firebase:

  1. Vai alla sezione Archiviazione dal pannello di sinistra, quindi fai clic sulla scheda Regole .
  2. Sostituisci la regola predefinita che è già nella console con le regole mostrate sopra.
  3. Fai clic su Pubblica .

Per aggiornare le regole di sicurezza da un file locale:

  1. Dalla directory web-start , apri storage.rules .
  2. Sostituisci le regole predefinite che sono già nel file con le regole mostrate sopra.
  3. Dalla directory web-start , apri firebase.json .
  4. Aggiungi l'attributo storage.rules che punta al file storage.rules , come mostrato di seguito. (L'attributo hosting e database dovrebbe essere già nel file.)

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. Distribuisci le regole di sicurezza utilizzando l'interfaccia a riga di comando di Firebase eseguendo il seguente comando:
firebase deploy --only storage
  1. La riga di comando dovrebbe visualizzare la seguente risposta:
=== 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. Raccogliere i dati sulle prestazioni

Puoi utilizzare l'SDK Performance Monitoring per raccogliere dati reali sulle prestazioni dalla tua app e quindi esaminare e analizzare tali dati nella console Firebase. Il monitoraggio delle prestazioni ti aiuta a capire dove e quando le prestazioni della tua app possono essere migliorate in modo da poter utilizzare tali informazioni per risolvere i problemi di prestazioni.

Esistono vari modi per l'integrazione con l'SDK JavaScript di Firebase Performance Monitoring. In questo codelab, abbiamo abilitato il monitoraggio delle prestazioni dagli URL di hosting . Fare riferimento alla documentazione per vedere altri metodi per abilitare l'SDK.

Tracce automatiche

Poiché importiamo già getPerformance nella parte superiore di web-start/src/index.js , dobbiamo solo aggiungere una riga per indicare a Performance Monitoring di raccogliere automaticamente le metriche di caricamento della pagina e di richiesta di rete per te quando gli utenti visitano il tuo sito implementato!

  1. In web-start/src/index.js , aggiungi la seguente riga sotto il TODO esistente per inizializzare il monitoraggio delle prestazioni.

index.js

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

Misura il ritardo del primo ingresso (opzionale)

Il primo ritardo di input è utile poiché il browser che risponde a un'interazione dell'utente fornisce agli utenti le loro prime impressioni sulla reattività della tua app.

Il primo ritardo di input inizia quando l'utente interagisce per la prima volta con un elemento della pagina, ad esempio facendo clic su un pulsante o su un collegamento ipertestuale. Si interrompe immediatamente dopo che il browser è in grado di rispondere all'input, il che significa che il browser non è impegnato a caricare o analizzare il contenuto della tua pagina.

Se desideri misurare il ritardo del primo input, dovrai includere direttamente il seguente codice.

  1. Apri public/index.html .
  2. Rimuovere il commento dal tag script nella riga seguente.

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

Per saperne di più sul polyfill del primo ritardo di input, dai un'occhiata alla documentazione .

Visualizza i dati sulle prestazioni

Poiché non hai ancora distribuito il tuo sito (lo implementerai nel passaggio successivo), ecco uno screenshot che mostra le metriche sulle prestazioni di caricamento della pagina che vedrai nella console Firebase entro 30 minuti dall'interazione degli utenti con il tuo sito distribuito :

29389131150f33d7.png

Quando integri l'SDK di monitoraggio delle prestazioni nella tua app, non è necessario scrivere altro codice prima che l'app inizi a monitorare automaticamente diversi aspetti critici delle prestazioni. Per le app Web, l'SDK registra aspetti come il primo disegno contenuto, la possibilità per gli utenti di interagire con la tua app e altro ancora.

Puoi anche impostare tracce, metriche e attributi personalizzati per misurare aspetti specifici della tua app. Visita la documentazione per ulteriori informazioni su tracce e metriche personalizzate e attributi personalizzati .

15. Distribuisci la tua app utilizzando Firebase Hosting

Firebase offre un servizio di hosting per servire le tue risorse e le tue app web. Puoi distribuire i tuoi file su Firebase Hosting utilizzando l'interfaccia a riga di comando di Firebase. Prima della distribuzione, è necessario specificare nel file firebase.json quali file locali devono essere distribuiti. Per questo codelab, l'abbiamo già fatto per te perché questo passaggio era necessario per servire i nostri file durante questo codelab. Le impostazioni di hosting sono specificate sotto l'attributo 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"
  }
}

Queste impostazioni indicano alla CLI che vogliamo distribuire tutti i file nella directory ./public ( "public": "./public" ).

  1. Assicurati che la riga di comando acceda alla directory web-start locale dell'app.
  2. Distribuisci i tuoi file nel tuo progetto Firebase eseguendo il seguente comando:
firebase deploy --except functions
  1. La console dovrebbe visualizzare quanto segue:
=== 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. Visita la tua app Web che ora è completamente ospitata su un CDN globale utilizzando Firebase Hosting in due dei tuoi sottodomini Firebase:
  • https://<firebase-projectId>.firebaseapp.com
  • https://<firebase-projectId>.web.app

In alternativa, puoi eseguire firebase open hosting:site nella riga di comando.

Visita la documentazione per saperne di più su come funziona Firebase Hosting .

Vai alla sezione Hosting della console Firebase del tuo progetto per visualizzare utili informazioni e strumenti di hosting, tra cui la cronologia delle tue distribuzioni, la funzionalità per ripristinare le versioni precedenti della tua app e il flusso di lavoro per configurare un dominio personalizzato.

16. Congratulazioni!

Hai utilizzato Firebase per creare un'applicazione Web di chat in tempo reale!

Di cosa abbiamo parlato

  • Autenticazione Firebase
  • CloudFirestore
  • SDK Firebase per Cloud Storage
  • Messaggeria cloud Firebase
  • Monitoraggio delle prestazioni di Firebase
  • Hosting Firebase

Prossimi passi

Learn more