Benachrichtigungen für eine Web-App mit Cloud Messaging und Cloud Functions senden

1. Übersicht

In diesem Codelab erfahren Sie, wie Sie mit Cloud Functions for Firebase einer Chat-Web-App Funktionen hinzufügen, indem Sie Nutzern der Chat-App Benachrichtigungen senden.

3b1284f5144b54f6.png

Lerninhalte

  • Funktionen in Google Cloud Functions mit Firebase SDK erstellen
  • Cloud Functions basierend auf Auth, Cloud Storage und Cloud Firestore-Ereignissen auslösen
  • Einer Web-App Unterstützung von Firebase Cloud Messaging hinzufügen

Voraussetzungen

  • Eine Kreditkarte Für Cloud Functions for Firebase ist der Firebase Blaze-Tarif erforderlich. Sie müssen also die Abrechnung für Ihr Firebase-Projekt mit einer Kreditkarte aktivieren.
  • Die IDE/den Texteditor Ihrer Wahl, z. B. WebStorm, Atom oder Sublime.
  • Ein Terminal zum Ausführen von Shell-Befehlen mit installierter Node.js-Version 9.
  • Einen Browser wie Chrome
  • Der Beispielcode Weitere Informationen dazu finden Sie im nächsten Schritt.

2. Beispielcode abrufen

Klonen Sie das GitHub-Repository über die Befehlszeile:

git clone https://github.com/firebase/friendlychat

Start-App importieren

Öffnen oder importieren Sie das Verzeichnis android_studio_folder.pngcloud-functions-start aus dem Beispielcodeverzeichnis in Ihrer IDE. Dieses Verzeichnis enthält den Startcode für das Codelab, das aus einer voll funktionsfähigen Chat-Web-App besteht.

3. Firebase-Projekt erstellen und App einrichten

Projekt erstellen

Klicken Sie in der Firebase Console auf Projekt hinzufügen und geben Sie FriendlyChat als Namen ein.

Klicken Sie auf Projekt erstellen.

Upgrade auf den Blaze-Tarif durchführen

Damit Sie Cloud Functions for Firebase und Cloud Storage for Firebase verwenden können, muss für Ihr Firebase-Projekt der Blaze-Tarif (Pay as you go) verwendet werden. Das bedeutet, dass es mit einem Cloud-Rechnungskonto verknüpft sein muss.

Wenn Sie keine Kreditkarte haben oder den Blaze-Preisplan nicht weiter nutzen möchten, können Sie die Firebase Emulator Suite verwenden, mit der Sie Cloud Functions kostenlos auf Ihrem lokalen Computer emulieren können.

Alle Firebase-Projekte, einschließlich derjenigen mit dem Blaze-Preisplan, haben weiterhin Zugriff auf Kontingente für die kostenlose Nutzung von Cloud Functions. Die in diesem Codelab beschriebenen Schritte bleiben innerhalb der Nutzungslimits der kostenlosen Stufe. Es fallen jedoch geringe Gebühren (ca.0,03 $) für Cloud Storage an, das zum Hosten Ihrer Cloud Functions-Build-Images verwendet wird.

So führen Sie ein Upgrade auf den Blaze-Tarif durch:

  1. Wählen Sie in der Firebase Console Tarif upgraden aus.
  2. Wählen Sie den Blaze-Tarif aus. Folgen Sie der Anleitung auf dem Bildschirm, um ein Cloud-Rechnungskonto mit Ihrem Projekt zu verknüpfen.
    Wenn Sie im Rahmen dieses Upgrades ein Cloud-Rechnungskonto erstellen mussten, müssen Sie möglicherweise zur Firebase Console zurückkehren, um das Upgrade abzuschließen.

Google Auth aktivieren

Damit sich Nutzer in der App anmelden können, verwenden wir Google Auth, das aktiviert werden muss.

Öffnen Sie in der Firebase Console den Bereich Build > Authentifizierung > Tab Anmeldemethode (oder klicken Sie hier, um dorthin zu gelangen). Aktivieren Sie dann den Anmeldeanbieter Google und klicken Sie auf Speichern. So können sich Nutzer mit ihren Google-Konten in der Web-App anmelden.

Sie können den öffentlichen Namen Ihrer App auch zu Friendly Chat ändern:

8290061806aacb46.png

Cloud Storage for Firebase einrichten

Die App nutzt Cloud Storage, um Bilder hochzuladen.

So richten Sie Cloud Storage for Firebase in Ihrem Firebase-Projekt ein:

  1. Maximieren Sie im linken Bereich der Firebase Console die Option Build und wählen Sie dann Storage aus.
  2. Klicken Sie auf Jetzt starten.
  3. Wählen Sie einen Speicherort für Ihren Standard-Storage-Bucket aus.
    Für Buckets in US-WEST1, US-CENTRAL1 und US-EAST1 kann die Stufe „Immer kostenlos“ für Google Cloud Storage genutzt werden. Für Buckets an allen anderen Speicherorten gelten die Preise und Nutzungsbedingungen für Google Cloud Storage.
  4. Klicken Sie auf Im Testmodus starten. Lesen Sie den Haftungsausschluss zu den Sicherheitsregeln.
    Verbreiten oder veröffentlichen Sie keine App, ohne Sicherheitsregeln für Ihren Speicher-Bucket hinzuzufügen.
  5. Klicken Sie auf Erstellen.

Web-App hinzufügen

Fügen Sie in der Firebase Console eine Webanwendung hinzu. Klicken Sie dazu auf Projekteinstellungen und scrollen Sie nach unten zu App hinzufügen. Wählen Sie „Web“ als Plattform aus und klicken Sie das Kästchen für die Einrichtung von Firebase Hosting an. Registrieren Sie dann die App und klicken Sie für die restlichen Schritte auf Weiter und abschließend auf Zur Console.

4. Firebase-Befehlszeilentool installieren

Mit der Firebase Command Line Interface (CLI) können Sie die Web-App lokal bereitstellen und Ihre Web-App und Cloud Functions bereitstellen.

Führen Sie den folgenden npm-Befehl aus, um die Befehlszeile zu installieren oder zu aktualisieren:

npm -g install firebase-tools

Um zu prüfen, ob die Befehlszeile richtig installiert wurde, öffnen Sie eine Konsole und führen Sie Folgendes aus:

firebase --version

Die Version der Firebase CLI muss höher als 4.0.0 sein, damit alle neuesten Funktionen für Cloud Functions verfügbar sind. Falls nicht, führen Sie npm install -g firebase-tools aus, um wie oben beschrieben ein Upgrade durchzuführen.

Autorisieren Sie die Firebase CLI mit dem folgenden Befehl:

firebase login

Achten Sie darauf, dass Sie sich im Verzeichnis cloud-functions-start befinden, und richten Sie die Firebase CLI so ein, dass sie Ihr Firebase-Projekt verwendet:

firebase use --add

Wählen Sie als Nächstes Ihre Projekt-ID aus und folgen Sie der Anleitung. Wenn Sie dazu aufgefordert werden, können Sie einen beliebigen Alias auswählen, z. B. codelab.

5. Web-App bereitstellen und ausführen

Nachdem Sie das Projekt importiert und konfiguriert haben, können Sie die Web-App zum ersten Mal ausführen. Öffnen Sie ein Terminalfenster, rufen Sie den Ordner cloud-functions-start auf und stellen Sie die Webanwendung mit folgendem Befehl in Firebase Hosting bereit:

firebase deploy --except functions

Die Ausgabe der Konsole sollte so aussehen:

i deploying database, storage, hosting
✔  database: rules ready to deploy.
i  storage: checking rules for compilation errors...
✔  storage: rules file compiled successfully
i  hosting: preparing ./ directory for upload...
✔  hosting: ./ folder uploaded successfully
✔ storage: rules file compiled successfully
✔ hosting: 8 files uploaded successfully
i starting release process (may take several minutes)...

✔ Deploy complete!

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

Webanwendung öffnen

In der letzten Zeile sollte die Hosting-URL angezeigt werden. Die Webanwendung sollte jetzt über diese URL bereitgestellt werden, die das Format https://<project-id>.firebaseapp.com haben sollte. Öffnen Sie sie. Daraufhin sollte die funktionierende Benutzeroberfläche einer Chat-App angezeigt werden.

Melden Sie sich über die Schaltfläche ÜBER GOOGLE ANMELDEN in der App an und fügen Sie Nachrichten hinzu oder posten Sie Bilder:

3b1284f5144b54f6.png

Wenn Sie sich zum ersten Mal über einen neuen Browser in der App anmelden, sollten Sie Benachrichtigungen zulassen, wenn die entsprechende Aufforderung erscheint: 8b9d0c66dc36153d.png

Benachrichtigungen müssen später aktiviert werden.

Falls Sie versehentlich auf Blockieren geklickt haben, können Sie diese Einstellung wieder ändern. Klicken Sie dazu in der Chrome Omnibar links neben der URL auf die Schaltfläche 🔒 Sicher und aktivieren oder deaktivieren Sie die Leiste neben Benachrichtigungen:

e926868b0546ed71.png

Jetzt fügen wir mithilfe des Firebase SDK for Cloud Functions einige Funktionen hinzu.

6. Das Cloud Functions-Verzeichnis

Mit Cloud Functions können Sie Code ganz einfach in der Cloud ausführen, ohne einen Server einrichten zu müssen. Wir zeigen Ihnen, wie Sie Funktionen erstellen, die auf Firebase Auth-, Cloud Storage- und Firebase Firestore-Datenbankereignisse reagieren. Beginnen wir mit der Authentifizierung.

Wenn Sie das Firebase SDK for Cloud Functions verwenden, befindet sich Ihr Functions-Code standardmäßig im Verzeichnis functions. Der Functions-Code ist auch eine Node.js-App. Daher ist eine package.json-Datei mit Angaben zu Ihrer App und einer Liste der Abhängigkeiten erforderlich.

Zur Vereinfachung haben wir bereits die Datei functions/index.js erstellt, in die der Code eingefügt werden soll. Sehen Sie sich diese Datei an, bevor Sie fortfahren.

cd functions
ls

Wenn Sie mit Node.js nicht vertraut sind, sollten Sie sich damit vertraut machen, bevor Sie mit dem Codelab fortfahren.

In der Datei package.json sind bereits zwei erforderliche Abhängigkeiten aufgelistet: Firebase SDK for Cloud Functions und Firebase Admin SDK. Wenn Sie sie lokal installieren möchten, rufen Sie den Ordner functions auf und führen Sie Folgendes aus:

npm install

Sehen wir uns nun die index.js-Datei an:

index.js

/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 * ...
 */

// TODO(DEVELOPER): Import the Cloud Functions for Firebase and the Firebase Admin modules here.

// TODO(DEVELOPER): Write the addWelcomeMessage Function here.

// TODO(DEVELOPER): Write the blurImages Function here.

// TODO(DEVELOPER): Write the sendNotification Function here.

Wir importieren die erforderlichen Module und schreiben dann drei Funktionen anstelle der TODOs. Beginnen wir mit dem Importieren der erforderlichen Node-Module.

7. Cloud Functions- und Firebase Admin-Module importieren

Für dieses Codelab sind zwei Module erforderlich: Mit firebase-functions können Sie Cloud Functions-Trigger und ‑Protokolle schreiben. Mit firebase-admin können Sie die Firebase-Plattform auf einem Server mit Administratorzugriff verwenden, um Aktionen wie das Schreiben in Cloud Firestore oder das Senden von FCM-Benachrichtigungen auszuführen.

Ersetzen Sie in der Datei index.js die erste TODO durch Folgendes:

index.js

/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 * ...
 */

// Import the Firebase SDK for Google Cloud Functions.
const functions = require('firebase-functions');
// Import and initialize the Firebase Admin SDK.
const admin = require('firebase-admin');
admin.initializeApp();

// TODO(DEVELOPER): Write the addWelcomeMessage Function here.

// TODO(DEVELOPER): Write the blurImages Function here.

// TODO(DEVELOPER): Write the sendNotification Function here.

Das Firebase Admin SDK kann automatisch konfiguriert werden, wenn es in einer Cloud Functions-Umgebung oder in anderen Google Cloud Platform-Containern bereitgestellt wird. Das passiert, wenn wir admin.initializeApp() ohne Argumente aufrufen.

Fügen Sie jetzt eine Funktion hinzu, die ausgeführt wird, wenn sich ein Nutzer zum ersten Mal in der Chat-App anmeldet, und eine Chatnachricht, um den Nutzer willkommen zu heißen.

8. Neue Nutzer willkommen heißen

Struktur der Chatnachrichten

Nachrichten, die im Chatfeed von Friendly Chat gepostet wurden, werden unter Cloud Firestore gespeichert. Sehen wir uns die Datenstruktur an, die wir für eine Nachricht verwenden. Posten Sie dazu eine neue Chatnachricht, die „Hallo Welt“ lautet:

11f5a676fbb1a69a.png

Das sollte dann so aussehen:

fe6d1c020d0744cf.png

Klicken Sie in der Firebase Console im Bereich Build auf Firestore-Datenbank. Sie sollten die Sammlung „Nachrichten“ und ein Dokument mit der von Ihnen verfassten Nachricht sehen:

442c9c10b5e2b245.png

Wie Sie sehen, werden Chatnachrichten in Cloud Firestore als Dokument mit den Attributen name, profilePicUrl, text und timestamp in der Sammlung messages gespeichert.

Willkommensnachrichten hinzufügen

Mit der ersten Cloud Functions-Funktion wird eine Willkommensnachricht für neue Nutzer in den Chat eingefügt. Dazu können wir den Trigger functions.auth().onCreate verwenden, der immer dann ausgeführt wird, wenn sich ein Nutzer zum ersten Mal in der Firebase App anmeldet. Fügen Sie die Funktion addWelcomeMessages in die Datei index.js ein:

index.js

// Adds a message that welcomes new users into the chat.
exports.addWelcomeMessages = functions.auth.user().onCreate(async (user) => {
  functions.logger.log('A new user signed in for the first time.');
  const fullName = user.displayName || 'Anonymous';

  // Saves the new welcome message into the database
  // which then displays it in the FriendlyChat clients.
  await admin.firestore().collection('messages').add({
    name: 'Firebase Bot',
    profilePicUrl: '/images/firebase-logo.png', // Firebase logo
    text: `${fullName} signed in for the first time! Welcome!`,
    timestamp: admin.firestore.FieldValue.serverTimestamp(),
  });
  functions.logger.log('Welcome message written to database.');
});

Dadurch, dass diese Funktion dem spezifischen Objekt exports hinzugefügt wird, kann außerhalb der aktuellen Datei darauf zugegriffen werden. Dies ist für Cloud Functions erforderlich.

In der oben genannten Funktion fügen wir eine neue Willkommensnachricht hinzu, die vom „Firebase-Bot“ mithilfe der Methode Hinzufügen in die Liste der Chatnachrichten gepostet wird. Dazu verwenden wir die Methode add in der Sammlung messages in Cloud Firestore, in der die Nachrichten des Chats gespeichert werden.

Da dies eine asynchrone Operation ist, müssen wir das Promise zurückgeben, das angibt, wann der Schreibvorgang in Cloud Firestore abgeschlossen ist, damit die Cloud Functions nicht zu früh ausgeführt werden.

Cloud Functions bereitstellen

Cloud Functions sind erst aktiv, nachdem Sie sie bereitgestellt haben. Führen Sie dazu folgenden Befehl in der Befehlszeile aus:

firebase deploy --only functions

Die Ausgabe der Konsole sollte so aussehen:

i  deploying functions
i  functions: ensuring necessary APIs are enabled...
⚠  functions: missing necessary APIs. Enabling now...
i  env: ensuring necessary APIs are enabled...
⚠  env: missing necessary APIs. Enabling now...
i  functions: waiting for APIs to activate...
i  env: waiting for APIs to activate...
✔  env: all necessary APIs are enabled
✔  functions: all necessary APIs are enabled
i  functions: preparing functions directory for uploading...
i  functions: packaged functions (X.XX KB) for uploading
✔  functions: functions folder uploaded successfully
i  starting release process (may take several minutes)...
i  functions: creating function addWelcomeMessages...
✔  functions[addWelcomeMessages]: Successful create operation. 
✔  functions: all functions deployed successfully!

✔  Deploy complete!

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

Funktion testen

Nachdem die Funktion bereitgestellt wurde, benötigen Sie einen Nutzer, der sich zum ersten Mal anmeldet.

  1. Öffnen Sie Ihre App im Browser mit der Hosting-URL (in Form von https://<project-id>.firebaseapp.com).
  2. Melden Sie sich als neuer Nutzer zum ersten Mal über die Schaltfläche Anmelden in Ihrer App an.

262535d1b1223c65.png

  1. Nach der Anmeldung sollte automatisch eine Willkommensnachricht angezeigt werden:

1c70e0d64b23525b.png

9. Bildermoderation

Nutzer können alle Arten von Bildern in den Chat hochladen. Es ist immer wichtig, anstößige Bilder zu moderieren, insbesondere auf öffentlichen sozialen Plattformen. In Friendly Chat werden die Bilder, die im Chat gepostet werden, in Cloud Storage-Buckets gespeichert.

Mit Cloud Functions-Funktionen können Sie neue Bilduploads erkennen. Verwenden Sie dazu den Trigger functions.storage().onFinalize. Er wird jedes Mal ausgeführt, wenn eine neue Datei in Cloud Storage hochgeladen oder modifiziert wurde.

So werden Bilder moderiert:

  1. Überprüfen Sie mithilfe der Cloud Vision API, ob das Bild als "Nicht jugendfrei" oder als "Gewaltverherrlichend" gekennzeichnet wurde.
  2. Wenn das Bild entsprechend markiert ist, laden Sie es in die laufende Functions-Instanz herunter.
  3. Machen Sie das Bild mithilfe der Weichzeichnen-Funktion von ImageMagick unkenntlich.
  4. Laden Sie das so bearbeitete Bild in Cloud Storage hoch.

Cloud Vision API aktivieren

Da wir in dieser Funktion die Google Cloud Vision API verwenden, müssen Sie die API in Ihrem Firebase-Projekt aktivieren. Klicken Sie auf diesen Link, wählen Sie Ihr Firebase-Projekt aus und aktivieren Sie die API:

5c77fee51ec5de49.png

Abhängigkeiten installieren

Zur Moderation von Bildern verwenden wir die Google Cloud Vision-Clientbibliothek für Node.js, @google-cloud/vision, um Bilder über die Cloud Vision API auszuführen und unangemessene Bilder zu erkennen.

Führen Sie den folgenden npm install --save-Befehl aus, um dieses Paket in Ihrer Cloud Functions App zu installieren. Sie müssen sich im Verzeichnis functions befinden.

npm install --save @google-cloud/vision@2.4.0

Dadurch wird das Paket lokal installiert und in der Datei package.json als Abhängigkeit deklariert.

Abhängigkeiten importieren und konfigurieren

Fügen Sie oben in der Datei index.js die folgenden Zeilen ein, um die installierten Abhängigkeiten und einige Node.js-Kernmodule (path, os und fs) zu importieren, die wir in diesem Abschnitt benötigen:

index.js

const Vision = require('@google-cloud/vision');
const vision = new Vision.ImageAnnotatorClient();
const {promisify} = require('util');
const exec = promisify(require('child_process').exec);

const path = require('path');
const os = require('os');
const fs = require('fs');

Da die Funktion in einer Google Cloud-Umgebung ausgeführt wird, müssen die Cloud Storage- und Cloud Vision-Bibliotheken nicht konfiguriert werden. Sie werden automatisch für die Verwendung Ihres Projekts konfiguriert.

Unangemessene Bilder erkennen

Sie verwenden den Cloud Functions-Trigger functions.storage.onChange. Damit wird Ihr Code ausgeführt, sobald eine Datei oder ein Ordner in einem Cloud Storage-Bucket erstellt oder geändert wurde. Fügen Sie die Funktion blurOffensiveImages der Datei index.js hinzu:

index.js

// Checks if uploaded images are flagged as Adult or Violence and if so blurs them.
exports.blurOffensiveImages = functions.runWith({memory: '2GB'}).storage.object().onFinalize(
    async (object) => {
      const imageUri = `gs://${object.bucket}/${object.name}`;
      // Check the image content using the Cloud Vision API.
      const batchAnnotateImagesResponse = await vision.safeSearchDetection(imageUri);
      const safeSearchResult = batchAnnotateImagesResponse[0].safeSearchAnnotation;
      const Likelihood = Vision.protos.google.cloud.vision.v1.Likelihood;
      if (Likelihood[safeSearchResult.adult] >= Likelihood.LIKELY ||
          Likelihood[safeSearchResult.violence] >= Likelihood.LIKELY) {
        functions.logger.log('The image', object.name, 'has been detected as inappropriate.');
        return blurImage(object.name);
      }
      functions.logger.log('The image', object.name, 'has been detected as OK.');
    });

Beachten Sie, dass wir einige Konfigurationen der Cloud Functions-Instanz hinzugefügt haben, die die Funktion ausführen wird. Mit .runWith({memory: '2GB'}) wird angefordert, dass die Instanz statt des Standardwerts 2 GB Arbeitsspeicher erhält, da diese Funktion speicherintensiv ist.

Wenn die Funktion ausgelöst wird, wird das Bild über die Cloud Vision API ausgeführt, um gewaltverherrlichende oder nicht jugendfreie Inhalte zu erkennen. Wenn das Bild anhand dieser Kriterien als unangemessen erkannt wird, wird es unkenntlich gemacht. Das geschieht mithilfe der Funktion blurImage, wie wir gleich sehen werden.

Bild unkenntlich machen

Fügen Sie der Datei index.js die folgende blurImage-Funktion hinzu:

index.js

// Blurs the given image located in the given bucket using ImageMagick.
async function blurImage(filePath) {
  const tempLocalFile = path.join(os.tmpdir(), path.basename(filePath));
  const messageId = filePath.split(path.sep)[1];
  const bucket = admin.storage().bucket();

  // Download file from bucket.
  await bucket.file(filePath).download({destination: tempLocalFile});
  functions.logger.log('Image has been downloaded to', tempLocalFile);
  // Blur the image using ImageMagick.
  await exec(`convert "${tempLocalFile}" -channel RGBA -blur 0x24 "${tempLocalFile}"`);
  functions.logger.log('Image has been blurred');
  // Uploading the Blurred image back into the bucket.
  await bucket.upload(tempLocalFile, {destination: filePath});
  functions.logger.log('Blurred image has been uploaded to', filePath);
  // Deleting the local file to free up disk space.
  fs.unlinkSync(tempLocalFile);
  functions.logger.log('Deleted local file.');
  // Indicate that the message has been moderated.
  await admin.firestore().collection('messages').doc(messageId).update({moderated: true});
  functions.logger.log('Marked the image as moderated in the database.');
}

In der obigen Funktion wird die Binärdatei des Bilds aus Cloud Storage heruntergeladen. Anschließend wird die Datei mithilfe des Tools convert von ImageMagick unkenntlich gemacht und die so bearbeitete Version wird wieder in das Storage-Bucket hochgeladen. Als Nächstes löschen wir die Datei auf der Cloud Functions-Instanz, um Speicherplatz freizugeben. Dies ist notwendig, da dieselbe Cloud Functions-Instanz wiederverwendet werden kann und bei nicht bereinigten Dateien der Speicherplatz aufgebraucht werden könnte. Zuletzt wird der Chatnachricht ein boolescher Wert hinzugefügt, der angibt, dass das Bild moderiert wurde. Dadurch wird eine Aktualisierung der Nachricht beim Client ausgelöst.

Funktion implementieren

Die Funktion ist erst nach der Bereitstellung aktiv. Führen Sie in der Befehlszeile firebase deploy --only functions aus:

firebase deploy --only functions

Die Ausgabe der Konsole sollte so aussehen:

i  deploying functions
i  functions: ensuring necessary APIs are enabled...
✔  functions: all necessary APIs are enabled
i  functions: preparing functions directory for uploading...
i  functions: packaged functions (X.XX KB) for uploading
✔  functions: functions folder uploaded successfully
i  starting release process (may take several minutes)...
i  functions: updating function addWelcomeMessages...
i  functions: creating function blurOffensiveImages...
✔  functions[addWelcomeMessages]: Successful update operation.
✔  functions[blurOffensiveImages]: Successful create operation.
✔  functions: all functions deployed successfully!

✔  Deploy complete!

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

Funktion testen

Wenn die Funktion bereitgestellt ist, tun Sie Folgendes:

  1. Öffnen Sie Ihre App im Browser mit der Hosting-URL (in Form von https://<project-id>.firebaseapp.com).
  2. Laden Sie nach der Anmeldung ein Bild hoch: 4db9fdab56703e4a.png
  3. Wählen Sie das beste anstößige Bild aus, das Sie hochladen möchten (oder verwenden Sie diesen fleischfressenden Zombie). Nach kurzer Zeit sollte Ihr Post mit einer unkenntlich gemachten Version des Bilds aktualisiert werden: 83dd904fbaf97d2b.png

10. Benachrichtigungen über neue Nachrichten

In diesem Abschnitt fügen Sie eine Cloud Functions-Funktion hinzu, mit der Chatteilnehmer über neue Nachrichten informiert werden.

Mit Firebase Cloud Messaging (FCM) können Sie zuverlässig plattformübergreifend Benachrichtigungen an Nutzer senden. Dafür benötigen Sie das FCM-Gerätetoken des Nutzers. Die Chat-Web-App, die wir verwenden, ruft bereits Gerätetokens von Nutzern ab, wenn sie die App zum ersten Mal auf einem neuen Gerät oder in einem neuen Browser öffnen. Diese Tokens werden in Cloud Firestore in der Sammlung fcmTokens gespeichert.

Wenn Sie wissen möchten, wie Sie FCM-Gerätetokens in einer Webanwendung abrufen, können Sie das Firebase Web Codelab durchgehen.

Benachrichtigungen senden

Um zu erkennen, wann neue Nachrichten gepostet wurden, verwenden Sie den Cloud Functions-Trigger functions.firestore.document().onCreate. Damit wird Ihr Code ausgeführt, wenn ein neues Objekt unter einem festgelegten Pfad in Cloud Firestore erstellt wurde. Fügen Sie die Funktion sendNotifications der Datei index.js hinzu:

index.js

// Sends a notifications to all users when a new message is posted.
exports.sendNotifications = functions.firestore.document('messages/{messageId}').onCreate(
  async (snapshot) => {
    // Notification details.
    const text = snapshot.data().text;
    const payload = {
      notification: {
        title: `${snapshot.data().name} posted ${text ? 'a message' : 'an image'}`,
        body: text ? (text.length <= 100 ? text : text.substring(0, 97) + '...') : '',
        icon: snapshot.data().profilePicUrl || '/images/profile_placeholder.png',
        click_action: `https://${process.env.GCLOUD_PROJECT}.firebaseapp.com`,
      }
    };

    // Get the list of device tokens.
    const allTokens = await admin.firestore().collection('fcmTokens').get();
    const tokens = [];
    allTokens.forEach((tokenDoc) => {
      tokens.push(tokenDoc.id);
    });

    if (tokens.length > 0) {
      // Send notifications to all tokens.
      const response = await admin.messaging().sendToDevice(tokens, payload);
      await cleanupTokens(response, tokens);
      functions.logger.log('Notifications have been sent and tokens cleaned up.');
    }
  });

In der oben genannten Funktion werden alle Gerätetokens der Nutzer aus der Cloud Firestore-Datenbank abgerufen und mithilfe der Funktion admin.messaging().sendToDevice wird an jeden dieser Nutzer eine Benachrichtigung gesendet.

Tokens löschen

Zum Schluss entfernen wir die nicht mehr gültigen Tokens. Das ist der Fall, wenn das Token, das wir einmal vom Nutzer erhalten haben, vom Browser oder Gerät nicht mehr verwendet wird. Das ist beispielsweise der Fall, wenn der Nutzer die Berechtigung für Benachrichtigungen für die Browsersitzung widerrufen hat. Fügen Sie dazu der Datei index.js die folgende cleanupTokens-Funktion hinzu:

index.js

// Cleans up the tokens that are no longer valid.
function cleanupTokens(response, tokens) {
 // For each notification we check if there was an error.
 const tokensDelete = [];
 response.results.forEach((result, index) => {
   const error = result.error;
   if (error) {
     functions.logger.error('Failure sending notification to', tokens[index], error);
     // Cleanup the tokens that are not registered anymore.
     if (error.code === 'messaging/invalid-registration-token' ||
         error.code === 'messaging/registration-token-not-registered') {
       const deleteTask = admin.firestore().collection('fcmTokens').doc(tokens[index]).delete();
       tokensDelete.push(deleteTask);
     }
   }
 });
 return Promise.all(tokensDelete);
}

Funktion implementieren

Die Funktion ist erst aktiv, nachdem Sie sie bereitgestellt haben. Führen Sie dazu den folgenden Befehl in der Befehlszeile aus:

firebase deploy --only functions

Die Ausgabe der Konsole sollte so aussehen:

i  deploying functions
i  functions: ensuring necessary APIs are enabled...
✔  functions: all necessary APIs are enabled
i  functions: preparing functions directory for uploading...
i  functions: packaged functions (X.XX KB) for uploading
✔  functions: functions folder uploaded successfully
i  starting release process (may take several minutes)...
i  functions: updating function addWelcomeMessages...
i  functions: updating function blurOffensiveImages...
i  functions: creating function sendNotifications...
✔  functions[addWelcomeMessages]: Successful update operation.
✔  functions[blurOffensiveImages]: Successful updating operation.
✔  functions[sendNotifications]: Successful create operation.
✔  functions: all functions deployed successfully!

✔  Deploy complete!

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

Funktion testen

  1. Öffnen Sie die App im Browser, nachdem die Funktion bereitgestellt wurde. Verwenden Sie dazu die Hosting-URL in Form von https://<project-id>.firebaseapp.com.
  2. Wenn Sie sich zum ersten Mal in der App anmelden, müssen Sie Benachrichtigungen zulassen, wenn Sie dazu aufgefordert werden: 8b9d0c66dc36153d.png
  3. Schließen Sie den Tab mit der Chat-App oder rufen Sie einen anderen Tab auf: Benachrichtigungen werden nur dann angezeigt, wenn die App im Hintergrund läuft. Wie Sie Nachrichten empfangen, wenn die App im Vordergrund läuft, erfahren Sie in der Dokumentation.
  4. Melden Sie sich mit einem anderen Browser oder einem Inkognitofenster in der App an und posten Sie eine Nachricht. Sie sollten daraufhin eine Benachrichtigung im ersten Browser erhalten: 45282ab12b28b926.png

11. Glückwunsch!

Sie haben das Firebase SDK for Cloud Functions verwendet und einer Chat-App serverseitig Komponenten hinzugefügt.

Behandelte Themen

  • Cloud Functions-Funktionen mithilfe des Firebase SDK for Cloud Functions erstellen
  • Cloud Functions basierend auf Auth, Cloud Storage und Cloud Firestore-Ereignissen auslösen
  • Einer Web-App Unterstützung von Firebase Cloud Messaging hinzufügen
  • Cloud Functions-Funktionen mithilfe der Firebase CLI bereitstellen

Nächste Schritte

Weitere Informationen