Wysyłanie powiadomień z aplikacji internetowej przy użyciu Komunikacji w chmurze i Cloud Functions

1. Omówienie

Z tego ćwiczenia w programie dowiesz się, jak za pomocą Cloud Functions dla Firebase dodać funkcje do aplikacji internetowej do obsługi czatu przez wysyłanie powiadomień do użytkowników tej aplikacji.

3b1284f5144b54f6.png

Czego się nauczysz

  • Tworzenie funkcji w Google Cloud Functions za pomocą pakietu SDK Firebase.
  • Aktywowanie funkcji w Cloud Functions na podstawie zdarzeń uwierzytelniania, Cloud Storage i Cloud Firestore.
  • Dodaj obsługę Komunikacji w chmurze Firebase (FCM) do swojej aplikacji internetowej.

Czego potrzebujesz

  • kartę kredytową; Cloud Functions dla Firebase wymaga abonamentu Firebase Blaze, co oznacza, że w projekcie Firebase musisz włączyć płatności przy użyciu karty kredytowej.
  • Wybrany edytor IDE/tekst, np. WebStorm, Atom lub Sublime.
  • Terminal do uruchamiania poleceń powłoki z zainstalowanym środowiskiem NodeJS w wersji 9.
  • Przeglądarka, np. Chrome.
  • Przykładowy kod. Zobacz następny krok.

2. Pobieranie przykładowego kodu

Skopiuj repozytorium GitHub, korzystając z wiersza poleceń:

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

Zaimportuj aplikację startową

Za pomocą swojego IDE otwórz lub zaimportuj katalog android_studio_folder.pngcloud-functions-start z katalogu przykładowego kodu. Ten katalog zawiera kod początkowy do ćwiczenia w Codelabs, które obejmuje w pełni funkcjonalną aplikację internetową Google Chat.

3. Tworzenie projektu Firebase i konfigurowanie aplikacji

Utwórz projekt

W konsoli Firebase kliknij Dodaj projekt i nazwij go FriendsChat.

Kliknij Utwórz projekt.

Przechodzenie na abonament Blaze

Jeśli chcesz korzystać z Cloud Functions dla Firebase, przejdź na abonament Blaze. Wymaga to dodania karty kredytowej lub innego instrumentu płatniczego do konta Google Cloud.

Wszystkie projekty Firebase, w tym te w abonamencie Blaze, nadal mają dostęp do bezpłatnych limitów wykorzystania Cloud Functions. Kroki opisane w tym ćwiczeniu w Codelabs będą się mieścić w limitach wykorzystania na poziomie bezpłatnym. Możesz jednak zauważyć niewielkie opłaty (około 0, 03 USD) z usługi Cloud Storage używanej do hostowania obrazów kompilacji w Cloud Functions.

Jeśli nie masz dostępu do karty kredytowej lub nie chcesz dalej korzystać z abonamentu Blaze, rozważ skorzystanie z Pakietu emulatorów Firebase, który pozwoli Ci bezpłatnie emulować Cloud Functions na komputerze lokalnym.

Włącz uwierzytelnianie Google

Aby umożliwić użytkownikom logowanie się w aplikacji, użyjemy uwierzytelniania Google, które musi być włączone.

W konsoli Firebase otwórz sekcję Kompilacja > Authentication (Uwierzytelnianie) > Metoda logowania (lub kliknij tutaj, aby otworzyć tę stronę). Następnie włącz dostawcę logowania Google i kliknij Zapisz. Dzięki temu użytkownicy będą mogli logować się w aplikacji internetowej za pomocą swoich kont Google.

Możesz też ustawić przyjazną nazwę czatu jako publiczną nazwę aplikacji:

8290061806aacb46.png

Włącz Cloud Storage

Aplikacja używa Cloud Storage do przesyłania zdjęć. Aby włączyć Cloud Storage w projekcie Firebase, otwórz sekcję Miejsce na dane i kliknij przycisk Rozpocznij. Przejdź przez kolejne kroki. Dla lokalizacji w Cloud Storage pojawi się wartość domyślna do użycia. Następnie kliknij Gotowe.

Dodaj aplikację internetową

W konsoli Firebase dodaj aplikację internetową. Aby to zrobić, otwórz Ustawienia projektu i przewiń w dół do opcji Dodaj aplikację. Jako platformę wybierz Internet i zaznacz pole konfigurowania Hostingu Firebase, a następnie zarejestruj aplikację i kliknij Dalej, aby przejść do pozostałych kroków, na koniec kliknij Przejdź do konsoli.

4. Instalowanie interfejsu wiersza poleceń Firebase

Interfejs wiersza poleceń Firebase (CLI) umożliwia obsługę aplikacji internetowej lokalnie oraz wdrażanie aplikacji internetowej i funkcji w Cloud Functions.

Aby zainstalować lub uaktualnić interfejs wiersza poleceń, uruchom to polecenie npm:

npm -g install firebase-tools

Aby sprawdzić, czy interfejs wiersza poleceń został prawidłowo zainstalowany, otwórz konsolę i uruchom polecenie:

firebase --version

Upewnij się, że interfejs wiersza poleceń Firebase jest w wersji nowszej niż 4.0.0, aby zapewnić dostęp do wszystkich najnowszych funkcji wymaganych przez Cloud Functions. Jeśli nie, uruchom npm install -g firebase-tools, aby uaktualnić w podany wyżej sposób.

Autoryzuj interfejs wiersza poleceń Firebase, uruchamiając polecenie:

firebase login

Upewnij się, że jesteś w katalogu cloud-functions-start, a następnie skonfiguruj interfejs wiersza poleceń Firebase, aby używać projektu Firebase:

firebase use --add

Następnie wybierz identyfikator projektu i postępuj zgodnie z instrukcjami. Gdy pojawi się prośba, możesz wybrać dowolny alias, na przykład codelab.

5. Wdrażanie i uruchamianie aplikacji internetowej

Po zaimportowaniu i skonfigurowaniu projektu możesz uruchomić aplikację internetową po raz pierwszy. Otwórz okno terminala, przejdź do folderu cloud-functions-start i wdróż aplikację internetową w Hostingu Firebase za pomocą:

firebase deploy --except functions

Oto dane wyjściowe konsoli, które powinny Ci się wyświetlić:

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

Otwórz aplikację internetową

W ostatnim wierszu powinien znajdować się Hosting URL (Adres URL serwera). Aplikacja internetowa powinna być teraz wyświetlana z tego adresu URL, który powinien mieć postać https://<identyfikator-projektu>.firebaseapp.com. Otwórz go. Powinien wyświetlić się działający interfejs aplikacji do obsługi czatu.

Zaloguj się w aplikacji za pomocą przycisku ZALOGUJ SIĘ PRZEZ GOOGLE i dodaj wiadomości oraz obrazy:

3b1284f5144b54f6.png

Jeśli logujesz się w aplikacji po raz pierwszy w nowej przeglądarce, włącz powiadomienia, gdy pojawi się taka prośba: 8b9d0c66dc36153d.png

Powiadomienia będziemy musieli włączyć później.

Jeśli przypadkowo klikniesz Zablokuj, możesz zmienić to ustawienie, klikając przycisk 🔒 Bezpieczny po lewej stronie adresu URL w Chrome Omnibar i przełączając pasek obok opcji Powiadomienia:

e926868b0546ed71.png

Teraz dodamy pewne funkcje z wykorzystaniem pakietu SDK Firebase dla Cloud Functions.

6. Katalog funkcji

Dzięki Cloud Functions można łatwo tworzyć kod uruchamiany w chmurze bez konieczności konfigurowania serwera. Przeprowadzimy Cię przez proces tworzenia funkcji, które reagują na zdarzenia uwierzytelniania Firebase, Cloud Storage i zdarzeń bazy danych Firebase Firestore. Zacznijmy od Uwierzytelnianie.

Jeśli korzystasz z pakietu SDK Firebase dla Cloud Functions, Twój kod funkcji znajduje się domyślnie w katalogu functions. Kod funkcji to również aplikacja Node.js i dlatego wymaga tagu package.json, który zawiera pewne informacje o aplikacji i zawiera listę zależności.

Aby ułatwić Ci pracę, utworzyliśmy już plik functions/index.js, w którym znajduje się Twój kod. Przejrzyj ten plik, zanim przejdziesz dalej.

cd functions
ls

Jeśli nie znasz jeszcze Node.js, dowiedz się więcej na ten temat, zanim przejdziesz dalej do ćwiczenia w Codelabs.

Plik package.json zawiera już 2 wymagane zależności: pakiet SDK Firebase dla Cloud Functions i pakiet SDK Firebase Admin SDK. Aby zainstalować je lokalnie, przejdź do folderu functions i uruchom:

npm install

Spójrzmy teraz na plik index.js:

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

Zaimportujemy wymagane moduły, a potem w miejsce zadań do wykonania napiszemy 3 funkcje. Zacznijmy od zaimportowania wymaganych modułów węzłów.

7. Importowanie modułów Cloud Functions i Firebase Admin

W trakcie tego ćwiczenia w Codelabs będą wymagane 2 moduły: firebase-functions umożliwia zapisywanie wyzwalaczy i logów Cloud Functions, a firebase-admin umożliwia korzystanie z platformy Firebase na serwerze z dostępem administracyjnym do wykonywania działań takich jak zapisywanie w Cloud Firestore czy wysyłanie powiadomień FCM.

W pliku index.js zastąp pierwszy element TODO następującym:

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

Pakiet Firebase Admin SDK można skonfigurować automatycznie po wdrożeniu w środowisku Cloud Functions lub innych kontenerach Google Cloud Platform. Dzieje się tak, gdy wywołujemy admin.initializeApp() bez podania argumentów.

Teraz dodajmy funkcję uruchamianą po pierwszym zalogowaniu się użytkownika w aplikacji czatu oraz wiadomość powitalną użytkownika.

8. Przywitaj nowych użytkowników

Struktura wiadomości Google Chat

Wiadomości publikowane w kanale czatu FriendsChat są przechowywane w Cloud Firestore. Przyjrzyjmy się strukturze danych wiadomości. W tym celu opublikuj na czacie nową wiadomość o treści „Hello World”:

11f5a676fbb1a69a.png

Powinien wyglądać tak:

fe6d1c020d0744cf.png

W konsoli Firebase kliknij Baza danych Firestore w sekcji Tworzenie. Powinna być widoczna kolekcja wiadomości i jeden dokument zawierający napisaną przez Ciebie wiadomość:

442c9c10b5e2b245.png

Jak widać, wiadomości czatu są przechowywane w Cloud Firestore jako dokument z atrybutami name, profilePicUrl, text i timestamp dodanymi do kolekcji messages.

Dodawanie wiadomości powitalnych

Pierwsza funkcja w Cloud Functions dodaje wiadomość powitalną nowych użytkowników do czatu. Do tego możemy użyć reguły functions.auth().onCreate, która uruchamia funkcję za każdym razem, gdy użytkownik loguje się w aplikacji Firebase po raz pierwszy. Dodaj funkcję addWelcomeMessages do pliku index.js:

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

Dodanie tej funkcji do specjalnego obiektu exports pozwala Node zapewnić dostępność funkcji poza bieżącym plikiem i jest wymagane w Cloud Functions.

W funkcji powyżej dodajemy nową wiadomość powitalną opublikowaną przez „bota Firebase”. na listę wiadomości czatu. Używamy do tego metody add w kolekcji messages w Cloud Firestore, gdzie są przechowywane wiadomości czatu.

Ponieważ jest to operacja asynchroniczna, musimy zwrócić wartość Promise, która wskazuje, że Cloud Firestore zakończył zapis, aby funkcje w Cloud Functions nie były wykonywane zbyt wcześnie.

Wdrażanie funkcji w Cloud Functions

Funkcje w Cloud Functions będą aktywne dopiero po ich wdrożeniu. W tym celu uruchom polecenie w wierszu poleceń:

firebase deploy --only functions

Oto dane wyjściowe konsoli, które powinny Ci się wyświetlić:

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

Testowanie funkcji

Po pomyślnym wdrożeniu funkcji potrzebujesz użytkownika, który loguje się po raz pierwszy.

  1. Otwórz aplikację w przeglądarce, korzystając z adresu URL hostingu (w formacie https://<project-id>.firebaseapp.com).
  2. Jeśli jesteś nowym użytkownikiem, zaloguj się po raz pierwszy w aplikacji, klikając przycisk Zaloguj się.
  • Po zalogowaniu się w aplikacji możesz otworzyć Uwierzytelnianie konsoli Firebase i usunąć swoje konto z listy użytkowników. Następnie zaloguj się ponownie.

262535d1b1223c65.png

  1. Po zalogowaniu powinna wyświetlić się wiadomość powitalna:

1c70e0d64b23525b.png

9. Moderowanie obrazów

Użytkownicy mogą przesyłać na czacie wszelkiego rodzaju obrazy, dlatego ważne jest, aby moderować obraźliwe obrazy, zwłaszcza na publicznych platformach społecznościowych. Obrazy publikowane w FriendsChat, są przechowywane w Google Cloud Storage.

Dzięki Cloud Functions możesz wykrywać przesyłane nowe obrazy za pomocą aktywatora functions.storage().onFinalize. Będzie ono uruchamiane za każdym razem, gdy nowy plik zostanie przesłany lub zmodyfikowany w Cloud Storage.

Aby moderować obrazy, uruchomimy następujący proces:

  1. Za pomocą interfejsu Cloud Vision API sprawdź, czy obraz jest oznaczony jako „Dla dorosłych” lub „Przemoc”.
  2. Jeśli obraz został oznaczony, pobierz go do uruchomionej instancji Functions.
  3. Rozmyj obraz za pomocą narzędzia ImageMagick.
  4. Prześlij rozmyty obraz do Cloud Storage.

Włączanie Cloud Vision API

W tej funkcji będziemy korzystać z interfejsu Google Cloud Vision API, więc musisz go włączyć w swoim projekcie Firebase. Kliknij ten link, a potem wybierz projekt Firebase i włącz interfejs API:

5c77fee51ec5de49.png

Zainstaluj zależności

Do moderowania obrazów użyjemy biblioteki klienta Google Cloud Vision dla Node.js (@google-cloud/vision), która pozwala wykryć nieodpowiednie obrazy za pomocą interfejsu Cloud Vision API.

Aby zainstalować ten pakiet w aplikacji Cloud Functions, uruchom to polecenie npm install --save. Pamiętaj, by zrobić to z katalogu functions.

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

Spowoduje to zainstalowanie pakietu lokalnie i dodanie go jako zadeklarowanej zależności w pliku package.json.

Importowanie i konfigurowanie zależności

Aby zaimportować zależności, które zostały zainstalowane, i niektóre podstawowe moduły Node.js (path, os i fs), które są potrzebne w tej sekcji, dodaj na początku pliku index.js te wiersze:

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

Ponieważ Twoja funkcja będzie działać w środowisku Google Cloud, nie musisz konfigurować bibliotek Cloud Storage ani Cloud Vision – zostaną one skonfigurowane automatycznie do korzystania z Twojego projektu.

Wykrywanie nieodpowiednich obrazów

Będziesz używać aktywatora functions.storage.onChange w Cloud Functions, który uruchamia Twój kod zaraz po utworzeniu lub zmodyfikowaniu pliku lub folderu w zasobniku Cloud Storage. Dodaj funkcję blurOffensiveImages do pliku index.js:

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

Zwróć uwagę, że dodaliśmy konfigurację instancji Cloud Functions, w której zostanie uruchomiona funkcja. Zgodnie z zasadą .runWith({memory: '2GB'}) żądanie pamięci masowej wynosiło 2 GB instancji, a nie ustawienia domyślne, ponieważ ta funkcja wymaga dużej ilości pamięci.

Po aktywowaniu tej funkcji obraz jest uruchamiany przez interfejs Cloud Vision API w celu wykrycia, czy został oznaczony jako przeznaczony dla dorosłych lub przedstawiający przemoc. Jeśli obraz zostanie uznany za nieodpowiedni na podstawie tych kryteriów, zamazujemy go, co jest wykonywane za pomocą funkcji blurImage, jak zobaczymy poniżej.

Zamazywanie obrazu

Dodaj do pliku index.js tę funkcję blurImage:

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

W powyższej funkcji plik binarny obrazu jest pobierany z Cloud Storage. Następnie obraz zostaje zamazany za pomocą narzędzia convert firmy ImageMagick, a jego wersja jest ponownie przesyłana do zasobnika na dane. Następnie usuwamy plik z instancji Cloud Functions, aby zwolnić trochę miejsca na dysku. Robimy to, ponieważ ta sama instancja Cloud Functions może zostać ponownie wykorzystana, a jeśli pliki nie zostaną wyczyszczone, może zabraknąć miejsca na dysku. Na koniec dodajemy do wiadomości na czacie wartość logiczną wskazującą, że obraz został poddany moderacji, co spowoduje odświeżenie wiadomości w kliencie.

Wdrażanie funkcji

Funkcja będzie aktywna dopiero po wdrożeniu. W wierszu poleceń uruchom polecenie firebase deploy --only functions:

firebase deploy --only functions

Oto dane wyjściowe konsoli, które powinny Ci się wyświetlić:

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

Testowanie funkcji

Po udanym wdrożeniu funkcji:

  1. Otwórz aplikację w przeglądarce, korzystając z adresu URL hostingu (w formacie https://<project-id>.firebaseapp.com).
  2. Po zalogowaniu się w aplikacji prześlij obraz: 4db9fdab56703e4a.png
  3. Wybierz do przesłania najbardziej obraźliwe zdjęcie (lub użyj tego zjazdu zombie!), a po kilku chwilach post powinien zostać odświeżony z rozmytą wersją zdjęcia: 83dd904fbaf97d2b.png

10. Powiadomienia o nowych wiadomościach

W tej sekcji dodasz funkcję w Cloud Functions, która wysyła powiadomienia do uczestników czatu po opublikowaniu nowej wiadomości.

Dzięki Komunikacji w chmurze Firebase (FCM) możesz niezawodnie wysyłać powiadomienia do użytkowników na różnych platformach. Aby wysłać powiadomienie do użytkownika, musisz mieć jego token urządzenia FCM. Używana przez nas aplikacja internetowa czatu już zbiera tokeny urządzeń od użytkowników, którzy po raz pierwszy otwierają aplikację w nowej przeglądarce lub na nowym urządzeniu. Te tokeny są przechowywane w Cloud Firestore w kolekcji fcmTokens.

Jeśli chcesz dowiedzieć się, jak uzyskiwać tokeny urządzenia FCM dla aplikacji internetowej, skorzystaj z ćwiczeń internetowych Firebase.

Wysyłanie powiadomień

Do wykrywania nowych wiadomości będziesz używać aktywatora functions.firestore.document().onCreate w Cloud Functions, który uruchamia Twój kod po utworzeniu nowego obiektu w danej ścieżce Cloud Firestore. Dodaj funkcję sendNotifications do pliku index.js:

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

W funkcji powyżej zbieramy dane o wszystkich użytkownikach z bazy danych Cloud Firestore i wysyłanie do każdego z nich powiadomienia za pomocą funkcji admin.messaging().sendToDevice.

Czyszczenie tokenów

Na koniec chcemy usunąć tokeny, które straciły ważność. Dzieje się tak, gdy token, który kiedyś otrzymaliśmy od użytkownika, nie jest już używany przez przeglądarkę lub urządzenie. Dzieje się tak na przykład wtedy, gdy użytkownik unieważnił uprawnienie do wyświetlania powiadomień dotyczące sesji przeglądarki. Aby to zrobić, dodaj do pliku index.js tę funkcję cleanupTokens:

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

Wdrażanie funkcji

Funkcja będzie aktywna dopiero po wdrożeniu. Aby ją wdrożyć, uruchom to polecenie w wierszu poleceń:

firebase deploy --only functions

Oto dane wyjściowe konsoli, które powinny Ci się wyświetlić:

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

Testowanie funkcji

  1. Po wdrożeniu funkcji otwórz aplikację w przeglądarce, korzystając z adresu URL hostingu (w formacie https://<project-id>.firebaseapp.com).
  2. Jeśli logujesz się w aplikacji po raz pierwszy, włącz powiadomienia, gdy pojawi się taka prośba: 8b9d0c66dc36153d.png
  3. Zamknięcie karty aplikacji do obsługi czatu lub wyświetl inną kartę: powiadomienia pojawiają się tylko wtedy, gdy aplikacja działa w tle. Aby dowiedzieć się, jak odbierać wiadomości, gdy aplikacja działa na pierwszym planie, zapoznaj się z naszą dokumentacją.
  4. Korzystając z innej przeglądarki (lub okna incognito), zaloguj się w aplikacji i opublikuj wiadomość. Powiadomienie wyświetli się w pierwszej przeglądarce: 45282ab12b28b926.png

11. Gratulacje!

Udało Ci się wykorzystać pakiet SDK Firebase dla Cloud Functions i dodać komponenty po stronie serwera do aplikacji do obsługi czatu.

Omówione zagadnienia

  • Tworzenie funkcji w Cloud Functions za pomocą pakietu SDK Firebase dla Cloud Functions.
  • Aktywowanie funkcji w Cloud Functions na podstawie zdarzeń uwierzytelniania, Cloud Storage i Cloud Firestore.
  • Dodaj obsługę Komunikacji w chmurze Firebase (FCM) do swojej aplikacji internetowej.
  • Wdrażaj funkcje w Cloud Functions za pomocą interfejsu wiersza poleceń Firebase.

Następne kroki

Więcej informacji