Zacznij: napisz, przetestuj i wdrażaj swoje pierwsze funkcje


Aby rozpocząć korzystanie z Cloud Functions, spróbuj zapoznać się z tym samouczkiem, który zaczyna się od wymaganych zadań konfiguracyjnych i obejmuje tworzenie, testowanie i wdrażanie dwóch powiązanych funkcji:

  • Funkcja „dodaj wiadomość”, która udostępnia adres URL, który akceptuje wartość tekstową i zapisuje ją w Cloud Firestore.
  • Funkcja „twórz wielkie litery”, która uruchamia zapis w Cloud Firestore i przekształca tekst na wielkie litery.

Oto pełny przykładowy kod zawierający funkcje:

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

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

initializeApp();

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = 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 getFirestore()
      .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 saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
  // Grab the current value of what was written to Firestore.
  const original = event.data.data().original;

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

  const uppercase = original.toUpperCase();

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

Pyton

# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn

# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore

app = initialize_app()


@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
    """Take the text parameter passed to this HTTP endpoint and insert it into
    a new document in the messages collection."""
    # Grab the text parameter.
    original = req.args.get("text")
    if original is None:
        return https_fn.Response("No text parameter provided", status=400)

    firestore_client: google.cloud.firestore.Client = firestore.client()

    # Push the new message into Cloud Firestore using the Firebase Admin SDK.
    _, doc_ref = firestore_client.collection("messages").add({"original": original})

    # Send back a message that we've successfully written the message
    return https_fn.Response(f"Message with ID {doc_ref.id} added.")


@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None]) -> None:
    """Listens for new documents to be added to /messages. If the document has
    an "original" field, creates an "uppercase" field containg the contents of
    "original" in upper case."""

    # Get the value of "original" if it exists.
    if event.data is None:
        return
    try:
        original = event.data.get("original")
    except KeyError:
        # No "original" field, so do nothing.
        return

    # Set the "uppercase" field.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    event.data.reference.update({"uppercase": upper})

O tym samouczku

Do tego przykładu wybraliśmy funkcje Cloud Firestore i funkcje wyzwalane przez HTTP, częściowo dlatego, że te wyzwalacze w tle można dokładnie przetestować za pomocą pakietu Firebase Local Emulator Suite . Ten zestaw narzędzi obsługuje także bazy danych czasu rzeczywistego, przechowywanie w chmurze, PubSub, uwierzytelnianie i wywoływalne wyzwalacze HTTP. Inne typy wyzwalaczy działających w tle, takie jak wyzwalacze Remote Config i TestLab, można testować interaktywnie przy użyciu zestawów narzędzi nieopisanych na tej stronie.

W poniższych sekcjach tego samouczka szczegółowo opisano kroki wymagane do kompilowania, testowania i wdrażania przykładu.

Utwórz projekt Firebase

  1. W konsoli Firebase kliknij Dodaj projekt .

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

    • Aby utworzyć nowy projekt, wprowadź żądaną nazwę projektu. Opcjonalnie możesz także edytować identyfikator projektu wyświetlany pod nazwą projektu.

  2. Jeśli pojawi się monit, przejrzyj i zaakceptuj warunki Firebase .

  3. Kliknij Kontynuuj .

  4. (Opcjonalnie) Skonfiguruj Google Analytics dla swojego projektu, co umożliwi optymalne korzystanie z dowolnego z następujących produktów Firebase:

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

    Jeśli tworzysz nowe konto, wybierz lokalizację raportowania Analytics , a następnie zaakceptuj ustawienia udostępniania danych i warunki Google Analytics dla swojego projektu.

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

Firebase automatycznie udostępnia zasoby dla Twojego projektu Firebase. Po zakończeniu procesu zostaniesz przeniesiony na stronę przeglądu projektu Firebase w konsoli Firebase.

Skonfiguruj środowisko i interfejs wiersza polecenia Firebase

Node.js

Do pisania funkcji potrzebne będzie środowisko Node.js , a do wdrażania funkcji w środowisku wykonawczym Cloud Functions potrzebny będzie interfejs wiersza polecenia Firebase. Do instalacji Node.js i npm zalecany jest Menedżer wersji węzła .

Po zainstalowaniu Node.js i npm zainstaluj interfejs CLI Firebase za pomocą preferowanej metody. Aby zainstalować CLI przez npm, użyj:

npm install -g firebase-tools

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

Pyton

Do pisania funkcji potrzebne będzie środowisko Python , a do wdrażania funkcji w środowisku wykonawczym Cloud Functions potrzebny będzie interfejs wiersza polecenia Firebase. Zalecamy użycie venv do izolowania zależności. Obsługiwane są wersje języka Python 3.10 i 3.11.

Po zainstalowaniu Pythona zainstaluj interfejs CLI Firebase za pomocą preferowanej metody.

Zainicjuj swój projekt

Kiedy inicjujesz zestaw SDK Firebase dla Cloud Functions, tworzysz pusty projekt zawierający zależności i minimalny przykładowy kod. Jeśli używasz Node.js, możesz wybrać TypeScript lub JavaScript do tworzenia funkcji. Na potrzeby tego samouczka musisz także zainicjować Cloud Firestore.

Aby zainicjować projekt:

  1. Uruchom firebase login , aby zalogować się przez przeglądarkę i uwierzytelnić interfejs CLI Firebase.
  2. Przejdź do katalogu projektu Firebase.
  3. Uruchom firebase init firestore . W tym samouczku możesz zaakceptować wartości domyślne po wyświetleniu monitu o reguły Firestore i pliki indeksu. Jeśli jeszcze nie korzystałeś z Cloud Firestore w tym projekcie, musisz także wybrać tryb początkowy i lokalizację Firestore, jak opisano w artykule Pierwsze kroki z Cloud Firestore .
  4. Uruchom firebase init functions . Interfejs CLI poprosi Cię o wybranie istniejącej bazy kodu lub zainicjowanie i nadanie nazwy nowej. Kiedy dopiero zaczynasz, wystarczy pojedyncza baza kodu w domyślnej lokalizacji; później, w miarę rozwoju implementacji, możesz chcieć uporządkować funkcje w bazach kodu .
  5. Interfejs CLI udostępnia następujące opcje obsługi języków:

    • JavaScript
    • Maszynopis
    • Pyton

    Na potrzeby tego samouczka wybierz JavaScript lub Python . Informacje na temat tworzenia w języku TypeScript można znaleźć w artykule Pisanie funkcji za pomocą TypeScriptu .

  6. Interfejs CLI umożliwia instalację zależności. Jeśli chcesz zarządzać zależnościami w inny sposób, możesz bezpiecznie odmówić.

Po pomyślnym wykonaniu tych poleceń struktura projektu wygląda następująco:

Node.js

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

W przypadku Node.js plik package.json utworzony podczas inicjalizacji zawiera ważny klucz: "engines": {"node": "18"} . Określa wersję Node.js do pisania i wdrażania funkcji. Możesz wybrać inne obsługiwane wersje .

Pyton

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
      |
      +- main.py      # Main source file for your Cloud Functions code
      |
      +- requirements.txt  #  List of the project's modules and packages 
      |
      +- venv/ # Directory where your dependencies are installed

Zaimportuj wymagane moduły i zainicjuj aplikację

Po zakończeniu zadań konfiguracyjnych możesz otworzyć katalog źródłowy i rozpocząć dodawanie kodu zgodnie z opisem w poniższych sekcjach. Na potrzeby tego przykładu Twój projekt musi zaimportować moduły Cloud Functions i Admin SDK. Dodaj do pliku źródłowego następujące linie:

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

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

initializeApp();

Pyton

# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn

# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore

app = initialize_app()

Te linie ładują wymagane moduły i inicjują instancję aplikacji admin , z której można wprowadzić zmiany w Cloud Firestore. Gdziekolwiek dostępna jest obsługa pakietu Admin SDK , np. w przypadku FCM, uwierzytelniania i bazy danych Firebase Realtime Database, zapewnia ona skuteczny sposób integracji Firebase za pomocą Cloud Functions.

Interfejs Firebase CLI automatycznie instaluje moduły Firebase Admin SDK i Firebase SDK for Cloud Functions podczas inicjowania projektu. Aby uzyskać więcej informacji na temat dodawania bibliotek innych firm do projektu, zobacz temat Obsługa zależności .

Dodaj funkcję „dodaj wiadomość”.

W przypadku funkcji „dodaj wiadomość” dodaj te linie do pliku źródłowego:

Node.js

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = 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 getFirestore()
      .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.`});
});

Pyton

@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
    """Take the text parameter passed to this HTTP endpoint and insert it into
    a new document in the messages collection."""
    # Grab the text parameter.
    original = req.args.get("text")
    if original is None:
        return https_fn.Response("No text parameter provided", status=400)

    firestore_client: google.cloud.firestore.Client = firestore.client()

    # Push the new message into Cloud Firestore using the Firebase Admin SDK.
    _, doc_ref = firestore_client.collection("messages").add({"original": original})

    # Send back a message that we've successfully written the message
    return https_fn.Response(f"Message with ID {doc_ref.id} added.")

Funkcja „dodaj wiadomość” jest punktem końcowym HTTP. Każde żądanie kierowane do punktu końcowego powoduje przesłanie obiektów żądań i odpowiedzi do modułu obsługi żądań na Twojej platformie ( onRequest() lub on_request ).

Funkcje HTTP są synchroniczne (podobnie jak funkcje wywoływalne ), dlatego warto jak najszybciej wysłać odpowiedź i odłożyć pracę przy użyciu Cloud Firestore. Funkcja HTTP „dodaj wiadomość” przekazuje wartość tekstową do punktu końcowego HTTP i wstawia ją do bazy danych pod ścieżką /messages/:documentId/original .

Dodaj funkcję „utwórz wielkie litery”.

W przypadku funkcji „make wielkimi literami” dodaj te linie do pliku źródłowego:

Node.js

// Listens for new messages added to /messages/:documentId/original
// and saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
  // Grab the current value of what was written to Firestore.
  const original = event.data.data().original;

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

  const uppercase = original.toUpperCase();

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

Pyton

@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None]) -> None:
    """Listens for new documents to be added to /messages. If the document has
    an "original" field, creates an "uppercase" field containg the contents of
    "original" in upper case."""

    # Get the value of "original" if it exists.
    if event.data is None:
        return
    try:
        original = event.data.get("original")
    except KeyError:
        # No "original" field, so do nothing.
        return

    # Set the "uppercase" field.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    event.data.reference.update({"uppercase": upper})

Funkcja „make wielkimi literami” jest wykonywana podczas zapisywania w Cloud Firestore, definiując dokument do nasłuchiwania. Ze względu na wydajność powinieneś być jak najbardziej szczegółowy.

Nawiasy klamrowe — na przykład {documentId} otaczają „parametry”, czyli symbole wieloznaczne, które ujawniają dopasowane dane w wywołaniu zwrotnym. Cloud Firestore uruchamia wywołanie zwrotne za każdym razem, gdy dodawane są nowe wiadomości.

W Node.js funkcje sterowane zdarzeniami, takie jak zdarzenia Cloud Firestore, są asynchroniczne. Funkcja wywołania zwrotnego powinna zwrócić wartość null , Object lub Promise . Jeśli nic nie zwrócisz, funkcja przekroczy limit czasu, sygnalizując błąd, i zostanie ponowiona. Zobacz Synchronizacja, asynchronizacja i obietnice .

Emuluj wykonywanie swoich funkcji

Pakiet Firebase Local Emulator Suite umożliwia tworzenie i testowanie aplikacji na komputerze lokalnym zamiast wdrażania w projekcie Firebase. Zdecydowanie zalecane jest testowanie lokalne podczas programowania, częściowo dlatego, że zmniejsza to ryzyko błędów w kodowaniu, które mogą potencjalnie wiązać się z kosztami w środowisku produkcyjnym (na przykład nieskończona pętla).

Aby emulować swoje funkcje:

  1. Uruchom firebase emulators:start i sprawdź wynik adresu URL interfejsu użytkownika pakietu emulatorów. Domyślnie jest to localhost:4000 , ale może być hostowany na innym porcie na twoim komputerze. Wprowadź ten adres URL w przeglądarce, aby otworzyć interfejs użytkownika pakietu emulatorów.

  2. Sprawdź dane wyjściowe polecenia firebase emulators:start dla adresu URL funkcji HTTP. Będzie wyglądać podobnie do http://localhost:5001/MY_PROJECT/us-central1/addMessage , z tą różnicą, że:

    1. MY_PROJECT zostanie zastąpiony identyfikatorem Twojego projektu.
    2. Port może być inny na 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ść „wielką literą” na wiadomość niestandardową.

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

  5. Zobacz efekty funkcji w interfejsie użytkownika pakietu Emulator:

    1. Na karcie Dzienniki powinny pojawić się nowe dzienniki wskazujące, że funkcje HTTP zostały pomyślnie uruchomione:

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

    2. Na karcie Firestore powinieneś zobaczyć dokument zawierający oryginalną wiadomość, a także wersję wiadomości zapisaną wielkimi literami (jeśli pierwotnie była to „wielkie litery”, zobaczysz „WIELKIE LITERY”).

Wdrażaj funkcje w środowisku produkcyjnym

Gdy funkcje będą działać zgodnie z oczekiwaniami w emulatorze, możesz przystąpić do ich wdrażania, testowania i uruchamiania w środowisku produkcyjnym. Pamiętaj, że aby wdrożyć projekt w środowisku produkcyjnym, Twój projekt musi być objęty planem cenowym Blaze . Zobacz ceny Cloud Functions .

Aby ukończyć samouczek, wdróż funkcje, a następnie je wykonaj.

  1. Uruchom to polecenie, aby wdrożyć funkcje:

     firebase deploy --only functions
     

    Po uruchomieniu tego polecenia interfejs CLI Firebase wyświetla adres URL dowolnych punktów końcowych funkcji HTTP. W terminalu powinieneś zobaczyć linię podobną do poniższej:

    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 martwić, niektóre produkcyjne funkcje HTTP powinny określać lokalizację , aby zminimalizować opóźnienia sieci.

    Jeśli napotkasz błędy dostępu, takie jak „Nie można autoryzować dostępu do projektu”, spróbuj sprawdzić alias swojego projektu .

  2. Korzystając z adresu URL wyświetlanego przez CLI, dodaj parametr zapytania tekstowego i otwórz go w przeglądarce:

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

    Funkcja wykonuje i przekierowuje przeglądarkę do konsoli Firebase w lokalizacji bazy danych, w której przechowywany jest ciąg tekstowy. To zdarzenie zapisu wyzwala funkcję „make wielkie litery”, która zapisuje ciąg znaków w wersji pisanej wielkimi literami.

Po wdrożeniu i wykonaniu funkcji możesz przeglądać logi w konsoli Google Cloud . Jeśli chcesz usunąć funkcje w fazie programistycznej lub produkcyjnej, użyj interfejsu wiersza polecenia Firebase.

W środowisku produkcyjnym możesz chcieć zoptymalizować wydajność funkcji i kontrolować koszty, ustawiając minimalną i maksymalną liczbę uruchamianych instancji. Aby uzyskać więcej informacji na temat tych opcji środowiska wykonawczego, zobacz Kontrolowanie zachowania skalowania .

Następne kroki

W tej dokumentacji możesz dowiedzieć się więcej o zarządzaniu funkcjami Cloud Functions, a także o obsłudze wszystkich typów zdarzeń obsługiwanych przez Cloud Functions.

Aby dowiedzieć się więcej o funkcjach chmury, możesz również wykonać następujące czynności: