Atelier de programmation Web AngularFire

1. Vue d'ensemble

Dans cet atelier de programmation, vous apprendrez à utiliser AngularFire pour créer des applications Web en implémentant et en déployant un client de chat à l'aide des produits et services Firebase.

angularfire-2.png

Ce que vous apprendrez

  • Créez une application Web à l'aide d'Angular et Firebase.
  • Synchronisez les données à l'aide de Cloud Firestore et Cloud Storage pour Firebase.
  • Authentifiez vos utilisateurs à l'aide de l'authentification Firebase.
  • Déployez votre application Web sur Firebase Hosting.
  • Envoyez des notifications avec Firebase Cloud Messaging.
  • Collectez les données de performances de votre application Web.

Ce dont vous aurez besoin

  • L'IDE/éditeur de texte de votre choix, tel que WebStorm , Atom , Sublime ou VS Code
  • Le gestionnaire de packages npm , qui est généralement fourni avec Node.js
  • Un terminal/console
  • Un navigateur de votre choix, tel que Chrome
  • Exemple de code de l'atelier de programmation (consultez l'étape suivante de l'atelier de programmation pour savoir comment obtenir le code.)

2. Obtenez l'exemple de code

Clonez le dépôt GitHub de l'atelier de programmation à partir de la ligne de commande :

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

Alternativement, si git n'est pas installé, vous pouvez télécharger le référentiel sous forme de fichier ZIP .

Importer l'application de démarrage

À l'aide de votre IDE, ouvrez ou importez le répertoire 📁 angularfire-start à partir du référentiel cloné. Ce répertoire 📁angularfire angularfire-start contient le code de démarrage de l'atelier de programmation, qui sera une application Web de chat entièrement fonctionnelle.

3. Créez et configurez un projet Firebase

Créer un projet Firebase

  1. Connectez-vous à Firebase .
  2. Dans la console Firebase, cliquez sur Ajouter un projet , puis nommez votre projet Firebase FriendlyChat . N'oubliez pas l'ID de votre projet Firebase.
  3. Décochez Activer Google Analytics pour ce projet
  4. Cliquez sur Créer un projet .

L'application que vous allez créer utilise les produits Firebase disponibles pour les applications Web :

  • Authentification Firebase pour permettre à vos utilisateurs de se connecter facilement à votre application.
  • Cloud Firestore pour enregistrer des données structurées sur le cloud et recevoir une notification instantanée lorsque les données changent.
  • Cloud Storage pour Firebase pour enregistrer des fichiers dans le cloud.
  • Firebase Hosting pour héberger et servir vos actifs.
  • Firebase Cloud Messaging pour envoyer des notifications push et afficher les notifications contextuelles du navigateur.
  • Firebase Performance Monitoring pour collecter des données de performances utilisateur pour votre application.

Certains de ces produits nécessitent une configuration spéciale ou doivent être activés à l'aide de la console Firebase.

Ajouter une application Web Firebase au projet

  1. Cliquez sur l'icône Web 58d6543a156e56f9.png pour créer une nouvelle application Web Firebase.
  2. Enregistrez l'application avec le surnom Friendly Chat , puis cochez la case à côté de Configurer également l'hébergement Firebase pour cette application . Cliquez sur Enregistrer l'application .
  3. À l'étape suivante, vous verrez un objet de configuration. Copiez uniquement l'objet JS (pas le HTML environnant) dans firebase-config.js

Capture d'écran de l'application Web Enregistrer

Activer la connexion Google pour l'authentification Firebase

Pour permettre aux utilisateurs de se connecter à l'application Web avec leurs comptes Google, vous utiliserez la méthode de connexion Google .

Vous devrez activer la connexion Google :

  1. Dans la console Firebase, localisez la section Build dans le panneau de gauche.
  2. Cliquez sur Authentification , puis cliquez sur l'onglet Méthode de connexion (ou cliquez ici pour y accéder directement).
  3. Activez le fournisseur de connexion Google , puis cliquez sur Enregistrer .
  4. Définissez le nom public de votre application sur Friendly Chat et choisissez un e-mail d'assistance au projet dans le menu déroulant.
  5. Configurez votre écran de consentement OAuth dans Google Cloud Console et ajoutez un logo :

d89fb3873b5d36ae.png

Activer Cloud Firestore

L'application Web utilise Cloud Firestore pour enregistrer les messages de discussion et recevoir de nouveaux messages de discussion.

Vous devrez activer Cloud Firestore :

  1. Dans la section Build de la console Firebase, cliquez sur Firestore Database .
  2. Cliquez sur Créer une base de données dans le volet Cloud Firestore.

729991a081e7cd5.png

  1. Sélectionnez l'option Démarrer en mode test , puis cliquez sur Suivant après avoir lu l'avertissement concernant les règles de sécurité.

Le mode test garantit que vous pouvez écrire librement dans la base de données pendant le développement. Vous rendrez notre base de données plus sécurisée plus tard dans cet atelier de programmation.

77e4986cbeaf9dee.png

  1. Définissez l'emplacement où vos données Cloud Firestore sont stockées. Vous pouvez laisser cela par défaut ou choisir une région proche de chez vous. Cliquez sur Terminé pour provisionner Firestore.

9f2bb0d4e7ca49c7.png

Activer le stockage cloud

L'application Web utilise Cloud Storage pour Firebase pour stocker, télécharger et partager des images.

Vous devrez activer Cloud Storage :

  1. Dans la section Build de la console Firebase, cliquez sur Storage .
  2. S'il n'y a pas de bouton Commencer , cela signifie que le stockage cloud est déjà activé et que vous n'avez pas besoin de suivre les étapes ci-dessous.
  3. Cliquez sur Commencer .
  4. Lisez l'avertissement concernant les règles de sécurité de votre projet Firebase, puis cliquez sur Suivant .

Avec les règles de sécurité par défaut, tout utilisateur authentifié peut écrire n'importe quoi sur Cloud Storage. Vous rendrez notre stockage plus sécurisé plus tard dans cet atelier de programmation.

62f1afdcd1260127.png

  1. L'emplacement Cloud Storage est présélectionné avec la même région que celle que vous avez choisie pour votre base de données Cloud Firestore. Cliquez sur Terminé pour terminer la configuration.

1d7f49ebaddb32fc.png

4. Installez l'interface de ligne de commande Firebase

L'interface de ligne de commande (CLI) Firebase vous permet d'utiliser Firebase Hosting pour servir votre application Web localement, ainsi que pour déployer votre application Web sur votre projet Firebase.

  1. Installez la CLI en exécutant la commande npm suivante :
npm -g install firebase-tools
  1. Vérifiez que la CLI a été correctement installée en exécutant la commande suivante :
firebase --version

Assurez-vous que la version de Firebase CLI est la version 4.1.0 ou ultérieure.

  1. Autorisez la CLI Firebase en exécutant la commande suivante :
firebase login

Vous avez configuré le modèle d'application Web pour extraire la configuration de votre application pour Firebase Hosting à partir du répertoire local de votre application (le dépôt que vous avez cloné précédemment dans l'atelier de programmation). Mais pour extraire la configuration, vous devez associer votre application à votre projet Firebase.

  1. Assurez-vous que votre ligne de commande accède au répertoire angularfire-start local de votre application.
  2. Associez votre application à votre projet Firebase en exécutant la commande suivante :
firebase use --add
  1. Lorsque vous y êtes invité, sélectionnez votre ID de projet , puis attribuez un alias à votre projet Firebase.

Un alias est utile si vous disposez de plusieurs environnements (production, staging, etc.). Cependant, pour cet atelier de programmation, utilisons simplement l'alias de default .

  1. Suivez les instructions restantes sur votre ligne de commande.

5. Installez AngularFire

Avant d'exécuter le projet, assurez-vous que Angular CLI et AngularFire sont configurés.

  1. Dans une console, exécutez la commande suivante :
npm install -g @angular/cli
  1. Ensuite, dans une console du répertoire angularfire-start , exécutez la commande Angular CLI suivante :
ng add @angular/fire

Cela installera toutes les dépendances nécessaires à votre projet.

  1. Lorsque vous y êtes invité, sélectionnez les fonctionnalités qui ont été configurées dans la console Firebase ( ng deploy -- hosting , Authentication , Firestore , Cloud Functions (callable) , Cloud Messaging , Cloud Storage ) et suivez les invites de la console.

6. Exécutez l'application de démarrage localement

Maintenant que vous avez importé et configuré votre projet, vous êtes prêt à exécuter l'application Web pour la première fois.

  1. Dans une console du répertoire angularfire-start , exécutez la commande Firebase CLI suivante :
firebase emulators:start
  1. Votre ligne de commande devrait afficher la réponse suivante :
✔  hosting: Local server: http://localhost:5000

Vous utilisez l'émulateur Firebase Hosting pour diffuser notre application localement. L'application Web devrait maintenant être disponible sur http://localhost:5000 . Tous les fichiers situés dans le sous-répertoire src sont servis.

  1. À l'aide de votre navigateur, ouvrez votre application à l'adresse http://localhost:5000 .

Vous devriez voir l'interface utilisateur de votre application FriendlyChat, qui ne fonctionne pas (encore !) :

angulairefire-2.png

L'application ne peut rien faire pour le moment, mais avec votre aide, elle le fera bientôt ! Jusqu'à présent, vous n'avez présenté l'interface utilisateur que pour vous.

Créons maintenant un chat en temps réel !

7. Importez et configurez Firebase

Configurer Firebase

Vous devrez configurer le SDK Firebase pour lui indiquer le projet Firebase que vous utilisez.

  1. Accédez aux paramètres de votre projet dans la console Firebase
  2. Dans la fiche "Vos applications", sélectionnez le pseudo de l'application pour laquelle vous avez besoin d'un objet de configuration.
  3. Sélectionnez « Config » dans le volet d'extraits du SDK Firebase.

Vous constaterez qu'un fichier d'environnement /angularfire-start/src/environments/environment.ts a été généré pour vous.

  1. Copiez l'extrait de l'objet de configuration, puis ajoutez-le à 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",
  },
};

Importer AngularFire

Vous constaterez que les fonctionnalités que vous avez sélectionnées dans la console ont été automatiquement routées dans le fichier /angularfire-start/src/app/app.module.ts . Cela permet à votre application d'utiliser les fonctionnalités de Firebase. Cependant, pour développer dans un environnement local, vous devez les connecter pour utiliser la suite Emulator.

  1. Dans /angularfire-start/src/app/app.module.ts , recherchez la section imports et modifiez les fonctions fournies pour vous connecter à la suite Emulator dans des environnements de non-production.
// ...

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

Au cours de cet atelier de programmation, vous allez utiliser l'authentification Firebase, Cloud Firestore, Cloud Storage, Cloud Messaging et Performance Monitoring, afin d'importer toutes leurs bibliothèques. Dans vos futures applications, assurez-vous de n'importer que les parties de Firebase dont vous avez besoin, afin de réduire le temps de chargement de votre application.

8. Configurer la connexion des utilisateurs

AngularFire devrait maintenant être prêt à être utilisé puisqu'il est importé et initialisé dans app.module.ts . Vous allez maintenant implémenter la connexion des utilisateurs à l'aide de Firebase Authentication .

Authentifiez vos utilisateurs avec Google Sign-In

Dans l'application, lorsqu'un utilisateur clique sur le bouton Se connecter avec Google , la fonction login est déclenchée. (Vous avez déjà configuré cela pour vous !) Pour cet atelier de programmation, vous souhaitez autoriser Firebase à utiliser Google comme fournisseur d'identité. Vous utiliserez une fenêtre contextuelle, mais plusieurs autres méthodes sont disponibles sur Firebase.

  1. Dans le répertoire angularfire-start , dans le sous-répertoire /src/app/services/ , ouvrez chat.service.ts .
  2. Recherchez la fonction login .
  3. Remplacez la fonction entière par le code suivant.

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 fonction logout est déclenchée lorsque l'utilisateur clique sur le bouton Déconnexion .

  1. Revenez au fichier src/app/services/chat.service.ts .
  2. Recherchez la fonction logout .
  3. Remplacez la fonction entière par le code suivant.

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

Suivre l'état d'authentification

Pour mettre à jour notre interface utilisateur en conséquence, vous avez besoin d'un moyen de vérifier si l'utilisateur est connecté ou déconnecté. Avec l'authentification Firebase, vous pouvez récupérer des observables sur l'état de l'utilisateur qui seront déclenchés à chaque fois que l'état d'authentification change.

  1. Revenez au fichier src/app/services/chat.service.ts .
  2. Recherchez l'affectation de variable user$ .
  3. Remplacez l’intégralité de l’affectation par le code suivant.

chat.service.ts

// Observable user
user$ = user(this.auth);

Le code ci-dessus appelle la fonction AngularFire user qui renvoie un utilisateur observable. Il se déclenchera à chaque fois que l'état d'authentification change (lorsque l'utilisateur se connecte ou se déconnecte). C'est à ce stade que vous mettrez à jour l'interface utilisateur pour rediriger, afficher l'utilisateur dans l'en-tête de navigation, etc. Toutes ces parties de l'interface utilisateur ont déjà été implémentées.

Testez la connexion à l'application

  1. Si votre application est toujours en cours de diffusion, actualisez-la dans le navigateur. Sinon, exécutez firebase emulators:start sur la ligne de commande pour commencer à diffuser l'application à partir de http://localhost:5000 , puis ouvrez-la dans votre navigateur.
  2. Connectez-vous à l'application à l'aide du bouton de connexion et de votre compte Google. Si vous voyez un message d'erreur indiquant auth/operation-not-allowed , assurez-vous que vous avez activé Google Sign-in en tant que fournisseur d'authentification dans la console Firebase.
  3. Une fois connecté, votre photo de profil et votre nom d'utilisateur devraient s'afficher : angulairefire-3.png

9. Écrivez des messages sur Cloud Firestore

Dans cette section, vous allez écrire des données dans Cloud Firestore afin de pouvoir remplir l'interface utilisateur de l'application. Cela peut être fait manuellement avec la console Firebase , mais vous le ferez dans l'application elle-même pour démontrer une écriture de base dans Cloud Firestore.

Modèle de données

Les données Cloud Firestore sont divisées en collections, documents, champs et sous-collections. Vous stockerez chaque message du chat en tant que document dans une collection de niveau supérieur appelée messages .

688d7bc5fb662b57.png

Ajouter des messages à Cloud Firestore

Pour stocker les messages de discussion rédigés par les utilisateurs, vous utiliserez Cloud Firestore .

Dans cette section, vous allez ajouter la fonctionnalité permettant aux utilisateurs d'écrire de nouveaux messages dans votre base de données. Un utilisateur cliquant sur le bouton ENVOYER déclenchera l'extrait de code ci-dessous. Il ajoute un objet message avec le contenu des champs de message à votre instance Cloud Firestore dans la collection messages . La méthode add() ajoute un nouveau document avec un identifiant généré automatiquement à la collection.

  1. Revenez au fichier src/app/services/chat.service.ts .
  2. Recherchez la fonction addMessage .
  3. Remplacez la fonction entière par le code suivant.

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

Tester l'envoi de messages

  1. Si votre application est toujours en cours de diffusion, actualisez-la dans le navigateur. Sinon, exécutez firebase emulators:start sur la ligne de commande pour commencer à diffuser l'application à partir de http://localhost:5000 , puis ouvrez-la dans votre navigateur.
  2. Après vous être connecté, saisissez un message tel que « Salut ! », puis cliquez sur ENVOYER . Cela écrira le message dans Cloud Firestore. Cependant, vous ne verrez pas encore les données dans votre application Web actuelle , car vous devez encore implémenter la récupération des données (la section suivante de l'atelier de programmation).
  3. Vous pouvez voir le message nouvellement ajouté dans votre console Firebase. Ouvrez l’interface utilisateur de votre suite Emulator. Dans la section Créer , cliquez sur Base de données Firestore (ou cliquez ici et vous devriez voir la collection de messages avec votre message nouvellement ajouté :

6812efe7da395692.png

10. Lire les messages

Synchroniser les messages

Pour lire les messages dans l'application, vous devrez ajouter un observable qui se déclenchera lorsque les données changeront, puis créer un élément d'interface utilisateur qui affichera les nouveaux messages.

Vous ajouterez du code qui écoute les messages nouvellement ajoutés depuis l’application. Dans ce code, vous récupérerez l'instantané de la collection messages . Vous n'afficherez que les 12 derniers messages du chat pour éviter d'afficher un historique très long au chargement.

  1. Revenez au fichier src/app/services/chat.service.ts .
  2. Recherchez la fonction loadMessages .
  3. Remplacez la fonction entière par le code suivant.

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

Pour écouter les messages dans la base de données, vous créez une requête sur une collection en utilisant la fonction collection pour spécifier dans quelle collection se trouvent les données que vous souhaitez écouter. Dans le code ci-dessus, vous écoutez les modifications dans les messages collection, où sont stockés les messages de discussion. Vous appliquez également une limite en écoutant uniquement les 12 derniers messages à l'aide limit(12) et en classant les messages par date à l'aide de orderBy('timestamp', 'desc') pour obtenir les 12 messages les plus récents.

La fonction collectionData utilise des instantanés sous le capot. La fonction de rappel sera déclenchée lorsque des modifications seront apportées aux documents correspondant à la requête. Cela peut se produire si un message est supprimé, modifié ou ajouté. Vous pouvez en savoir plus à ce sujet dans la documentation Cloud Firestore .

Tester la synchronisation des messages

  1. Si votre application est toujours en cours de diffusion, actualisez-la dans le navigateur. Sinon, exécutez firebase emulators:start sur la ligne de commande pour commencer à diffuser l'application à partir de http://localhost:5000 , puis ouvrez-la dans votre navigateur.
  2. Les messages que vous avez créés précédemment dans la base de données doivent être affichés dans l'interface utilisateur de FriendlyChat (voir ci-dessous). N'hésitez pas à écrire de nouveaux messages ; ils devraient apparaître instantanément.
  3. (Facultatif) Vous pouvez essayer de supprimer, modifier ou ajouter manuellement de nouveaux messages directement dans la section Firestore de la suite Emulator ; tout changement doit être reflété dans l’interface utilisateur.

Toutes nos félicitations! Vous lisez des documents Cloud Firestore dans votre application !

angulairefire-2.png

11. Envoyer des images

Vous allez maintenant ajouter une fonctionnalité qui partage des images.

Alors que Cloud Firestore convient au stockage de données structurées, Cloud Storage est mieux adapté au stockage de fichiers. Cloud Storage pour Firebase est un service de stockage de fichiers/blob, et vous l'utiliserez pour stocker toutes les images qu'un utilisateur partage à l'aide de notre application.

Enregistrer des images sur le stockage cloud

Pour cet atelier de programmation, vous avez déjà ajouté un bouton qui déclenche une boîte de dialogue de sélection de fichiers. Après avoir sélectionné un fichier, la fonction saveImageMessage est appelée et vous pouvez obtenir une référence au fichier sélectionné. La fonction saveImageMessage accomplit les tâches suivantes :

  1. Crée un message de discussion « espace réservé » dans le fil de discussion, afin que les utilisateurs voient une animation « Chargement » pendant que vous téléchargez l'image.
  2. Télécharge le fichier image sur Cloud Storage vers ce chemin : /<uid>/<file_name>
  3. Génère une URL lisible publiquement pour le fichier image.
  4. Met à jour le message de discussion avec l'URL du fichier image nouvellement téléchargé au lieu de l'image de chargement temporaire.

Vous allez maintenant ajouter la fonctionnalité permettant d'envoyer une image :

  1. Revenez au fichier src/chat.service.ts .
  2. Recherchez la fonction saveImageMessage .
  3. Remplacez la fonction entière par le code suivant.

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

Tester l'envoi d'images

  1. Si votre application est toujours en cours de diffusion, actualisez-la dans le navigateur. Sinon, exécutez firebase emulators:start sur la ligne de commande pour commencer à diffuser l'application à partir de http://localhost:5000 , puis ouvrez-la dans votre navigateur.
  2. Après vous être connecté, cliquez sur le bouton de téléchargement d'image en bas à gauche angulairefire-4.png et sélectionnez un fichier image à l’aide du sélecteur de fichiers. Si vous cherchez une image, n'hésitez pas à utiliser cette jolie photo d'une tasse de café .
  3. Un nouveau message devrait apparaître dans l'interface utilisateur de l'application avec l'image sélectionnée : angulairefire-2.png

Si vous essayez d'ajouter une image sans être connecté, vous devriez voir une erreur vous indiquant que vous devez vous connecter pour ajouter des images.

12. Afficher les notifications

Vous allez maintenant ajouter la prise en charge des notifications du navigateur. L'application avertira les utilisateurs lorsque de nouveaux messages seront publiés dans le chat. Firebase Cloud Messaging (FCM) est une solution de messagerie multiplateforme qui vous permet de transmettre des messages et des notifications de manière fiable et gratuite.

Ajouter le service worker FCM

L'application Web a besoin d'un service worker qui recevra et affichera les notifications Web.

Le fournisseur de messagerie devrait déjà avoir été configuré lors de l'ajout d'AngularFire, assurez-vous que le code suivant existe dans la section importations de /angularfire-start/src/app/app.module.ts

provideMessaging(() => {
    return getMessaging();
}),

app/app.module.ts

Le service worker doit simplement charger et initialiser le SDK Firebase Cloud Messaging, qui se chargera d'afficher les notifications.

Obtenir des jetons d'appareil FCM

Lorsque les notifications ont été activées sur un appareil ou un navigateur, vous recevrez un jeton d'appareil . Ce jeton d'appareil est ce que vous utilisez pour envoyer une notification à un appareil particulier ou à un navigateur particulier.

Lorsque l'utilisateur se connecte, vous appelez la fonction saveMessagingDeviceToken . C'est là que vous obtiendrez le jeton de périphérique FCM du navigateur et l'enregistrerez dans Cloud Firestore.

chat.service.ts

  1. Recherchez la fonction saveMessagingDeviceToken .
  2. Remplacez la fonction entière par le code suivant.

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

Cependant, ce code ne fonctionnera pas au départ. Pour que votre application puisse récupérer le jeton de l'appareil, l'utilisateur doit accorder à votre application l'autorisation d'afficher des notifications (étape suivante de l'atelier de programmation).

Demander des autorisations pour afficher les notifications

Lorsque l'utilisateur n'a pas encore autorisé votre application à afficher des notifications, vous ne recevrez pas de jeton d'appareil. Dans ce cas, vous appelez la méthode requestPermission() , qui affichera une boîte de dialogue du navigateur demandant cette autorisation ( dans les navigateurs pris en charge ).

8b9d0c66dc36153d.png

  1. Revenez au fichier src/app/services/chat.service.ts .
  2. Recherchez la fonction requestNotificationsPermissions .
  3. Remplacez la fonction entière par le code suivant.

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

Obtenez le jeton de votre appareil

  1. Si votre application est toujours en cours de diffusion, actualisez-la dans le navigateur. Sinon, exécutez firebase emulators:start sur la ligne de commande pour commencer à diffuser l'application à partir de http://localhost:5000 , puis ouvrez-la dans votre navigateur.
  2. Une fois connecté, la boîte de dialogue d'autorisation des notifications devrait apparaître : bd3454e6dbfb6723.png
  3. Cliquez sur Autoriser .
  4. Ouvrez la console JavaScript de votre navigateur. Le message suivant doit s'afficher : Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
  5. Copiez le jeton de votre appareil. Vous en aurez besoin pour la prochaine étape de l'atelier de programmation.

Envoyer une notification sur votre appareil

Maintenant que vous disposez du token de votre appareil, vous pouvez envoyer une notification.

  1. Ouvrez l' onglet Cloud Messaging de la console Firebase .
  2. Cliquez sur "Nouvelle notification"
  3. Saisissez un titre de notification et un texte de notification.
  4. Sur le côté droit de l'écran, cliquez sur "envoyer un message test"
  5. Saisissez le jeton d'appareil que vous avez copié depuis la console JavaScript de votre navigateur, puis cliquez sur le signe plus (« + »)
  6. Cliquez sur "tester"

Si votre application est au premier plan, vous verrez la notification dans la console JavaScript.

Si votre application est en arrière-plan, une notification devrait apparaître dans votre navigateur, comme dans cet exemple :

de79e8638a45864c.png

13. Règles de sécurité Cloud Firestore

Afficher les règles de sécurité de la base de données

Cloud Firestore utilise un langage de règles spécifique pour définir les droits d'accès, la sécurité et les validations des données.

Lors de la configuration du projet Firebase au début de cet atelier de programmation, vous avez choisi d'utiliser les règles de sécurité par défaut du "Mode test" afin de ne pas restreindre l'accès à la banque de données. Dans la console Firebase , dans l'onglet Règles de la section Base de données , vous pouvez consulter et modifier ces règles.

À l'heure actuelle, vous devriez voir les règles par défaut, qui ne restreignent pas l'accès à la banque de données. Cela signifie que n'importe quel utilisateur peut lire et écrire dans n'importe quelle collection de votre banque de données.

rules_version = '2';

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

Vous mettrez à jour les règles pour restreindre les choses en utilisant les règles suivantes :

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

Les règles de sécurité devraient être mises à jour automatiquement dans votre suite Emulator.

Afficher les règles de sécurité de Cloud Storage

Cloud Storage pour Firebase utilise un langage de règles spécifique pour définir les droits d'accès, la sécurité et les validations des données.

Lors de la configuration du projet Firebase au début de cet atelier de programmation, vous avez choisi d'utiliser la règle de sécurité Cloud Storage par défaut qui autorise uniquement les utilisateurs authentifiés à utiliser Cloud Storage. Dans la console Firebase , dans l'onglet Règles de la section Stockage , vous pouvez afficher et modifier les règles. Vous devriez voir la règle par défaut qui permet à tout utilisateur connecté de lire et d'écrire tous les fichiers de votre compartiment de stockage.

rules_version = '2';

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

Vous allez mettre à jour les règles pour effectuer les opérations suivantes :

  • Autoriser chaque utilisateur à écrire uniquement dans ses propres dossiers spécifiques
  • Autoriser n'importe qui à lire depuis Cloud Storage
  • Assurez-vous que les fichiers téléchargés sont des images
  • Limitez la taille des images pouvant être téléchargées à 5 Mo maximum

Cela peut être mis en œuvre en utilisant les règles suivantes :

règles de stockage

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. Déployez votre application à l'aide de Firebase Hosting

Firebase propose un service d'hébergement pour servir vos actifs et vos applications Web. Vous pouvez déployer vos fichiers sur Firebase Hosting à l'aide de la CLI Firebase. Avant le déploiement, vous devez spécifier dans votre fichier firebase.json quels fichiers locaux doivent être déployés. Pour cet atelier de programmation, vous l'avez déjà fait pour vous, car cette étape était nécessaire pour diffuser nos fichiers au cours de cet atelier de programmation. Les paramètres d'hébergement sont spécifiés sous l'attribut 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"
  }
}

Ces paramètres indiquent à la CLI que vous souhaitez déployer tous les fichiers du répertoire ./public ( "public": "./public" ).

  1. Assurez-vous que votre ligne de commande accède au répertoire angularfire-start local de votre application.
  2. Déployez vos fichiers sur votre projet Firebase en exécutant la commande suivante :
ng deploy

Sélectionnez ensuite l'option Firebase et suivez les invites de la ligne de commande.

  1. La console devrait afficher ce qui suit :
=== 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. Visitez votre application Web qui est désormais entièrement hébergée sur un CDN mondial à l'aide de l'hébergement Firebase sur deux de vos propres sous-domaines Firebase :
  • https://<firebase-projectId>.firebaseapp.com
  • https://<firebase-projectId>.web.app

Alternativement, vous pouvez exécuter firebase open hosting:site dans la ligne de commande.

Consultez la documentation pour en savoir plus sur le fonctionnement de Firebase Hosting .

Accédez à la section Hébergement de la console Firebase de votre projet pour afficher des informations et des outils d'hébergement utiles, notamment l'historique de vos déploiements, la fonctionnalité permettant de revenir aux versions précédentes de votre application et le flux de travail permettant de configurer un domaine personnalisé.

15. Félicitations !

Vous avez utilisé Firebase pour créer une application Web de chat en temps réel !

Ce que vous avez couvert

  • Authentification Firebase
  • Cloud Firestore
  • SDK Firebase pour le stockage cloud
  • Messagerie cloud Firebase
  • Surveillance des performances de Firebase
  • Hébergement Firebase

Prochaines étapes

Apprendre encore plus

16. [Facultatif] Appliquer avec App Check

Firebase App Check aide à sécuriser vos services contre le trafic indésirable et à protéger votre backend contre les abus. Au cours de cette étape, vous allez ajouter la validation des informations d'identification et bloquer les clients non autorisés avec App Check et reCAPTCHA Enterprise .

Tout d’abord, vous devrez activer App Check et reCaptcha.

Activation de reCaptcha Entreprise

  1. Dans la console Cloud, recherchez et sélectionnez reCaptcha Enterprise sous Sécurité.
  2. Activez le service lorsque vous y êtes invité, puis cliquez sur Créer une clé .
  3. Saisissez un nom d'affichage lorsque vous y êtes invité et sélectionnez Site Web comme type de plate-forme.
  4. Ajoutez vos URL déployées à la liste des domaines et assurez-vous que l'option "Utiliser la vérification par case à cocher" n'est pas sélectionnée .
  5. Cliquez sur Créer une clé et stockez la clé générée quelque part pour la conserver. Vous en aurez besoin plus tard dans cette étape.

Activation de la vérification des applications

  1. Dans la console Firebase, localisez la section Build dans le panneau de gauche.
  2. Cliquez sur App Check , puis cliquez sur l'onglet Méthode de connexion pour accéder à App Check .
  3. Cliquez sur S'inscrire et saisissez votre clé reCaptcha Enterprise lorsque vous y êtes invité, puis cliquez sur Enregistrer .
  4. Dans la vue API, sélectionnez Stockage et cliquez sur Appliquer . Faites de même pour Cloud Firestore .

App Check devrait maintenant être appliqué ! Actualisez votre application et essayez d'afficher ou d'envoyer des messages de discussion. Vous devriez obtenir le message d'erreur :

Uncaught Error in snapshot listener: FirebaseError: [code=permission-denied]: Missing or insufficient permissions.

Cela signifie qu'App Check bloque les demandes non validées par défaut. Ajoutons maintenant la validation à votre application.

Accédez à votre fichier environment.ts et ajoutez reCAPTCHAEnterpriseKey à l'objet 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"
  },
};

Remplacez la valeur de key par votre jeton reCaptcha Enterprise.

Ensuite, accédez au fichier app.module.ts et ajoutez les importations suivantes :

import { getApp } from '@angular/fire/app';
import {
  ReCaptchaEnterpriseProvider,
  initializeAppCheck,
  provideAppCheck,
} from '@angular/fire/app-check';

Dans le même fichier app.module.ts , ajoutez la déclaration de variable globale suivante :

declare global {
  var FIREBASE_APPCHECK_DEBUG_TOKEN: boolean;
}

@NgModule({ ...

Dans les importations, ajoutez l’initialisation d’App Check avec ReCaptchaEnterpriseProvider et définissez isTokenAutoRefreshEnabled sur true pour permettre l’actualisation automatique des jetons.

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

Pour autoriser les tests locaux, définissez self.FIREBASE_APPCHECK_DEBUG_TOKEN sur true . Lorsque vous actualisez votre application dans localhost , cela enregistrera un jeton de débogage dans la console similaire à :

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.

Maintenant, accédez à la vue Applications d’App Check dans la console Firebase.

Cliquez sur le menu de débordement et sélectionnez Gérer les jetons de débogage .

Ensuite, cliquez sur Ajouter un jeton de débogage et collez le jeton de débogage depuis votre console comme vous y êtes invité.

Accédez au fichier chat.service.ts et ajoutez l'importation suivante :

import { AppCheck } from '@angular/fire/app-check';

Dans le même fichier chat.service.ts , injectez App Check aux côtés des autres services Firebase.

export class ChatService {
appCheck: AppCheck = inject(AppCheck);
...

Toutes nos félicitations! App Check devrait maintenant fonctionner dans votre application.