Pierwsze kroki: pisanie, testowanie i wdrażanie pierwszych funkcji


Zacznij korzystać z Cloud Functions od tego samouczka. Zaczyna on od wymaganych zadań konfiguracyjnych i obejmuje tworzenie, testowanie i wdrażanie 2 powiązanych funkcji:

  • Funkcja dodawania wiadomości, która ujawnia adres URL, który akceptuje wartość tekstową i zapisuje ją w Cloud Firestore.
  • Funkcja „wielkie litery”, która uruchamia się przy zapisie w Cloud Firestore i przekształca tekst na wielkie litery.

W tym przykładzie wybraliśmy funkcje Cloud Firestore i aktywowane przez HTTP funkcje JavaScriptu, ponieważ te aktywatory działające w tle można dokładnie przetestować za pomocą Pakietu emulatorów lokalnych Firebase. Ten zestaw narzędzi obsługuje też aktywatory Bazy danych czasu rzeczywistego, PubSub, Uwierzytelnianie i HTTP. Inne typy aktywatorów działających w tle, takie jak aktywatory Zdalnej konfiguracji, TestLab i Analytics, można testować interaktywnie przy użyciu zbiorów narzędzi, które nie zostały opisane na tej stronie.

Poniższe sekcje tego samouczka zawierają informacje o krokach wymaganych do skompilowania, przetestowania i wdrożenia przykładu. Jeśli wolisz po prostu uruchomić kod i go sprawdzić, przejdź do sekcji Przeglądanie pełnego kodu przykładowego.

Utwórz projekt Firebase

  1. W konsoli Firebase kliknij Dodaj projekt.

    • Aby dodać zasoby Firebase do istniejącego projektu Google Cloud, wpisz nazwę projektu lub wybierz go z menu.

    • Aby utworzyć nowy projekt, wpisz nazwę projektu. Możesz też opcjonalnie edytować identyfikator projektu wyświetlany pod jego nazwą.

  2. Jeśli pojawi się taka prośba, przeczytaj i zaakceptuj warunki korzystania z Firebase.

  3. Kliknij Dalej.

  4. (Opcjonalnie) Skonfiguruj Google Analytics w swoim projekcie, by zapewnić optymalne działanie każdej z tych usług Firebase:

    Wybierz istniejące konto Google Analytics lub utwórz nowe.

    Jeśli utworzysz nowe konto, wybierz lokalizację raportowania Analytics, a następnie zaakceptuj w swoim projekcie ustawienia udostępniania danych i warunki korzystania z Google Analytics.

  5. Kliknij Utwórz projekt (lub Dodaj Firebase, jeśli używasz istniejącego projektu Google Cloud).

Firebase automatycznie udostępnia zasoby dla Twojego projektu Firebase. Po zakończeniu tego procesu wyświetli się strona przeglądu Twojego projektu Firebase w konsoli Firebase.

Skonfiguruj Node.js i interfejs wiersza poleceń Firebase

Aby zapisywać funkcje, potrzebujesz środowiska Node.js, a do wdrażania funkcji w środowisku wykonawczym Cloud Functions będziesz potrzebować interfejsu wiersza poleceń Firebase. Do instalowania Node.js i npm zalecamy użycie Menedżera wersji węzłów.

Po zainstalowaniu Node.js i npm zainstaluj interfejs wiersza poleceń Firebase za pomocą preferowanej metody. Aby zainstalować interfejs wiersza poleceń przy użyciu npm, użyj:

npm install -g firebase-tools

Spowoduje to zainstalowanie dostępnego globalnie polecenia Firebase. Jeśli polecenie nie powiedzie się, być może trzeba zmienić uprawnienia npm. Aby zaktualizować aplikację firebase-tools do najnowszej wersji, uruchom to samo polecenie ponownie.

Zainicjuj projekt

Gdy zainicjujesz pakiet Firebase SDK dla Cloud Functions, utworzysz pusty projekt zawierający zależności i minimalny przykładowy kod, a następnie wybierzesz typ Script lub JavaScript do tworzenia funkcji. Na potrzeby tego samouczka musisz też zainicjować Cloud Firestore.

Aby zainicjować projekt:

  1. Uruchom firebase login, aby zalogować się w przeglądarce i uwierzytelnić interfejs wiersza poleceń Firebase.
  2. Otwórz katalog projektu Firebase.
  3. Uruchom firebase init firestore. W tym samouczku po wyświetleniu prośby o reguły Firestore i pliki indeksu możesz zaakceptować wartości domyślne. Jeśli ta usługa nie była jeszcze używana w tym projekcie, musisz też wybrać tryb początkowy i lokalizację Firestore zgodnie z opisem w sekcji Pierwsze kroki z Cloud Firestore.
  4. Uruchom firebase init functions. Interfejs wiersza poleceń prosi o wybranie istniejącej bazy kodu lub zainicjowanie nowej bazy i nadanie nowej nazwy. Na początek wystarczy pojedyncza baza kodu w domyślnej lokalizacji. Później, w miarę rozwoju implementacji, warto uporządkować funkcje w bazach kodu.
  5. Interfejs wiersza poleceń udostępnia 2 opcje obsługi języków:

    Na potrzeby tego samouczka wybierz JavaScript.

  6. Interfejs wiersza poleceń umożliwia instalowanie zależności przy użyciu npm. Możesz bezpiecznie odrzucić zmiany, jeśli chcesz zarządzać zależnościami w inny sposób, ale jeśli to zrobisz, musisz uruchomić npm install przed emulacją lub wdrożeniem funkcji.

Gdy te polecenia zostaną ukończone, struktura projektu będzie wyglądać tak:

myproject
 +- .firebaserc    # Hidden file that helps you quickly switch between
 |                 # projects with `firebase use`
 |
 +- firebase.json  # Describes properties for your project
 |
 +- functions/     # Directory containing all your functions code
      |
      +- .eslintrc.json  # Optional file containing rules for JavaScript linting.
      |
      +- package.json  # npm package file describing your Cloud Functions code
      |
      +- index.js      # main source file for your Cloud Functions code
      |
      +- node_modules/ # directory where your dependencies (declared in
                       # package.json) are installed

Plik package.json utworzony podczas inicjowania zawiera ważny klucz: "engines": {"node": "16"}. Określa wersję Node.js do zapisywania i wdrażania funkcji. Możesz wybrać inne obsługiwane wersje.

Zaimportuj wymagane moduły i zainicjuj aplikację

Po ukończeniu zadań konfiguracyjnych możesz otworzyć katalog źródłowy i zacząć dodawać kod zgodnie z opisem w następnych sekcjach. W tym przykładzie Twój projekt musi zaimportować moduły Cloud Functions i pakietu Admin SDK za pomocą instrukcji węzła require. Dodaj do pliku index.js wiersze podobne do tych:

// The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
const functions = require('firebase-functions/v1');

// The Firebase Admin SDK to access Firestore.
const admin = require("firebase-admin");
admin.initializeApp();

Te wiersze wczytują moduły firebase-functions i firebase-admin oraz inicjują instancję aplikacji admin, w której można wprowadzać zmiany w Cloud Firestore. Wszędzie tam, gdzie dostępna jest obsługa pakietu Admin SDK, tak samo jak w przypadku FCM, uwierzytelniania i Bazy danych czasu rzeczywistego Firebase, zapewnia ona skuteczny sposób integracji Firebase z wykorzystaniem Cloud Functions.

Interfejs wiersza poleceń Firebase automatycznie instaluje moduły Firebase i Firebase SDK dla węzłów w Cloud Functions po zainicjowaniu projektu. Aby dodać do projektu biblioteki zewnętrzne, możesz zmodyfikować package.json i uruchomić npm install. Więcej informacji znajdziesz w opisie obsługi zależności.

Dodaj funkcję addMessage()

W przypadku funkcji addMessage() do elementu index.js dodaj te wiersze:

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addMessage = functions.https.onRequest(async (req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into Firestore using the Firebase Admin SDK.
  const writeResult = await admin
    .firestore()
    .collection("messages")
    .add({ original: original });
  // Send back a message that we've successfully written the message
  res.json({ result: `Message with ID: ${writeResult.id} added.` });
});

Funkcja addMessage() jest punktem końcowym HTTP. Każde żądanie skierowane do punktu końcowego powoduje przekazanie obiektów Request i Response w stylu ExpressJS do wywołania zwrotnego onRequest().

Funkcje HTTP są synchroniczne (podobnie do funkcji wywoływanych), więc musisz jak najszybciej wysłać odpowiedź i odłożyć pracę w Cloud Firestore. Funkcja HTTP addMessage() przekazuje wartość tekstową do punktu końcowego HTTP i wstawia ją do bazy danych pod ścieżką /messages/:documentId/original.

Dodaj funkcję makeUppercase()

W przypadku funkcji makeUppercase() do elementu index.js dodaj te wiersze:

// Listens for new messages added to /messages/:documentId/original and creates an
// uppercase version of the message to /messages/:documentId/uppercase
exports.makeUppercase = functions.firestore
  .document("/messages/{documentId}")
  .onCreate((snap, context) => {
    // Grab the current value of what was written to Firestore.
    const original = snap.data().original;

    // Access the parameter `{documentId}` with `context.params`
    functions.logger.log("Uppercasing", context.params.documentId, original);

    const uppercase = original.toUpperCase();

    // You must return a Promise when performing asynchronous tasks inside a Functions such as
    // writing to Firestore.
    // Setting an 'uppercase' field in Firestore document returns a Promise.
    return snap.ref.set({ uppercase }, { merge: true });
  });

Funkcja makeUppercase() jest wykonywana podczas zapisywania w Cloud Firestore. Funkcja ref.set definiuje dokument, na którym ma być nasłuchiwany. Ze względu na skuteczność należy podawać jak najbardziej szczegółowe informacje.

Nawiasy klamrowe (np. {documentId}) otaczają „parametry”, czyli symbole wieloznaczne, które ujawniają dopasowane dane w wywołaniu zwrotnym.

Cloud Firestore aktywuje wywołanie zwrotne onCreate() po każdym dodaniu nowych wiadomości.

Funkcje oparte na zdarzeniach, takie jak zdarzenia Cloud Firestore, są asynchroniczne. Funkcja wywołania zwrotnego powinna zwracać wartość null, obiekt lub Promise. Jeśli nie zwrócisz niczego, funkcja przekroczy limit czasu, co zasygnalizuje błąd. Następnie zostanie ponowiona. Zapoznaj się z sekcją Synchronizacja, asynchroniczne i obietnice.

Emuluj wykonywanie funkcji

Pakiet emulatorów lokalnych Firebase pozwala tworzyć i testować aplikacje na komputerze lokalnym, zamiast wdrażać je w projekcie Firebase. Zdecydowanie zalecamy testy lokalne w trakcie programowania, m.in. dlatego, że zmniejsza to ryzyko wystąpienia błędów w kodowaniu, które mogą spowodować koszty w środowisku produkcyjnym (np. w pętli nieskończonej).

Aby emulować funkcje:

  1. Uruchom firebase emulators:start i sprawdź dane wyjściowe adresu URL interfejsu Pakietu emulatorów. Domyślnie jest to localhost:4000, ale może być hostowany na innym porcie na komputerze. Wpisz ten URL w przeglądarce, by otworzyć interfejs Pakietu emulatorów.

  2. Sprawdź dane wyjściowe polecenia firebase emulators:start pod kątem adresu URL funkcji HTTP addMessage(). Będzie on wyglądał podobnie do http://localhost:5001/MY_PROJECT/us-central1/addMessage z tymi różnicami:

    1. Pole MY_PROJECT zostanie zastąpione identyfikatorem projektu.
    2. Port może się różnić na komputerze lokalnym.
  3. Dodaj ciąg zapytania ?text=uppercaseme na końcu adresu URL funkcji. Powinien wyglądać mniej więcej tak: http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme. Opcjonalnie możesz zmienić komunikat „wielkie litery” na komunikat niestandardowy.

  4. Utwórz nową wiadomość, otwierając adres URL w nowej karcie przeglądarki.

  5. Zobacz efekty działania funkcji w interfejsie Pakietu emulatorów:

    1. Na karcie Logi powinny pojawić się nowe logi wskazujące, że funkcje addMessage() i makeUppercase() zostały uruchomione:

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

    2. Na karcie Firestore powinien być widoczny dokument zawierający oryginalną wiadomość oraz jej wersję pisaną wielkimi literami (jeśli wcześniejsza wiadomość była pisana wielkimi literami, będzie wyświetlana WIELKA LICZBA).

Wdrażanie funkcji w środowisku produkcyjnym

Gdy funkcje w emulatorze działają zgodnie z oczekiwaniami, możesz je wdrażać, testować i uruchamiać w środowisku produkcyjnym. Pamiętaj, że aby można było przeprowadzić wdrożenie w zalecanym środowisku wykonawczym Node.js 14, projekt musi być objęty abonamentem Blaze. Sprawdź cennik Cloud Functions.

Aby zakończyć samouczek, wdróż funkcje, a następnie wykonaj addMessage(), aby aktywować makeUppercase().

  1. Aby wdrożyć funkcje, uruchom to polecenie:

     firebase deploy --only functions
     

    Po uruchomieniu tego polecenia interfejs wiersza poleceń Firebase wyświetli adres URL wszystkich punktów końcowych funkcji HTTP. W terminalu powinien pojawić się wiersz podobny do tego:

    Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage
    

    Adres URL zawiera identyfikator projektu oraz region dla funkcji HTTP. Na razie nie musisz się tym przejmować, ale niektóre produkcyjne funkcje HTTP powinny określać lokalizację, aby zminimalizować opóźnienia w sieci.

    Jeśli wystąpią błędy dostępu, takie jak „Nie można autoryzować dostępu do projektu”, spróbuj sprawdzić aliasy projektu.

  2. Korzystając z adresu URL addMessage() wyświetlanego przez interfejs wiersza poleceń, dodaj tekstowy parametr zapytania i otwórz go w przeglądarce:

    https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercasemetoo
    

    Funkcja uruchamia przeglądarkę i przekierowuje ją do konsoli Firebase w lokalizacji bazy danych, w której jest przechowywany ciąg tekstowy. To zdarzenie zapisu aktywuje funkcję makeUppercase(), która zapisuje wersję ciągu znaków wielkimi literami.

Po wdrożeniu i wykonaniu funkcji możesz wyświetlić logi w konsoli Google Cloud. Jeśli musisz usunąć funkcje w środowisku programistycznym lub produkcyjnym, użyj interfejsu wiersza poleceń Firebase.

W środowisku produkcyjnym możesz optymalizować wydajność funkcji i kontrolować koszty przez ustawienie minimalnej i maksymalnej liczby instancji, które mają zostać uruchomione. Więcej informacji o tych opcjach środowiska wykonawczego znajdziesz w artykule o zarządzaniu zachowaniem skalowania.

Sprawdź pełny przykładowy kod

Oto gotowy tekst functions/index.js zawierający funkcje addMessage() i makeUppercase(). Te funkcje umożliwiają przekazanie parametru do punktu końcowego HTTP, który zapisuje wartość w Cloud Firestore, a następnie przekształca ją przez zmianę wielkości liter wszystkich znaków w ciągu znaków.

// The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
const functions = require('firebase-functions/v1');

// The Firebase Admin SDK to access Firestore.
const admin = require("firebase-admin");
admin.initializeApp();

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addMessage = functions.https.onRequest(async (req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into Firestore using the Firebase Admin SDK.
  const writeResult = await admin
    .firestore()
    .collection("messages")
    .add({ original: original });
  // Send back a message that we've successfully written the message
  res.json({ result: `Message with ID: ${writeResult.id} added.` });
});

// Listens for new messages added to /messages/:documentId/original and creates an
// uppercase version of the message to /messages/:documentId/uppercase
exports.makeUppercase = functions.firestore
  .document("/messages/{documentId}")
  .onCreate((snap, context) => {
    // Grab the current value of what was written to Firestore.
    const original = snap.data().original;

    // Access the parameter `{documentId}` with `context.params`
    functions.logger.log("Uppercasing", context.params.documentId, original);

    const uppercase = original.toUpperCase();

    // You must return a Promise when performing asynchronous tasks inside a Functions such as
    // writing to Firestore.
    // Setting an 'uppercase' field in Firestore document returns a Promise.
    return snap.ref.set({ uppercase }, { merge: true });
  });

Dalsze kroki

Z tej dokumentacji dowiesz się więcej o zarządzaniu funkcjami w Cloud Functions oraz o obsłudze wszystkich typów zdarzeń obsługiwanych przez Cloud Functions.

Aby dowiedzieć się więcej o Cloud Functions, możesz też wykonać te czynności: