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 i obejmuje tworzenie, testowanie i wdrażanie 2 powiązanych funkcji:

  • funkcję „dodaj wiadomość”, która udostępnia adres URL akceptujący wartość tekstową i zapisujący ją w Cloud Firestore;
  • Funkcja „zmień na wielkie litery”, która jest aktywowana przez 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/https");
const {onDocumentCreated} = require("firebase-functions/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});
});

Python

# 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})

Informacje o tym samouczku

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

W kolejnych sekcjach tego samouczka znajdziesz szczegółowe instrukcje tworzenia, testowania i wdrażania przykładowej aplikacji.

Tworzenie projektu w Firebase

Nowy użytkownik Firebase lub Cloud

Jeśli dopiero zaczynasz korzystać z Firebase lub Google Cloud, wykonaj te czynności.
Możesz też wykonać te czynności, jeśli chcesz utworzyć zupełnie nowy projekt w Firebase (i powiązany z nim projekt Google Cloud).

  1. Zaloguj się w konsoli Firebase.
  2. Kliknij przycisk, aby utworzyć nowy projekt w Firebase.
  3. W polu tekstowym wpisz nazwę projektu.

    Jeśli należysz do organizacji Google Cloud, możesz opcjonalnie wybrać folder, w którym chcesz utworzyć projekt.

  4. Jeśli pojawi się taka prośba, przeczytaj i zaakceptuj Warunki korzystania z Firebase, a następnie kliknij Dalej.
  5. (Opcjonalnie) Włącz pomoc AI w konsoli Firebase (nazywaną „Gemini w Firebase”), która może pomóc Ci rozpocząć pracę i usprawnić proces programowania.
  6. (Opcjonalnie) Skonfiguruj Google Analytics w projekcie, aby zapewnić optymalne działanie tych usług Firebase: Firebase A/B Testing, Cloud Messaging, Crashlytics, In-App Messaging i Remote Config (w tym Personalizacja).

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

  7. Kliknij Utwórz projekt.

Firebase utworzy projekt, udostępni niektóre zasoby początkowe i włączy ważne interfejsy API. Po zakończeniu procesu otworzy się strona przeglądu projektu w Firebase w konsoli Firebase.

Istniejący projekt w chmurze

Jeśli chcesz zacząć korzystać z Firebase w dotychczasowym projekcie Google Cloud, wykonaj te czynności. Dowiedz się więcej o dodawaniu Firebase do istniejącego projektu Google Cloud i rozwiązywaniu problemów z tym związanych.

  1. Zaloguj się w konsoli Firebase na konto, które daje Ci dostęp do istniejącego projektu Google Cloud.
  2. Kliknij przycisk, aby utworzyć nowy projekt w Firebase.
  3. U dołu strony kliknij Add Firebase to Google Cloud project (Dodaj Firebase do projektu Google Cloud).
  4. W polu tekstowym zacznij wpisywać nazwę projektu, a następnie wybierz projekt z wyświetlonej listy.
  5. Kliknij Otwórz projekt.
  6. Jeśli pojawi się taka prośba, przeczytaj i zaakceptuj Warunki korzystania z Firebase, a następnie kliknij Dalej.
  7. (Opcjonalnie) Włącz pomoc AI w konsoli Firebase (nazywaną „Gemini w Firebase”), która może pomóc Ci rozpocząć pracę i usprawnić proces programowania.
  8. (Opcjonalnie) Skonfiguruj Google Analytics w projekcie, aby zapewnić optymalne działanie tych usług Firebase: Firebase A/B Testing, Cloud Messaging, Crashlytics, In-App Messaging i Remote Config (w tym Personalizacja).

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

  9. Kliknij Dodaj Firebase.

Firebase dodaje Firebase do istniejącego projektu. Po zakończeniu procesu otworzy się strona przeglądu projektu w Firebase w konsoli Firebase.

Konfigurowanie środowiska i interfejsu wiersza poleceń Firebase

Node.js

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

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

npm install -g firebase-tools

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

Python

Do pisania funkcji potrzebne jest środowisko Python, a do wdrażania funkcji w środowisku wykonawczym Cloud Functions – interfejs wiersza poleceń Firebase. Zalecamy użycie venv do odizolowania zależności. Obsługiwane są wersje Pythona od 3.10 do 3.13, przy czym domyślnym środowiskiem wykonawczym jest wersja 3.13.

Po zainstalowaniu Pythona zainstaluj interfejs wiersza poleceń Firebase w wybrany przez siebie sposób.

Inicjowanie projektu

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

Aby zainicjować projekt:

  1. Uruchom firebase login, aby zalogować się przez przeglądarkę 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 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 Pierwsze kroki z Cloud Firestore.
  4. Uruchom firebase init functions. Interfejs wiersza poleceń poprosi Cię 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 rozszerzysz implementację, możesz uporządkować funkcje w bazach kodu.
  5. Interfejs wiersza poleceń udostępnia te opcje obsługi języków:

    • JavaScript
    • TypeScript
    • Python

    Na potrzeby tego samouczka wybierz JavaScript lub Python. Informacje o tworzeniu funkcji w TypeScript znajdziesz w artykule Pisanie funkcji w TypeScript.

  6. Interfejs wiersza poleceń umożliwia zainstalowanie zależności. Możesz bezpiecznie odrzucić tę opcję, jeśli chcesz zarządzać zależnościami w inny sposób.

Po wykonaniu tych poleceń struktura projektu będzie wyglądać tak:

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 inicjowania 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.

Python

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

Importowanie wymaganych modułów i inicjowanie aplikacji

Po ukończeniu zadań konfiguracyjnych możesz otworzyć katalog źródłowy i zacząć dodawać kod zgodnie z opisem w kolejnych sekcjach. W tym przykładzie projekt musi importować moduły Cloud Functions i pakiet Admin SDK. Dodaj do pliku źródłowego wiersze podobne do tych:

Node.js

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

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

initializeApp();

Python

# 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 wiersze wczytują wymagane moduły i inicjują instancję aplikacji admin, z której można wprowadzać zmiany w Cloud Firestore. Wszędzie tam, gdzie dostępna jest obsługa pakietu Admin SDK, czyli w przypadku FCM, Authentication i Firebase Realtime Database, zapewnia on zaawansowany sposób integracji Firebase przy użyciu Cloud Functions.

Interfejs wiersza poleceń Firebase automatycznie instaluje pakiet Firebase Admin SDK i moduły pakietu SDK Firebase dla Cloud Functions podczas inicjowania projektu. Więcej informacji o dodawaniu bibliotek innych firm do projektu znajdziesz w artykule o obsłudze zależności.

Dodawanie funkcji „dodaj wiadomość”

W przypadku funkcji „add message” dodaj do pliku źródłowego te wiersze:

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

Python

@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 „add message” jest punktem końcowym HTTP. Każde żądanie wysłane do punktu końcowego powoduje przekazanie obiektów żądania i odpowiedzi do modułu obsługi żądań na Twojej platformie (onRequest() lub on_request).

Funkcje HTTP są synchroniczne (podobnie jak funkcje wywoływalne), więc należy jak najszybciej wysłać odpowiedź i odroczyć pracę za pomocą Cloud Firestore. Funkcja HTTP „add message” przekazuje wartość tekstową do punktu końcowego HTTP i wstawia ją do bazy danych w ścieżce /messages/:documentId/original.

Dodawanie funkcji „zamień na wielkie litery”

W przypadku funkcji „make uppercase” dodaj do pliku źródłowego te wiersze:

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

Python

@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 uppercase” jest wykonywana, gdy następuje zapis w Cloud Firestore, co definiuje dokument, który ma być nasłuchiwany. Ze względu na wydajność należy podać jak najwięcej szczegółów.

Nawiasy klamrowe, np. {documentId}, otaczają „parametry”, czyli symbole wieloznaczne, które ujawniają dopasowane dane w wywołaniu zwrotnym. Cloud Firestore wywołuje 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 zwracać wartość null, obiekt lub obietnicę. Jeśli nic nie zwrócisz, funkcja przekroczy limit czasu, sygnalizując błąd, i zostanie ponowiona. Zobacz Synchronizacja, asynchronizacja i obiekty Promise.

Emulowanie wykonywania funkcji

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

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ć hostowany na innym porcie na Twoim komputerze. Wpisz ten adres URL w przeglądarce, aby otworzyć Emulator Suite UI.

  2. Sprawdź dane wyjściowe polecenia firebase emulators:start, aby znaleźć adres URL funkcji HTTP. Będzie on wyglądać podobnie do http://localhost:5001/MY_PROJECT/us-central1/addMessage, z tymi wyjątkami:

    1. MY_PROJECT zostanie zastąpiony identyfikatorem Twojego projektu.
    2. Port na komputerze lokalnym może być inny.
  3. Dodaj ciąg zapytania ?text=uppercaseme na końcu adresu URL funkcji. Powinna ona wyglądać mniej więcej tak: http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme. Opcjonalnie możesz zmienić wiadomość „uppercaseme” na niestandardową.

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

  5. Zobacz efekty działania funkcji w Emulator Suite UI:

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

      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ę zapisaną wielkimi literami (jeśli oryginalna wiadomość to „zamieńnawielkielitery”, zobaczysz „ZAMIEŃNAWIELKIELITERY”).

wdrażać funkcje 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ć funkcję w środowisku produkcyjnym, Twój projekt musi być objęty abonamentem Blaze. Sprawdź ceny Cloud Functions.

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

  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ę następujący wiersz:

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

    Adres URL zawiera identyfikator projektu oraz region funkcji HTTP. Nie musisz się tym teraz przejmować, ale niektóre produkcyjne funkcje HTTP powinny określać lokalizację, aby zminimalizować opóźnienie sieci.

    Jeśli wystąpią błędy dostępu, takie jak „Nie udało się autoryzować dostępu do projektu”, sprawdź aliasy projektu.

  2. Używając adresu URL wygenerowanego przez interfejs wiersza poleceń, dodaj parametr zapytania tekstowego i otwórz go w przeglądarce:

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

    Funkcja zostanie wykonana i przekieruje przeglądarkę do konsoli Firebase w lokalizacji bazy danych, w której przechowywany jest ciąg tekstowy. To zdarzenie zapisu aktywuje funkcję „make uppercase”, która zapisuje wersję ciągu znaków pisaną 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 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 artykule o kontrolowaniu zachowania skalowania.

Dalsze kroki

Z tej dokumentacji dowiesz się, jak zarządzać funkcjami w Cloud Functions oraz 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: