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

1. Omówienie

W tym laboratorium kodu dowiesz się, jak za pomocą Cloud Functions for Firebase dodać do aplikacji czatu na stronie internetowej funkcję wysyłania powiadomień do użytkowników tej aplikacji.

3b1284f5144b54f6.png

Czego się nauczysz

  • Utwórz funkcję Google Cloud za pomocą pakietu SDK Firebase.
  • Aktywuj funkcje Cloud Functions na podstawie zdarzeń Auth, Cloud Storage i Cloud Firestore.
  • Dodaj do aplikacji internetowej obsługę Komunikacji w chmurze Firebase.

Czego potrzebujesz

  • karta kredytowa, Cloud Functions dla Firebase wymaga abonamentu Blaze w Firebase, co oznacza, że musisz włączyć płatności w swoim projekcie Firebase za pomocą karty kredytowej.
  • IDE lub edytor tekstu, np. WebStorm, Atom lub Sublime.
  • Terminal do uruchamiania poleceń powłoki z zainstalowaną wersją NodeJS 9.
  • przeglądarkę, np. Chrome;
  • Przykładowy kod. W tym celu wykonaj czynności opisane w następnym kroku.

2. Pobieranie przykładowego kodu

Sklonuj repozytorium GitHub z poziomu wiersza poleceń:

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

Importowanie aplikacji startowej

Za pomocą IDE otwórz lub zaimportuj katalog android_studio_folder.pngcloud-functions-start z katalogu przykładowego kodu. Ten katalog zawiera kod początkowy dla Codelab, który składa się z w pełni funkcjonalnej aplikacji internetowej Google Chat.

3. Tworzenie projektu Firebase i konfigurowanie aplikacji

Utwórz projekt

konsoli Firebase kliknij Dodaj projekt i nazwij go FriendlyChat.

Kliknij Utwórz projekt.

Przejdź na abonament Blaze

Aby korzystać z Cloud Functions dla Firebase i Cloud Storage dla Firebase, musisz mieć projekt Firebase w abonamentem Blaze (płatność według wykorzystania), co oznacza, że jest on połączony z kontem płatności Google Cloud.

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

Wszystkie projekty Firebase, w tym te korzystające z abonamentu Blaze, nadal mają dostęp do bezpłatnych limitów wykorzystania Cloud Functions. Kroki opisane w tym laboratorium kodu mieszczą się w limitach poziomu bezpłatnego. Zobaczysz jednak niewielkie opłaty (około 0,03 USD) z Cloud Storage, który jest używany do hostowania obrazów kompilacji Cloud Functions.

Aby przenieść projekt na abonament Blaze:

  1. W konsoli Firebase wybierz uaktualnienie abonamentu.
  2. Wybierz pakiet Blaze. Postępuj zgodnie z instrukcjami wyświetlanymi na ekranie, aby połączyć konto rozliczeniowe Cloud z projektem.
    Jeśli w ramach tego przejścia na wyższy poziom abonamentu musisz utworzyć konto rozliczeniowe Cloud, konieczne może być powrót do procesu przejścia w konsoli Firebase, aby go dokończyć.

Włączanie uwierzytelniania Google

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

W Konsoli Firebase otwórz sekcję Kompilacja > Uwierzytelnianie > karta Metoda logowania (lub kliknij tutaj, aby przejść do tej sekcji). Następnie włącz usługę Google jako dostawcę logowania 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ć publiczną nazwę aplikacji na Friendly Chat:

8290061806aacb46.png

Konfigurowanie Cloud Storage dla Firebase

Aplikacja przesyła zdjęcia za pomocą Cloud Storage.

Oto jak skonfigurować Cloud Storage dla Firebase w projekcie Firebase:

  1. W panelu po lewej stronie konsoli Firebase rozwiń Kompilacja, a potem kliknij Storage.
  2. Kliknij Rozpocznij.
  3. Wybierz lokalizację domyślnego zasobnika Storage.
    Zasobniki w regionach US-WEST1, US-CENTRAL1 i US-EAST1 mogą korzystać z poziomu Always Free w Google Cloud Storage. Zasobniki w innych lokalizacjach podlegają cennikom i zasadom korzystania z Google Cloud Storage.
  4. Kliknij Rozpocznij w trybie testowym. Przeczytaj wyłączenie odpowiedzialności dotyczące reguł zabezpieczeń.
    Nie rozpowszechniaj ani nie udostępniaj publicznie aplikacji bez dodania reguł zabezpieczeń dla zasobnika Storage.
  5. Kliknij Utwórz.

Dodawanie aplikacji internetowej

W konsoli Firebase dodaj aplikację internetową. Aby to zrobić, kliknij Ustawienia projektu i przewiń w dół do opcji Dodaj aplikację. Wybierz internet jako platformę i zaznacz pole wyboru konfiguracji Hostingu Firebase, a następnie zarejestruj aplikację i kliknij Dalej, aby wykonać pozostałe czynności, a 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 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:

firebase --version

Upewnij się, że wersja wiersza poleceń Firebase jest nowsza niż 4.0.0, aby zawierała wszystkie najnowsze funkcje wymagane przez Cloud Functions. Jeśli nie, uruchom npm install -g firebase-tools, aby przejść na nowszą wersję, jak pokazano powyżej.

Autoryzuj wiersz poleceń Firebase, wykonując:

firebase login

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

firebase use --add

Następnie wybierz identyfikator projektu i postępuj zgodnie z instrukcjami. Gdy pojawi się odpowiedni komunikat, możesz wybrać dowolny alias, np. 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 usłudze hostingu Firebase, korzystając z:

firebase deploy --except functions

Dane wyjściowe konsoli powinny wyglądać tak:

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ą

Ostatni wiersz powinien zawierać adres URL hostingu. Aplikacja internetowa powinna być teraz dostępna pod tym adresem URL, który powinien mieć format https://<project-id>.firebaseapp.com. Otwórz ją. Powinien wyświetlić się interfejs aplikacji do czatu.

Zaloguj się w aplikacji, korzystając z przycisku LOGOWANIE Z GOOGLE. Możesz dodawać wiadomości i publikować zdjęcia:

3b1284f5144b54f6.png

Jeśli logujesz się w aplikacji po raz pierwszy w nowej przeglądarce, upewnij się, że zezwalasz na powiadomienia, gdy pojawi się taka prośba: 8b9d0c66dc36153d.png

Musimy później włączyć powiadomienia.

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

e926868b0546ed71.png

Dodamy teraz kilka funkcji, korzystając z pakietu SDK Firebase dla Cloud Functions.

6. Katalog funkcji

Cloud Functions umożliwia łatwe uruchamianie kodu w chmurze bez konieczności konfigurowania serwera. Pokażę Ci, jak tworzyć funkcje reagujące na zdarzenia z Bazy danych Firebase Auth, Cloud Storage i Firebase Firestore. Zacznijmy od uwierzytelniania.

Gdy używasz pakietu SDK Firebase do Cloud Functions, kod funkcji będzie się znajdować w katalogu functions (domyślnie). Kod funkcji jest też aplikacją Node.js, dlatego wymaga pliku package.json, który zawiera informacje o aplikacji i wypisuje zależności.

Aby ułatwić Ci pracę, utworzyliśmy już plik functions/index.js, w którym znajdzie się Twój kod. Możesz go sprawdzić, zanim przejdziesz dalej.

cd functions
ls

Jeśli nie znasz jeszcze Node.js, warto dowiedzieć się więcej o tym narzędziu, zanim przejdziesz do dalszej części tego ćwiczenia.

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

npm install

Przyjrzyjmy się teraz plikowi index.js:

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 napiszemy 3 funkcje zamiast TODO. Zacznijmy od zaimportowania wymaganych modułów Node.

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

W tym ćwiczeniu będziesz potrzebować 2 modułów: firebase-functions umożliwia pisanie wyzwalaczy i logów Cloud Functions, a firebase-admin – używanie platformy Firebase na serwerze z dostępem administracyjnym do wykonywania takich działań jak zapisywanie w Cloud Firestore czy wysyłanie powiadomień FCM.

W pliku index.js zastąp pierwszy element TODO tym:

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 SDK Firebase Admin można skonfigurować automatycznie podczas wdrażania w środowisku Cloud Functions lub innych kontenerach Google Cloud Platform. Dzieje się to, gdy wywołujemy admin.initializeApp() bez argumentów.

Teraz dodamy funkcję, która będzie działać, gdy użytkownik po raz pierwszy zaloguje się w aplikacji czatu. Dodamy też wiadomość powitalną.

8. Powitanie nowych użytkowników

Struktura wiadomości na czacie

Wiadomości publikowane w strumieniach czatu FriendlyChat są przechowywane w Cloud Firestore. Przyjrzyjmy się strukturze danych, której używamy do wiadomości. Aby to zrobić, opublikuj nową wiadomość w czacie z tekstem „Hello World”:

11f5a676fbb1a69a.png

Powinien on wyglądać tak:

fe6d1c020d0744cf.png

W konsoli Firebase w sekcji Kompilacja kliknij Baza danych Firestore. Powinna pojawić się kolekcja wiadomości i 1 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, texttimestamp dodanymi do kolekcji messages.

Dodawanie wiadomości powitalnych

Pierwsza funkcja Cloud Functions dodaje do czatu wiadomość powitalną dla nowych użytkowników. W tym celu możesz użyć wyzwalacza functions.auth().onCreate, który uruchamia funkcję za każdym razem, gdy użytkownik po raz pierwszy loguje się w aplikacji Firebase. Dodaj funkcję addWelcomeMessages do pliku index.js:

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 to sposób, w jaki Node udostępnia funkcję poza bieżącym plikiem. Jest to wymagane w przypadku funkcji w Cloud Functions.

W ramach tej funkcji do listy wiadomości na czacie dodajemy nową wiadomość powitalną opublikowaną przez „Firebase Bot”. Wykorzystujemy do tego metodę add w zbiorze messages w Cloud Firestore, w którym są przechowywane wiadomości czatu.

Ponieważ jest to operacja asynchroniczna, musimy zwrócić obietnice wskazującą, kiedy Cloud Firestore zakończyło zapisywanie, aby funkcje Cloud Functions nie zostały wykonane zbyt wcześnie.

Wdrażanie funkcji w Cloud Functions

Funkcje Cloud Functions będą aktywne dopiero po ich wdrożeniu. Aby to zrobić, uruchom w wierszu poleceń to polecenie:

firebase deploy --only functions

Dane wyjściowe konsoli powinny wyglądać tak:

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 wdrożeniu funkcji musisz mieć użytkownika, który zaloguje się po raz pierwszy.

  1. Otwórz aplikację w przeglądarce, korzystając z adresu URL hostingu (w formie https://<project-id>.firebaseapp.com).
  2. W przypadku nowego użytkownika zaloguj się po raz pierwszy w aplikacji, używając przycisku Zaloguj się.

262535d1b1223c65.png

  1. Po zalogowaniu powinien automatycznie wyświetlić się komunikat powitalny:

1c70e0d64b23525b.png

9. Moderowanie obrazów

Użytkownicy mogą przesyłać do czatu wszystkie rodzaje obrazów, dlatego ważne jest, aby moderować obraźliwe obrazy, zwłaszcza na publicznych platformach społecznościowych. W usłudze FriendlyChat obrazy publikowane w czacie są przechowywane w zasobnikach Cloud Storage.

W Cloud Functions możesz wykrywać nowe przesłane obrazy za pomocą wyzwalacza functions.storage().onFinalize. Skrypt będzie uruchamiany za każdym razem, gdy nowy plik zostanie przesłany lub zmodyfikowany w Cloud Storage.

Aby moderować obrazy, wykonamy te czynności:

  1. Za pomocą Cloud Vision API sprawdź, czy obraz został oznaczony jako przeznaczony dla dorosłych lub zawierający przemoc.
  2. Jeśli obraz został oznaczony, pobierz go w uruchomionej instancji Functions.
  3. Rozmycie obrazu za pomocą ImageMagick.
  4. Prześlij rozmyty obraz do Cloud Storage.

Włączanie interfejsu Cloud Vision API

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

5c77fee51ec5de49.png

Instalowanie zależności

Do moderowania obrazów użyjemy biblioteki klienta Google Cloud Vision dla Node.js @google-cloud/vision, aby przeprowadzić analizę obrazów za pomocą interfejsu Cloud Vision API w celu wykrycia nieodpowiednich obrazów.

Aby zainstalować ten pakiet w aplikacji Cloud Functions, uruchom to polecenie npm install --save. Pamiętaj, aby wykonać tę czynność 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ć zainstalowane zależności i niektóre podstawowe moduły Node.js (path, osfs), których będziemy potrzebować w tej sekcji, dodaj te wiersze na początku pliku index.js:

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

Funkcja będzie działać w środowisku Google Cloud, więc nie musisz konfigurować bibliotek Cloud Storage i Cloud Vision: zostaną one skonfigurowane automatycznie pod kątem Twojego projektu.

Wykrywanie nieodpowiednich obrazów

Użyjesz wyzwalacza functions.storage.onChange Cloud Functions, który uruchamia kod, gdy tylko plik lub folder zostanie utworzony lub zmodyfikowany w zasobniku Cloud Storage. Dodaj funkcję blurOffensiveImages do pliku index.js:

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

Pamiętaj, że dodaliśmy konfigurację instancji Cloud Functions, która będzie wykonywać funkcję. W przypadku funkcji .runWith({memory: '2GB'}) prosimy o przydzielenie instancji 2 GB pamięci zamiast domyślnej ilości, ponieważ ta funkcja jest bardzo pamięciochłonna.

Gdy funkcja zostanie wywołana, obraz zostanie przetworzony przez interfejs Cloud Vision API, aby wykryć, czy został oznaczony jako przeznaczony dla dorosłych lub czy zawiera przemoc. Jeśli na podstawie tych kryteriów obraz zostanie uznany za nieodpowiedni, rozmyje się go, co zostanie wykonane za pomocą funkcji blurImage, którą omówimy w dalszej części.

Rozmycie obrazu

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

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 funkcji powyżej binarny obraz jest pobierany z Cloud Storage. Następnie obraz jest rozmyty za pomocą narzędzia convert ImageMagick, a rozmyta wersja jest ponownie przesyłana do zasobnika Storage. 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 użyta, a jeśli nie usuniemy plików, może zabraknąć miejsca na dysku. Na koniec dodamy do wiadomości na czacie wartość logiczną wskazującą, że obraz został zmoderowany. Spowoduje to odświeżenie wiadomości na kliencie.

Wdrażanie funkcji

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

firebase deploy --only functions

Dane wyjściowe konsoli powinny wyglądać tak:

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 wdrożeniu funkcji:

  1. Otwórz aplikację w przeglądarce, korzystając z adresu URL hostingu (w formie https://<project-id>.firebaseapp.com).
  2. Po zalogowaniu się w aplikacji prześlij obraz: 4db9fdab56703e4a.png
  3. Wybierz najbardziej obraźliwy obraz do przesłania (możesz też użyć tego zombie żywiącego się ludzkim mięsem). Po kilku chwilach Twój post powinien zostać odświeżony z rozmytą wersją obrazu: 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, gdy zostanie opublikowana nowa wiadomość.

Korzystając z usługi Komunikacja 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 do czatu zbiera już tokeny urządzeń od użytkowników, gdy 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 pobrać tokeny urządzeń FCM w aplikacji internetowej, skorzystaj z Codelab Firebase na potrzeby internetu.

Wysyłanie powiadomień

Aby wykrywać publikowanie nowych wiadomości, użyjesz aktywatora funkcji w Cloud Functions functions.firestore.document().onCreate, który uruchamia kod po utworzeniu nowego obiektu w Cloud Firestore pod podaną ścieżką. Dodaj funkcję sendNotifications do pliku index.js:

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 powyżej funkcji zbieramy wszystkie tokeny urządzeń użytkowników z bazy danych Cloud Firestore i wysyłamy powiadomienie do każdego z nich za pomocą funkcji admin.messaging().sendToDevice.

Czyszczenie tokenów

Na koniec chcemy usunąć tokeny, które nie są już ważne. Dzieje się tak, gdy token, który otrzymaliśmy od użytkownika, nie jest już używany przez przeglądarkę lub urządzenie. Może się tak zdarzyć, jeśli użytkownik cofnie zgodę na wyświetlanie powiadomień w sesji przeglądarki. Aby to zrobić, dodaj do pliku index.js tę funkcję cleanupTokens:

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ć, wykonaj w wierszu poleceń to polecenie:

firebase deploy --only functions

Dane wyjściowe konsoli powinny wyglądać tak:

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 pomyślnym wdrożeniu funkcji otwórz aplikację w przeglądarce, korzystając z adresu URL hostingu (w formie https://<project-id>.firebaseapp.com).
  2. Jeśli logujesz się w aplikacji po raz pierwszy, zezwól na powiadomienia, gdy pojawi się taka prośba: 8b9d0c66dc36153d.png
  3. Zamknij kartę aplikacji do czatu lub wyświetl inną kartę: powiadomienia będą wyświetlane tylko wtedy, gdy aplikacja jest na drugim planie. Jeśli chcesz dowiedzieć się, jak odbierać wiadomości, gdy aplikacja jest na pierwszym planie, zapoznaj się z naszą dokumentacją.
  4. Zaloguj się w innej przeglądarce (lub w oknie incognito) i opublikuj wiadomość. W pierwszej przeglądarce powinno pojawić się powiadomienie: 45282ab12b28b926.png

11. Gratulacje!

Użyj pakietu SDK Firebase do funkcji Cloud Functions i dodaj do aplikacji do czatu komponenty po stronie serwera.

Omówione zagadnienia

  • tworzenie funkcji Cloud Functions za pomocą pakietu SDK Firebase dla Cloud Functions;
  • Aktywuj funkcje Cloud Functions na podstawie zdarzeń Auth, Cloud Storage i Cloud Firestore.
  • Dodaj do aplikacji internetowej obsługę Komunikacji w chmurze Firebase.
  • wdrażać funkcje Cloud Functions za pomocą wiersza poleceń Firebase;

Następne kroki

Więcej informacji