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


Aby rozpocząć korzystanie z Cloud Functions, zapoznaj się z tym samouczkiem, który zaczyna się od wymaganych zadań konfiguracyjnych, a kończy na tworzeniu, testowaniu i wdrażaniu 2 powiązanych ze sobą funkcji:

  • Funkcja „dodaj wiadomość”, która ujawnia adres URL przyjmujący wartość tekstową i zapisuje ją w Cloud Firestore.
  • Funkcja „make uppercase”, która jest wywoływana po zapisie za pomocą funkcji Cloud Firestore i przekształca tekst na wielkie litery.

W tym przykładzie wybraliśmy Cloud Firestore i wywoływane przez HTTP funkcje JavaScriptu, m.in. dlatego, że te aktywatory działające w tle można dokładnie przetestować w narzędziu Firebase Local Emulator Suite. Ten zestaw narzędzi obsługuje też Realtime Database, PubSub, Auth i wywoływane przez HTTP uruchamiane przez HTTP. Inne typy aktywatorów działających w tle, takie jak aktywatory Remote Config, TestLab i Analytics, można testować interaktywnie za pomocą zestawów narzędzi, które nie zostały opisane na tej stronie.

W następnych sekcjach tego samouczka znajdziesz szczegółowe instrukcje kompilowania, testowania i wdrażania przykładowej aplikacji. Jeśli wolisz uruchomić kod i go sprawdzić, przejdź do sekcji Przeglądanie pełnego przykładowego kodu.

Tworzenie projektu Firebase

  1. W konsoli Firebase kliknij Dodaj projekt.

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

    • Aby utworzyć nowy projekt, wpisz odpowiednią nazwę. Opcjonalnie możesz też edytować identyfikator projektu wyświetlany pod nazwą projektu.

  2. Jeśli pojawi się taka prośba, zapoznaj się z warunkami usługi Firebase i je zaakceptuj.

  3. Kliknij Dalej.

  4. (Opcjonalnie) Skonfiguruj w projekcie Google Analytics, aby optymalnie korzystać z tych usług Firebase:

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

    Jeśli tworzysz nowe konto, wybierz Analyticslokalizację raportowania, a potem zaakceptuj ustawienia udostępniania danych i zasady Google Analytics dotyczące projektu.

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

Firebase automatycznie udostępnia zasoby projektu Firebase. Po zakończeniu procesu wyświetli się strona podsumowania projektu Firebase w konsoli Firebase.

Skonfiguruj Node.js i interfejs wiersza poleceń Firebase

Do tworzenia funkcji potrzebujesz środowiska Node.js, a do wdrażania funkcji w środowisku wykonawczym Cloud Functions – interfejsu wiersza poleceń Firebase. Do instalowania Node.js i npm zalecamy użycie menedżera wersji Node.js.

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 polecenia firebase dostępnego na całym świecie. Jeśli polecenie się nie powiedzie, konieczna może być zmiana uprawnień npm. Aby zaktualizować aplikację firebase-tools do najnowszej wersji, ponownie uruchom to samo polecenie.

Zainicjuj projekt

Gdy zainicjujesz pakiet SDK Firebase dla Cloud Functions, utworzysz pusty projekt zawierający zależności i minimalną ilość przykładowego kodu, a do tworzenia funkcji wybierasz język TypeScript lub JavaScript. W tym samouczku 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 możesz zaakceptować wartości domyślne, gdy pojawi się prośba o reguły Firestore i pliki indeksu. Jeśli nie korzystasz jeszcze z Cloud Firestore w tym projekcie, musisz też wybrać tryb początkowy i lokalizację Firestore zgodnie z instrukcjami w artykule Początkowanie pracy z Cloud Firestore.
  4. Uruchom firebase init functions. Narzędzie wiersza poleceń wyświetli prośbę o wybranie istniejącej bazy kodu lub zainicjowanie i nazwanie nowej. Na początku wystarczy jedna baza kodu w domyślnej lokalizacji. Później, gdy Twoja implementacja się rozrośnie, możesz uporządkować funkcje w bazach kodu.
  5. Interfejs wiersza poleceń oferuje 2 opcje obsługi języka:

    Na potrzeby tego samouczka wybierz JavaScript.

  6. Interfejs wiersza poleceń umożliwia instalowanie zależności za pomocą npm. Jeśli chcesz zarządzać zależnościami w inny sposób, możesz bezpiecznie odrzucić tę prośbę. Jeśli jednak to zrobisz, przed emulacją lub wdrożeniem funkcji trzeba będzie uruchomić polecenie npm install.

Po wykonaniu tych poleceń 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 inicjalizacji zawiera ważny klucz: "engines": {"node": "16"}. To ustawienie określa wersję Node.js używaną do zapisywania i wdrażania funkcji. Możesz wybrać inne obsługiwane wersje.

Importowanie wymaganych modułów i inicjowanie aplikacji

Po wykonaniu zadań konfiguracyjnych możesz otworzyć katalog źródeł i rozpocząć dodawanie kodu zgodnie z instrukcjami podanymi w następnych sekcjach. W tym przykładzie Twój projekt musi zaimportować moduły Cloud Functions i Admin SDK za pomocą instrukcji Node 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-functionsfirebase-admin oraz inicjują wystąpienie aplikacji admin, z którego można wprowadzać zmiany w elementach Cloud Firestore. Wszędzie tam, gdzie jest dostępny pakiet Admin SDK (jak w przypadku FCM, AuthenticationFirebase Realtime Database), stanowi on potężne narzędzie do integracji Firebase za pomocą Cloud Functions.

Gdy inicjujesz projekt, wiersz poleceń Firebase automatycznie instaluje pakiet SDK Firebase i Firebase dla modułów Cloud Functions Node. Aby dodać biblioteki innych firm do projektu, możesz zmodyfikować package.json i uruchomić npm install. Więcej informacji znajdziesz w artykule o zależnościach obsługi.

Dodaj funkcję addMessage()

W przypadku funkcji addMessage() dodaj do index.js 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 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), dlatego odpowiedź należy wysłać jak najszybciej, a opóźnić ją, używając funkcji 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() dodaj te wiersze do funkcji index.js:

// 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 po zapisaniu elementu Cloud Firestore. Funkcja ref.set określa dokument, na który ma reagować. Ze względu na wydajność podawaj jak najwięcej szczegółów.

Nawiasy klamrowe (np. {documentId}) – przestrzenne „parametry” i symbole wieloznaczne, które ujawniają pasujące dane w wywołaniu zwrotnym.

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

Funkcje reagujące na zdarzenia, takie jak zdarzenia Cloud Firestore, są asynchroniczne. Funkcja wywołania zwrotnego powinna zwracać wartość null, obiekt lub obietnica. Jeśli nie zwrócisz niczego, funkcja zostanie przerwana, co spowoduje błąd i ponownie podjęta próba. Zobacz Synchronizacja, asynchroniczne i obietnice.

Emuluj wykonywanie funkcji

Firebase Local Emulator Suiteumożliwia tworzenie i testowanie aplikacji na komputerze lokalnym zamiast wdrażania ich w projekcie Firebase. Zalecamy testowanie lokalne podczas tworzenia aplikacji, ponieważ zmniejsza to ryzyko błędów w kodzie, które mogą potencjalnie generować koszty w środowisku produkcyjnym (np. nieskończona pętla).

Aby emulować funkcje:

  1. Uruchom firebase emulators:start i sprawdź dane wyjściowe pod kątem adresu URL Emulator Suite UI. Domyślnie jest to localhost:4000, ale może być hostowane na innym porcie na komputerze. Wpisz ten adres URL w przeglądarce, aby otworzyć Emulator Suite UI.

  2. Sprawdź dane wyjściowe polecenia firebase emulators:start dotyczące adresu URL funkcji HTTP addMessage(). Będzie on wyglądał podobnie do http://localhost:5001/MY_PROJECT/us-central1/addMessage, z tym że:

    1. MY_PROJECT zostanie zastąpiony identyfikatorem projektu.
    2. Port może się różnić w zależności od komputera lokalnego.
  3. Dodaj ciąg zapytania ?text=uppercaseme na końcu adresu URL funkcji. Powinien wyglądać podobnie do tego: http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme. Opcjonalnie możesz zmienić wiadomość „uppercaseme” na wiadomość niestandardową.

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

  5. Wyświetl efekty działania funkcji w sekcji Emulator Suite UI:

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

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

    2. Na karcie Firestore powinien pojawić się dokument zawierający oryginalną wiadomość oraz jej wersję z wielkimi literami (jeśli oryginalna wiadomość brzmiała „uppercaseme”, zobaczysz „UPPERCASEME”).

Wdrażanie funkcji w środowisku produkcyjnym

Gdy funkcje będą działać zgodnie z oczekiwaniami w emulatorze, możesz je wdrożyć, przetestować i uruchomić w środowisku produkcyjnym. Pamiętaj, że aby możliwe było wdrożenie w zalecanym środowisku wykonawczym Node.js 14, projekt musi być objęty abonamentem Blaze. Sprawdź cennikCloud Functions.

Aby ukoń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świetla 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. Nie musisz się teraz tym martwić, 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”, sprawdź aliasy projektu.

  2. Korzystając z adresu URL addMessage() wygenerowanego przez CLI, dodaj parametr zapytania tekstowego i otwórz go w przeglądarce:

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

    Funkcja jest wykonywana i przekierowuje przeglądarkę do konsoli Firebase w lokalizacji bazy danych, w której zapisany jest ciąg tekstowy. To zdarzenie zapisu powoduje wywołanie funkcji makeUppercase(), która zapisuje ciąg tekstowy w wersji z wielkimi literami.

Po wdrożeniu i wykonywaniu funkcji możesz wyświetlać dzienniki w konsoli Google Cloud. Jeśli chcesz usunąć funkcje w wersji rozwojowej lub produkcyjnej, użyj interfejsu wiersza poleceń Firebase.

W środowisku produkcyjnym warto zoptymalizować wydajność funkcji i kontrolować koszty przez ustawienie minimalnej i maksymalnej liczby instancji do uruchomienia. Więcej informacji o tych opcjach środowiska wykonawczego znajdziesz w artykule o sterowaniu skalowaniem.

Przejrzyj kompletny przykładowy kod

Oto gotowa funkcja functions/index.js zawierająca funkcje addMessage()makeUppercase(). Te funkcje umożliwiają przekazanie parametru do punktu końcowego HTTP, który zapisuje wartość w parametrie Cloud Firestore, a potem przekształca ją, zamieniając wszystkie znaki w ciągu na wielkie litery.

// 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

W tej dokumentacji znajdziesz więcej informacji o zarządzaniu funkcjami w przypadku usługi Cloud Functions, a także o obsługiwaniu wszystkich typów zdarzeń obsługiwanych przez tę usługę.Cloud Functions

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