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


Aby rozpocząć korzystanie z Cloud Functions, zapoznaj się z tym samouczkiem. Zaczyna się on od wymaganych zadań konfiguracyjnych, a następnie pokazuje, jak tworzyć, testować i wdrażać 2 powiązane funkcje:

  • Funkcja „add message” (dodaj wiadomość), która udostępnia adres URL akceptujący wartość tekstową i zapisujący ją w Cloud Firestore.
  • Funkcja „zapisz wielkimi literami”, która jest aktywowana przez Cloud Firestore zapis i przekształca tekst na wielkie litery.

W tym przykładzie wybraliśmy Cloud Firestore i funkcje JavaScript wywoływane przez HTTP, ponieważ te wyzwalacze w tle można dokładnie przetestować za pomocą Firebase Local Emulator Suite. Ten zestaw narzędzi obsługuje też Realtime Database, PubSub, Auth i wywoływane przez HTTP wyzwalacze. Inne typy reguł w tle, takie jak Remote Config, TestLab i reguły Analytics, można testować interaktywnie za pomocą zestawów narzędzi, które nie są opisane na tej stronie.

W kolejnych sekcjach tego samouczka znajdziesz szczegółowe informacje o krokach wymaganych do skompilowania, przetestowania i wdrożenia próbki. Jeśli wolisz po prostu uruchomić kod i go sprawdzić, przejdź do sekcji Sprawdzanie pełnego przykładowego kodu.

Tworzenie projektu Firebase

  1. W Firebasekonsoli kliknij Dodaj projekt.

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

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

  2. Jeśli pojawi się taka prośba, przeczytaj i zaakceptuj warunki usługi Firebase.

  3. Kliknij Dalej.

  4. (Opcjonalnie) skonfiguruj Google Analytics w projekcie, co umożliwi optymalne korzystanie z tych usług Firebase: Firebase A/B Testing, Cloud Messaging, Crashlytics, In-App MessagingRemote Config (w tym Personalizacja).

    Wybierz istniejące Google Analyticskonto lub utwórz nowe. Jeśli tworzysz nowe konto, wybierz Analyticslokalizację raportowania, a następnie zaakceptuj ustawienia udostępniania danych i Google Analytics warunki korzystania z usługi w przypadku projektu.

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

Firebase automatycznie udostępnia zasoby dla Twojego projektu Firebase. Po zakończeniu procesu otworzy się strona podsumowania projektu Firebase w Firebasekonsoli.

Konfigurowanie Node.js i wiersza poleceń Firebase

Do pisania funkcji potrzebujesz środowiska Node.js, a do wdrażania funkcji w środowisku wykonawczym Cloud Functions potrzebujesz interfejsu Firebase CLI. Do instalacji Node.js i npm zalecany jest Node Version Manager.

Po zainstalowaniu Node.js i npm zainstaluj FirebaseCLI w wybrany przez siebie sposób. Aby zainstalować interfejs wiersza poleceń za pomocą npm, użyj tego polecenia:

npm install -g firebase-tools

Spowoduje to zainstalowanie polecenia firebase dostępnego globalnie. Jeśli polecenie się nie powiedzie, może być konieczna zmiana uprawnień npm. Aby zaktualizować firebase-tools do najnowszej wersji, ponownie uruchom to samo polecenie.

Zainicjuj projekt

Podczas inicjowania Firebase pakietu SDK dla Cloud Functions tworzysz pusty projekt zawierający zależności i minimalny przykładowy kod. Możesz też wybrać język TypeScript 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 Firebase CLI.

  2. Przejdź do katalogu projektu Firebase.

  3. Uruchom firebase init firestore. W tym samouczku możesz zaakceptować wartości domyślne, gdy pojawi się prośba o podanie reguł Firestore i plików indeksu. Jeśli nie używasz jeszcze Cloud Firestore w tym projekcie, musisz też wybrać tryb początkowy i lokalizację Firestore zgodnie z opisem w artykule Wprowadzenie do Cloud Firestore.

  4. Uruchom firebase init functions. Interfejs CLI wyświetli prośbę o wybranie istniejącej bazy kodu lub zainicjowanie i nazwanie nowej. Na początek wystarczy jedna baza kodu w domyślnej lokalizacji. Później, gdy Twoje wdrożenie się rozwinie, możesz uporządkować funkcje w bazach kodu.

  5. Interfejs CLI oferuje te opcje obsługi języków:

    Na potrzeby tego samouczka wybierz JavaScript.

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

Po pomyślnym 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"}. Określa wersję Node.js do pisania 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 dalszej części tego artykułu. W tym przykładzie projekt musi importować 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ą instancję aplikacji admin, w której można wprowadzać zmiany Cloud Firestore. Wszędzie tam, gdzie dostępny jest pakiet Admin SDK, czyli w przypadku FCM, AuthenticationFirebase Realtime Database, zapewnia on zaawansowany sposób integracji Firebase za pomocą Cloud Functions.

Interfejs Firebase CLI automatycznie instaluje pakiety SDK Firebase i Firebase dla Cloud Functions modułów Node podczas inicjowania projektu. Aby dodać do projektu biblioteki innych firm, możesz zmodyfikować plik package.json i uruchomić polecenie npm install. Więcej informacji znajdziesz w sekcji Obsługa zależności.

Dodawanie funkcji addMessage()

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

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

addMessage() to punkt końcowy HTTP. Każde żądanie wysłane do punktu końcowego powoduje przekazanie do wywołania zwrotnego onRequest() obiektów RequestResponse w stylu ExpressJS.

Funkcje HTTP są synchroniczne (podobnie jak funkcje wywoływane), więc należy jak najszybciej wysłać odpowiedź i odłożyć pracę za pomocą 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.

Dodawanie funkcji makeUppercase()

W przypadku funkcji makeUppercase() dodaj te wiersze do pliku 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, gdy zapisywana jest wartość Cloud Firestore. Funkcja ref.set określa dokument, na który ma reagować funkcja. Ze względu na wydajność podaj jak najdokładniejsze informacje.

Klamry – np. {documentId} – otaczają „parametry”, czyli symbole wieloznaczne, które w wywołaniu zwrotnym udostępniają dopasowane dane.

Cloud Firestore wywołuje funkcję zwrotną onCreate() za każdym razem, gdy dodawane są nowe wiadomości.

Funkcje reagujące na zdarzenia, takie jak Cloud Firestore zdarzenia, są asynchroniczne. Funkcja wywołania zwrotnego powinna zwracać wartość null, obiekt lub obietnicę. Jeśli nie zwrócisz żadnych danych, funkcja przekroczy limit czasu, co będzie oznaczać błąd, i zostanie ponowiona. Zobacz Synchronizacja, asynchroniczność i obietnice.

Emulowanie wykonywania funkcji

Firebase Local Emulator Suite umożliwia tworzenie i testowanie aplikacji na komputerze lokalnym zamiast wdrażania ich w projekcie Firebase. Zdecydowanie zalecamy testowanie lokalne podczas programowania, ponieważ zmniejsza ono ryzyko wystąpienia błędów w kodzie, które mogą generować koszty w środowisku produkcyjnym (np. nieskończona pętla).

Aby emulować funkcje:

  1. Uruchom firebase emulators:start i sprawdź w danych wyjściowych adres URL Emulator Suite UI. Domyślnie jest to localhost:4000, ale może być hostowany na innym porcie na Twoim komputerze. Wpisz ten adres URL w przeglądarce, aby otworzyć Emulator Suite UI.

  2. Sprawdź wynik 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 tą różnicą, że:

    1. MY_PROJECT zostanie zastąpiony identyfikatorem projektu.
    2. Port może się różnić na Twoim komputerze lokalnym.
  3. Dodaj ciąg zapytania ?text=uppercaseme na końcu adresu URL funkcji. Powinno to wyglądać mniej więcej tak: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. Sprawdź efekty funkcji w Emulator Suite UI:

    1. Na karcie Logi powinny być widoczne nowe logi wskazujące, że funkcje addMessage()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ę zapisaną wielkimi literami (jeśli oryginalna wiadomość to „uppercaseme”, zobaczysz „UPPERCASEME”).

Wdrażanie funkcji w środowisku produkcyjnym

Gdy funkcje będą działać w emulatorze zgodnie z oczekiwaniami, możesz je wdrożyć, przetestować i uruchomić w środowisku produkcyjnym. Pamiętaj, że aby wdrożyć projekt w środowisku wykonawczym Node.js 14, musisz mieć abonament Blaze. Sprawdź Cloud Functions cennik.

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

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

     firebase deploy --only functions
     

    Po uruchomieniu tego polecenia interfejs Firebase CLI 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 funkcji HTTP. Chociaż nie musisz się tym teraz przejmować, niektóre funkcje HTTP w środowisku produkcyjnym powinny określać lokalizację, aby zminimalizować opóźnienie sieci.

    Jeśli napotkasz błędy dostępu, takie jak „Nie można autoryzować dostępu do projektu”, sprawdź aliasowanie projektu.

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

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

    Funkcja wykonuje działanie i przekierowuje przeglądarkę do Firebasekonsoli w lokalizacji bazy danychFirebase, w której przechowywany jest ciąg tekstowy. To zdarzenie zapisu wywołuje makeUppercase(), które zapisuje ciąg znaków w wersji pisanej wielkimi literami.

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

W środowisku produkcyjnym możesz zoptymalizować wydajność funkcji i kontrolować koszty, ustawiając minimalną i maksymalną liczbę instancji do uruchomienia. Więcej informacji o tych opcjach środowiska wykonawczego znajdziesz w sekcji Kontrolowanie skalowania.

Przeglądanie pełnego przykładowego kodu

Oto ukończony kod functions/index.js zawierający funkcje addMessage() i makeUppercase(). Te funkcje umożliwiają przekazywanie parametru do punktu końcowego HTTP, który zapisuje wartość w Cloud Firestore, a następnie przekształca ją, zmieniają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 tym, jak zarządzać funkcjami w przypadku Cloud Functions, a także jak obsługiwać wszystkie typy zdarzeń obsługiwane przez Cloud Functions.

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