1. Panoramica
In questo codelab imparerai come utilizzare AngularFire per creare applicazioni Web implementando e distribuendo un client di chat utilizzando prodotti e servizi Firebase.
Cosa imparerai
- Crea un'app Web utilizzando Angular e Firebase.
- 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 pacchetti npm , che in genere viene fornito con Node.js
- Un terminale/console
- Un browser a tua scelta, come Chrome
- Il codice di esempio del codelab (vedi il passaggio successivo del codelab per 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
Utilizzando il tuo IDE, apri o importa la directory 📁 angularfire-start
dal repository clonato. Questa 📁 directory angularfire-start
contiene il codice iniziale per codelab, che sarà un'app web di chat completamente funzionale.
3. Crea e configura un progetto Firebase
Crea un progetto Firebase
- Accedi a Firebase .
- Nella console Firebase, fai clic su Aggiungi progetto , quindi assegna il nome al tuo progetto Firebase FriendlyChat . Ricorda l'ID progetto per il tuo progetto Firebase.
- Deseleziona Abilita Google Analytics per questo progetto
- Fare clic su Crea progetto .
L'applicazione che creerai utilizza i prodotti Firebase disponibili per le app Web:
- Autenticazione Firebase per consentire ai tuoi utenti di accedere facilmente 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 file nel cloud.
- Firebase Hosting per ospitare e servire le tue risorse.
- Firebase Cloud Messaging per inviare notifiche push e visualizzare notifiche popup del browser.
- Firebase Performance Monitoring per raccogliere dati sulle prestazioni degli utenti per la tua app.
Alcuni di questi prodotti necessitano di una configurazione speciale o devono essere abilitati utilizzando la console Firebase.
Aggiungi un'app Web Firebase al progetto
- Fare clic sull'icona Web per creare una nuova app Web Firebase.
- 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 .
- Nel passaggio successivo vedrai un oggetto di configurazione. Copia solo l'oggetto JS (non l'HTML circostante) in firebase-config.js
Abilita l'accesso a Google per l'autenticazione Firebase
Per consentire agli utenti di accedere all'app Web con i propri account Google, utilizzerai il metodo di accesso di Google .
Dovrai abilitare l'accesso a Google :
- Nella console Firebase, individua la sezione Build nel pannello di sinistra.
- Fai clic su Autenticazione , quindi fai clic sulla scheda Metodo di accesso (o fai clic qui per andare direttamente lì).
- Abilita il provider di accesso Google , quindi fai clic su Salva .
- Imposta il nome pubblico della tua app su Friendly Chat e scegli un'e -mail di supporto per il progetto dal menu a discesa.
- Configura la schermata di consenso OAuth in Google Cloud Console e aggiungi un logo:
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:
- Nella sezione Compila della console Firebase, fai clic su Database Firestore .
- Fai clic su Crea database nel riquadro Cloud Firestore.
- Selezionare l'opzione Avvia in modalità test , quindi fare clic su Avanti dopo aver letto la dichiarazione di non responsabilità sulle regole di sicurezza.
La modalità test garantisce la possibilità di scrivere liberamente nel database durante lo sviluppo. Renderai il nostro database più sicuro più avanti in questo codelab.
- Imposta la posizione in cui vengono archiviati i dati Cloud Firestore. Puoi lasciare questa impostazione predefinita o scegliere una regione vicino a te. Fai clic su Fine per effettuare il provisioning di Firestore.
Abilita archiviazione cloud
L'app Web utilizza Cloud Storage for Firebase per archiviare, caricare e condividere immagini.
Dovrai abilitare Cloud Storage:
- Nella sezione Build della console Firebase, fai clic su Archiviazione .
- Se non è presente il pulsante Inizia , significa che l'archiviazione sul cloud è già abilitata e non è necessario seguire i passaggi seguenti.
- Fare clic su Inizia .
- Leggi la dichiarazione di non responsabilità 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. Renderai il nostro spazio di archiviazione più sicuro più avanti in questo codelab.
- 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.
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.
- Installa la CLI eseguendo il seguente comando npm:
npm -g install firebase-tools
- Verificare che la CLI sia stata installata correttamente eseguendo il comando seguente:
firebase --version
Assicurati che la versione della CLI Firebase sia v4.1.0 o successiva.
- Autorizza la CLI Firebase eseguendo il comando seguente:
firebase login
Hai configurato il modello dell'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, devi associare la tua app al tuo progetto Firebase.
- Assicurati che la riga di comando acceda alla directory
angularfire-start
locale della tua app. - Associa la tua app al tuo progetto Firebase eseguendo il comando seguente:
firebase use --add
- Quando richiesto, seleziona il tuo ID progetto , quindi assegna un alias al tuo progetto Firebase.
Un alias è utile se disponi di più ambienti (produzione, staging, ecc.). Tuttavia, per questo codelab, utilizziamo semplicemente l'alias di default
.
- Segui le rimanenti istruzioni sulla riga di comando.
5. Installa AngularFire
Prima di eseguire il progetto, assicurati di aver configurato Angular CLI e AngularFire.
- In una console, esegui il comando seguente:
npm install -g @angular/cli
- Quindi, in una console dalla directory
angularfire-start
, esegui il seguente comando Angular CLI:
ng add @angular/fire
Questo installerà tutte le dipendenze necessarie per il tuo progetto.
- Quando richiesto, seleziona le funzionalità configurate nella console Firebase (
ng deploy -- hosting
,Authentication
,Firestore
,Cloud Functions (callable)
,Cloud Messaging
,Cloud Storage
) e segui le istruzioni sulla console.
6. Esegui l'app iniziale localmente
Ora che hai importato e configurato il tuo progetto, sei pronto per eseguire l'app Web per la prima volta.
- In una console dalla directory
angularfire-start
, esegui il seguente comando CLI Firebase:
firebase emulators:start
- La riga di comando dovrebbe visualizzare la seguente risposta:
✔ hosting: Local server: http://localhost:5000
Stai 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 src
.
- Utilizzando il browser, apri l'app all'indirizzo http://localhost:5000 .
Dovresti vedere l'interfaccia utente dell'app FriendlyChat, che non funziona (ancora!):
L'app non può fare nulla in questo momento, ma con il tuo aiuto lo farà presto! Finora hai presentato solo l'interfaccia utente.
Costruiamo ora una chat in tempo reale!
7. Importa e configura Firebase
Configura Firebase
Dovrai configurare l'SDK Firebase per indicargli quale progetto Firebase stai utilizzando.
- Vai alle impostazioni del progetto nella console Firebase
- Nella scheda "Le tue app", seleziona il nickname dell'app per la quale hai bisogno di un oggetto di configurazione.
- Seleziona "Config" dal riquadro dello snippet dell'SDK Firebase.
Scoprirai che è stato generato un file di ambiente /angularfire-start/src/environments/environment.ts
.
- Copia lo snippet dell'oggetto di configurazione, quindi aggiungilo a
angularfire-start/src/firebase-config.js
.
environment.ts
export const environment = {
firebase: {
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",
},
};
Importa AngularFire
Scoprirai che le funzionalità che hai selezionato nella console sono state automaticamente instradate nel file /angularfire-start/src/app/app.module.ts
. Ciò consente alla tua app di utilizzare caratteristiche e funzionalità di Firebase. Tuttavia, per sviluppare in un ambiente locale, è necessario collegarli per utilizzare la suite Emulator.
- In
/angularfire-start/src/app/app.module.ts
, trova la sezioneimports
e modifica le funzioni fornite per connetterti alla suite dell'emulatore in ambienti non di produzione.
// ...
import { provideAuth,getAuth, connectAuthEmulator } from '@angular/fire/auth';
import { provideFirestore,getFirestore, connectFirestoreEmulator } from '@angular/fire/firestore';
import { provideFunctions,getFunctions, connectFunctionsEmulator } from '@angular/fire/functions';
import { provideMessaging,getMessaging } from '@angular/fire/messaging';
import { provideStorage,getStorage, connectStorageEmulator } from '@angular/fire/storage';
// ...
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideAuth(() => {
const auth = getAuth();
if (location.hostname === 'localhost') {
connectAuthEmulator(auth, 'http://127.0.0.1:9099', { disableWarnings: true });
}
return auth;
}),
provideFirestore(() => {
const firestore = getFirestore();
if (location.hostname === 'localhost') {
connectFirestoreEmulator(firestore, '127.0.0.1', 8080);
}
return firestore;
}),
provideFunctions(() => {
const functions = getFunctions();
if (location.hostname === 'localhost') {
connectFunctionsEmulator(functions, '127.0.0.1', 5001);
}
return functions;
}),
provideStorage(() => {
const storage = getStorage();
if (location.hostname === 'localhost') {
connectStorageEmulator(storage, '127.0.0.1', 5001);
}
return storage;
}),
provideMessaging(() => {
return getMessaging();
}),
// ...
app.module.ts
Durante questo codelab utilizzerai Firebase Authentication, Cloud Firestore, Cloud Storage, Cloud Messaging e Performance Monitoring, quindi importerai 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.
8. Configura l'accesso dell'utente
AngularFire ora dovrebbe essere pronto per l'uso poiché è stato importato e inizializzato in app.module.ts
. Ora implementerai l'accesso utente utilizzando l'autenticazione Firebase .
Autentica i tuoi utenti con Google Sign-In
Nell'app, quando un utente fa clic sul pulsante Accedi con Google , viene attivata la funzione login
. (Lo hai già configurato per te!) Per questo codelab, vuoi autorizzare Firebase a utilizzare Google come provider di identità. Utilizzerai un popup, ma Firebase offre molti altri metodi .
- Nella directory
angularfire-start
, nella sottodirectory/src/app/services/
, aprichat.service.ts
. - Trova la funzione
login
. - Sostituisci l'intera funzione con il seguente codice.
chat.service.ts
// Signs-in Friendly Chat.
login() {
signInWithPopup(this.auth, this.provider).then((result) => {
const credential = GoogleAuthProvider.credentialFromResult(result);
this.router.navigate(['/', 'chat']);
return credential;
})
}
La funzione logout
viene attivata quando l'utente fa clic sul pulsante Disconnetti .
- Torna al file
src/app/services/chat.service.ts
. - Trova la funzione
logout
. - Sostituisci l'intera funzione con il seguente codice.
chat.service.ts
// Logout of Friendly Chat.
logout() {
signOut(this.auth).then(() => {
this.router.navigate(['/', 'login'])
console.log('signed out');
}).catch((error) => {
console.log('sign out error: ' + error);
})
}
Tieni traccia dello stato di autenticazione
Per aggiornare di conseguenza la nostra interfaccia utente, è necessario un modo per verificare se l'utente ha effettuato l'accesso o è disconnesso. Con Firebase Authentication, puoi recuperare dati osservabili sullo stato dell'utente che verranno attivati ogni volta che lo stato di autenticazione cambia.
- Torna al file
src/app/services/chat.service.ts
. - Trova l'assegnazione della variabile
user$
. - Sostituisci l'intera assegnazione con il codice seguente.
chat.service.ts
// Observable user
user$ = user(this.auth);
Il codice sopra chiama la funzione AngularFire user
che restituisce un utente osservabile. Si attiverà ogni volta che cambia lo stato di autenticazione (quando l'utente accede o si disconnette). È a questo punto che aggiornerai l'interfaccia utente per reindirizzare, visualizzare l'utente nel menu di navigazione dell'intestazione e così via. Tutte queste parti dell'interfaccia utente sono già state implementate.
Prova ad accedere all'app
- Se la tua app è ancora in servizio, aggiorna l'app nel browser. Altrimenti, esegui
firebase emulators:start
sulla riga di comando per iniziare a servire l'app da http://localhost:5000 , quindi aprila nel tuo browser. - 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
, assicurati di aver abilitato l'accesso con Google come provider di autenticazione nella console Firebase. - Dopo aver effettuato l'accesso, dovrebbero essere visualizzati l'immagine del profilo e il nome utente:
9. Scrivi messaggi su Cloud Firestore
In questa sezione scriverai alcuni dati su Cloud Firestore in modo da poter popolare l'interfaccia utente dell'app. Questa operazione può essere eseguita manualmente con la console Firebase , ma lo farai nell'app stessa per dimostrare una scrittura di base su Cloud Firestore.
Modello di dati
I dati di Cloud Firestore sono suddivisi in raccolte, documenti, campi e sottoraccolte. Memorizzerai ogni messaggio della chat come documento in una raccolta di primo livello chiamata messages
.
Aggiungi messaggi a Cloud Firestore
Per archiviare i messaggi di chat scritti dagli utenti, utilizzerai 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 il contenuto dei campi messaggio alla tua istanza Cloud Firestore nella raccolta messages
. Il metodo add()
aggiunge alla raccolta un nuovo documento con un ID generato automaticamente.
- Torna al file
src/app/services/chat.service.ts
. - Trova la funzione
addMessage
. - Sostituisci l'intera funzione con il seguente codice.
chat.service.ts
// Adds a text or image message to Cloud Firestore.
addMessage = async(textMessage: string | null, imageUrl: string | null): Promise<void | DocumentReference<DocumentData>> => {
let data: any;
try {
this.user$.subscribe(async (user) =>
{
if(textMessage && textMessage.length > 0) {
data = await addDoc(collection(this.firestore, 'messages'), {
name: user?.displayName,
text: textMessage,
profilePicUrl: user?.photoURL,
timestamp: serverTimestamp(),
uid: user?.uid
})}
else if (imageUrl && imageUrl.length > 0) {
data = await addDoc(collection(this.firestore, 'messages'), {
name: user?.displayName,
imageUrl: imageUrl,
profilePicUrl: user?.photoURL,
timestamp: serverTimestamp(),
uid: user?.uid
});
}
return data;
}
);
}
catch(error) {
console.error('Error writing new message to Firebase Database', error);
return;
}
}
Prova a inviare messaggi
- Se la tua app è ancora in servizio, aggiorna l'app nel browser. Altrimenti, esegui
firebase emulators:start
sulla riga di comando per iniziare a servire l'app da http://localhost:5000 , quindi aprila nel tuo browser. - Dopo aver effettuato l'accesso, inserisci un messaggio come "Ehi!", quindi fai clic su INVIA . Questo scriverà il messaggio in Cloud Firestore. Tuttavia, non vedrai ancora i dati nella tua app Web effettiva perché devi ancora implementare il recupero dei dati (la sezione successiva del codelab).
- Puoi vedere il messaggio appena aggiunto nella console Firebase. Apri l'interfaccia utente della suite di emulazione. Nella sezione Compila , fai clic su Database Firestore (o fai clic qui e dovresti vedere la raccolta di messaggi con il messaggio appena aggiunto:
10. Leggi i messaggi
Sincronizza i messaggi
Per leggere i messaggi nell'app, dovrai aggiungere un osservabile che si attiverà quando i dati cambiano e quindi creare un elemento dell'interfaccia utente che mostri i nuovi messaggi.
Aggiungerai il codice che ascolta i messaggi appena aggiunti dall'app. In questo codice recupererai lo snapshot della raccolta messages
. Visualizzerai solo gli ultimi 12 messaggi della chat per evitare di visualizzare una cronologia molto lunga al momento del caricamento.
- Torna al file
src/app/services/chat.service.ts
. - Trova la funzione
loadMessages
. - Sostituisci l'intera funzione con il seguente codice.
chat.service.ts
// Loads chat message history and listens for upcoming ones.
loadMessages = () => {
// Create the query to load the last 12 messages and listen for new ones.
const recentMessagesQuery = query(collection(this.firestore, 'messages'), orderBy('timestamp', 'desc'), limit(12));
// Start listening to the query.
return collectionData(recentMessagesQuery);
}
Per ascoltare i messaggi nel database, crei una query su una raccolta utilizzando la funzione collection
per specificare in quale raccolta si trovano i dati che desideri ascoltare. Nel codice sopra, stai ascoltando le modifiche all'interno dei messages
raccolta, che è dove vengono archiviati i messaggi di chat. Stai anche applicando un limite ascoltando solo gli ultimi 12 messaggi utilizzando limit(12)
e ordinando i messaggi per data utilizzando orderBy('timestamp', 'desc')
per ottenere i 12 messaggi più recenti.
La funzione collectionData
utilizza gli snapshot dietro le quinte. La funzione di callback verrà attivata quando verranno apportate modifiche ai documenti che corrispondono alla query. Ciò potrebbe accadere se un messaggio viene eliminato, modificato o aggiunto. Puoi leggere ulteriori informazioni al riguardo nella documentazione di Cloud Firestore .
Testare la sincronizzazione dei messaggi
- Se la tua app è ancora in servizio, aggiorna l'app nel browser. Altrimenti, esegui
firebase emulators:start
sulla riga di comando per iniziare a servire l'app da http://localhost:5000 , quindi aprila nel tuo browser. - 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 immediatamente.
- (Facoltativo) Puoi provare a eliminare, modificare o aggiungere manualmente nuovi messaggi direttamente nella sezione Firestore della suite dell'emulatore; eventuali modifiche dovrebbero riflettersi nell'interfaccia utente.
Congratulazioni! Stai leggendo i documenti Cloud Firestore nella tua app!
11. Invia immagini
Ora aggiungerai una funzionalità che condivide le immagini.
Sebbene Cloud Firestore sia utile per l'archiviazione di dati strutturati, Cloud Storage è più adatto per l'archiviazione di file. Cloud Storage for Firebase è un servizio di archiviazione file/blob e lo utilizzerai per archiviare tutte le immagini che un utente condivide utilizzando la nostra app.
Salva le immagini su Cloud Storage
Per questo codelab, hai già aggiunto un pulsante che attiva una finestra di dialogo di selezione file. Dopo aver selezionato un file, viene richiamata la funzione saveImageMessage
ed è possibile ottenere un riferimento al file selezionato. La funzione saveImageMessage
realizza quanto segue:
- Crea un messaggio di chat "segnaposto" nel feed della chat, in modo che gli utenti vedano un'animazione di "Caricamento" mentre carichi l'immagine.
- Carica il file immagine su Cloud Storage in questo percorso:
/<uid>/<file_name>
- Genera un URL leggibile pubblicamente per il file immagine.
- Aggiorna il messaggio di chat con l'URL del file immagine appena caricato al posto dell'immagine di caricamento temporanea.
Ora aggiungerai la funzionalità per inviare un'immagine:
- Torna al file
src/chat.service.ts
. - Trova la funzione
saveImageMessage
. - Sostituisci l'intera funzione con il seguente codice.
chat.service.ts
// Saves a new message containing an image in Firebase.
// This first saves the image in Firebase storage.
saveImageMessage = async(file: any) => {
try {
// 1 - You add a message with a loading icon that will get updated with the shared image.
const messageRef = await this.addMessage(null, this.LOADING_IMAGE_URL);
// 2 - Upload the image to Cloud Storage.
const filePath = `${this.auth.currentUser?.uid}/${file.name}`;
const newImageRef = ref(this.storage, 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.
messageRef ?
await updateDoc(messageRef,{
imageUrl: publicImageUrl,
storageUri: fileSnapshot.metadata.fullPath
}): null;
} catch (error) {
console.error('There was an error uploading a file to Cloud Storage:', error);
}
}
Prova a inviare immagini
- Se la tua app è ancora in servizio, aggiorna l'app nel browser. Altrimenti, esegui
firebase emulators:start
sulla riga di comando per iniziare a servire l'app da http://localhost:5000 , quindi aprila nel tuo browser. - Dopo aver effettuato l'accesso, fai clic sul pulsante di caricamento dell'immagine in basso a sinistra e seleziona un file immagine utilizzando il selettore file. Se stai cercando un'immagine, sentiti libero di usare questa simpatica immagine di una tazza di caffè .
- Dovrebbe apparire un nuovo messaggio nell'interfaccia utente dell'app con l'immagine selezionata:
Se provi ad aggiungere un'immagine senza aver effettuato l'accesso, dovresti visualizzare un errore che ti informa che devi accedere per aggiungere immagini.
12. Mostra notifiche
Ora aggiungerai 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 messaggi e notifiche in modo affidabile e senza alcun costo.
Aggiungi l'operatore del servizio FCM
L'app Web necessita di un operatore del servizio che riceverà e visualizzerà le notifiche Web.
Il provider di messaggistica dovrebbe essere già stato configurato quando è stato aggiunto AngularFire, assicurati che il seguente codice esista nella sezione importazioni di /angularfire-start/src/app/app.module.ts
provideMessaging(() => {
return getMessaging();
}),
app/app.module.ts
L'addetto al servizio deve semplicemente caricare e inizializzare l'SDK Firebase Cloud Messaging, che si occuperà di visualizzare le notifiche.
Ottieni token dispositivo FCM
Quando le notifiche sono state abilitate su un dispositivo o browser, ti verrà assegnato un token del dispositivo . Questo token del dispositivo è ciò che usi per inviare una notifica a un particolare dispositivo o browser specifico.
Quando l'utente accede, chiami la funzione saveMessagingDeviceToken
. È lì che otterrai il token del dispositivo FCM dal browser e lo salverai su Cloud Firestore.
chat.service.ts
- Trova la funzione
saveMessagingDeviceToken
. - Sostituisci l'intera funzione con il seguente codice.
chat.service.ts
// Saves the messaging device token to Cloud Firestore.
saveMessagingDeviceToken= async () => {
try {
const currentToken = await getToken(this.messaging);
if (currentToken) {
console.log('Got FCM device token:', currentToken);
// Saving the Device Token to Cloud Firestore.
const tokenRef = doc(this.firestore, 'fcmTokens', currentToken);
await setDoc(tokenRef, { uid: this.auth.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(this.messaging, (message) => {
console.log(
'New foreground notification from Firebase Messaging!',
message.notification
);
});
} else {
// Need to request permissions to show notifications.
this.requestNotificationsPermissions();
}
} catch(error) {
console.error('Unable to get messaging token.', error);
};
}
Tuttavia, questo codice inizialmente non funzionerà. Affinché la tua app possa recuperare il token del dispositivo, l'utente deve concedere all'app l'autorizzazione a mostrare le notifiche (il passaggio successivo del codelab).
Richiedi le autorizzazioni per mostrare le notifiche
Se l'utente non ha ancora concesso alla tua app l'autorizzazione a mostrare le notifiche, non ti verrà fornito un token del dispositivo. In questo caso, chiami il metodo requestPermission()
, che visualizzerà una finestra di dialogo del browser che richiede questa autorizzazione ( nei browser supportati ).
- Torna al file
src/app/services/chat.service.ts
. - Trova la funzione
requestNotificationsPermissions
. - Sostituisci l'intera funzione con il seguente codice.
chat.service.ts
// Requests permissions to show notifications.
requestNotificationsPermissions = async () => {
console.log('Requesting notifications permission...');
const permission = await Notification.requestPermission();
if (permission === 'granted') {
console.log('Notification permission granted.');
// Notification permission granted.
await this.saveMessagingDeviceToken();
} else {
console.log('Unable to get permission to notify.');
}
}
Ottieni il token del tuo dispositivo
- Se la tua app è ancora in servizio, aggiorna l'app nel browser. Altrimenti, esegui
firebase emulators:start
sulla riga di comando per iniziare a servire l'app da http://localhost:5000 , quindi aprila nel tuo browser. - Dopo aver effettuato l'accesso, dovrebbe apparire la finestra di dialogo per l'autorizzazione delle notifiche:
- Fare clic su Consenti .
- Apri la console JavaScript del tuo browser. Dovresti visualizzare il seguente messaggio:
Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
- Copia il token del tuo dispositivo. Ne avrai bisogno per la fase successiva del codelab.
Invia una notifica al tuo dispositivo
Ora che hai il token del tuo dispositivo, puoi inviare una notifica.
- Apri la scheda Cloud Messaging della console Firebase .
- Fai clic su "Nuova notifica"
- Inserisci un titolo e un testo di notifica.
- Sul lato destro dello schermo, fai clic su "invia un messaggio di prova"
- Inserisci il token del dispositivo che hai copiato dalla console JavaScript del tuo browser, quindi fai clic sul segno più ("+").
- Fare 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:
13. 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, hai scelto di utilizzare le regole di sicurezza predefinite della "modalità test" in modo da non limitare l'accesso al datastore. Nella console 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;
}
}
}
Aggiornerai 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;
}
}
}
Le regole di sicurezza dovrebbero aggiornarsi automaticamente nella tua suite di emulatore.
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, hai scelto di utilizzare la regola di sicurezza predefinita di Cloud Storage che consente solo agli utenti autenticati di utilizzare Cloud Storage. Nella console 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 effettuato 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;
}
}
}
Aggiornerai le regole per effettuare le seguenti operazioni:
- 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
Ciò può essere implementato utilizzando le seguenti regole:
regole.di.archiviazione
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;
}
}
}
14. 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 la CLI Firebase. Prima della distribuzione, è necessario specificare nel file firebase.json
quali file locali devono essere distribuiti. Per questo codelab, lo hai già fatto perché questo passaggio era necessario per servire i nostri file durante questo codelab. Le impostazioni di hosting sono specificate nell'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 desideri distribuire tutti i file nella directory ./public
( "public": "./public"
).
- Assicurati che la riga di comando acceda alla directory
angularfire-start
locale della tua app. - Distribuisci i tuoi file nel tuo progetto Firebase eseguendo il comando seguente:
ng deploy
Quindi seleziona l'opzione Firebase e segui le istruzioni nella riga di comando.
- 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
- Visita la tua app Web che ora è completamente ospitata su una 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.
Consulta la documentazione per saperne di più su come funziona Firebase Hosting .
Vai alla sezione Hosting della console Firebase del tuo progetto per visualizzare informazioni e strumenti di hosting utili, inclusa la cronologia delle distribuzioni, la funzionalità per ripristinare le versioni precedenti della tua app e il flusso di lavoro per impostare un dominio personalizzato.
15. Congratulazioni!
Hai utilizzato Firebase per creare un'applicazione Web di chat in tempo reale!
Quello che hai coperto
- Autenticazione Firebase
- Cloud Fire Store
- SDK Firebase per archiviazione cloud
- Messaggistica cloud Firebase
- Monitoraggio delle prestazioni di Firebase
- Hosting Firebase
Prossimi passi
Saperne di più
16. [Facoltativo] Applica con Controllo app
Firebase App Check aiuta a proteggere i tuoi servizi dal traffico indesiderato e aiuta a proteggere il tuo backend dagli abusi. In questo passaggio aggiungerai la convalida delle credenziali e bloccherai i client non autorizzati con App Check e reCAPTCHA Enterprise .
Innanzitutto, dovrai abilitare App Check e reCaptcha.
Abilitazione di reCaptcha Enterprise
- Nella console Cloud, trova e seleziona reCaptcha Enterprise in Sicurezza.
- Abilita il servizio come richiesto e fai clic su Crea chiave .
- Inserisci un nome visualizzato come richiesto e seleziona Sito web come tipo di piattaforma.
- Aggiungi gli URL distribuiti all'elenco dei domini e assicurati che l'opzione "Utilizza verifica casella di controllo" sia deselezionata .
- Fare clic su Crea chiave e archiviare la chiave generata da qualche parte per tenerla al sicuro. Ne avrai bisogno più avanti in questo passaggio.
Abilitazione del controllo dell'app
- Nella console Firebase, individua la sezione Build nel pannello di sinistra.
- Fai clic su App Check , quindi sulla scheda Metodo di accesso per passare ad App Check .
- Fai clic su Registra e inserisci la chiave reCaptcha Enterprise quando richiesto, quindi fai clic su Salva .
- Nella visualizzazione API, seleziona Archiviazione e fai clic su Applica . Fai lo stesso per Cloud Firestore .
Ora il controllo dell'app dovrebbe essere applicato! Aggiorna la tua app e prova a visualizzare o inviare messaggi di chat. Dovresti ricevere il messaggio di errore:
Uncaught Error in snapshot listener: FirebaseError: [code=permission-denied]: Missing or insufficient permissions.
Ciò significa che App Check blocca le richieste non convalidate per impostazione predefinita. Ora aggiungiamo la convalida alla tua app.
Passare al file environment.ts
e aggiungere reCAPTCHAEnterpriseKey
all'oggetto environment
.
export const environment = {
firebase: {
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',
},
reCAPTCHAEnterpriseKey: {
key: "Replace with your recaptcha enterprise site key"
},
};
Sostituisci il valore di key
con il tuo token reCaptcha Enterprise.
Quindi, vai al file app.module.ts
e aggiungi le seguenti importazioni:
import { getApp } from '@angular/fire/app';
import {
ReCaptchaEnterpriseProvider,
initializeAppCheck,
provideAppCheck,
} from '@angular/fire/app-check';
Nello stesso file app.module.ts
, aggiungi la seguente dichiarazione di variabile globale:
declare global {
var FIREBASE_APPCHECK_DEBUG_TOKEN: boolean;
}
@NgModule({ ...
Nelle importazioni, aggiungi l'inizializzazione di App Check con ReCaptchaEnterpriseProvider
e imposta isTokenAutoRefreshEnabled
su true
per consentire l'aggiornamento automatico dei token.
imports: [
BrowserModule,
AppRoutingModule,
CommonModule,
FormsModule,
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideAppCheck(() => {
const appCheck = initializeAppCheck(getApp(), {
provider: new ReCaptchaEnterpriseProvider(
environment.reCAPTCHAEnterpriseKey.key
),
isTokenAutoRefreshEnabled: true,
});
if (location.hostname === 'localhost') {
self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
}
return appCheck;
}),
Per consentire il test locale, impostare self.FIREBASE_APPCHECK_DEBUG_TOKEN
su true
. Quando aggiorni la tua app in localhost
, questo registrerà un token di debug nella console simile a:
App Check debug token: CEFC0C76-7891-494B-B764-349BDFD00D00. You will need to add it to your app's App Check settings in the Firebase console for it to work.
Ora vai alla Visualizzazione app di App Check nella console Firebase.
Fai clic sul menu extra e seleziona Gestisci token di debug .
Quindi, fai clic su Aggiungi token di debug e incolla il token di debug dalla console come richiesto.
Passare al file chat.service.ts
e aggiungere la seguente importazione:
import { AppCheck } from '@angular/fire/app-check';
Nello stesso file chat.service.ts
, inserisci App Check insieme agli altri servizi Firebase.
export class ChatService {
appCheck: AppCheck = inject(AppCheck);
...
Congratulazioni! App Check ora dovrebbe funzionare nella tua app.