Zarządzanie funkcjami (1 generacji)

Funkcje możesz wdrażać, usuwać i modyfikować za pomocą poleceń CLI Firebase lub przez ustawienie opcji środowiska wykonawczego w kodzie źródłowym funkcji.

Wdrażanie funkcji

Aby wdrożyć funkcje, uruchom to Firebase polecenie CLI:

firebase deploy --only functions

Domyślnie Firebase CLI wdraża jednocześnie wszystkie funkcje w źródle. Jeśli Twój projekt zawiera więcej niż 5 funkcji, zalecamy użycie flagi --only z nazwami konkretnych funkcji, aby wdrożyć tylko te funkcje, które zostały przez Ciebie edytowane. Wdrażanie w ten sposób konkretnych funkcji przyspiesza proces wdrażania i pomaga uniknąć przekroczenia limitów wdrażania. Przykład:

firebase deploy --only functions:addMessage,functions:makeUppercase

Podczas wdrażania dużej liczby funkcji możesz przekroczyć standardowy limit i otrzymać komunikaty o błędach HTTP 429 lub 500. Aby rozwiązać ten problem, wdrażaj funkcje w grupach po 10 lub mniej.

Pełną listę dostępnych poleceń znajdziesz w dokumentacji Firebase CLI.

Domyślnie Firebase CLI szuka kodu źródłowego w folderze functions/ dla. Jeśli wolisz, możesz uporządkować funkcje w bazach kodu lub w wielu zestawach plików.

Usuwanie funkcji

Wcześniej wdrożone funkcje możesz usunąć na te sposoby:

  • jawnie w Firebase CLI za pomocą functions:delete
  • jawnie w konsoli Google Cloud.
  • niejawnie przez usunięcie funkcji ze źródła przed wdrożeniem.

Wszystkie operacje usuwania wymagają potwierdzenia przed usunięciem funkcji ze środowiska produkcyjnego.

Jawne usuwanie funkcji w Firebase CLI obsługuje wiele argumentów oraz grupy funkcji i umożliwia określenie funkcji działającej w danym regionie. Możesz też zastąpić prośbę o potwierdzenie.

  • Usuwa wszystkie funkcje pasujące do podanej nazwy we wszystkich regionach:

    firebase functions:delete FUNCTION-1_NAME

  • Usuwa określoną funkcję działającą w regionie innym niż domyślny:

    firebase functions:delete FUNCTION-1_NAME --region REGION_NAME

  • Usuwa więcej niż 1 funkcję:

    firebase functions:delete FUNCTION-1_NAME FUNCTION-2_NAME

  • Usuwa określoną grupę funkcji:

    firebase functions:delete GROUP_NAME

  • Pomija prośbę o potwierdzenie:

    firebase functions:delete FUNCTION-1_NAME --force

W przypadku niejawnego usuwania funkcji polecenie firebase deploy analizuje źródło i usuwa ze środowiska produkcyjnego wszystkie funkcje, które zostały usunięte z pliku.

Zmienianie nazwy, regionu lub aktywatora funkcji

Jeśli zmieniasz nazwę, regiony lub aktywator funkcji obsługujących ruch produkcyjny, wykonaj czynności opisane w tej sekcji, aby uniknąć utraty zdarzeń podczas modyfikacji. Zanim wykonasz te czynności, upewnij się, że Twoja funkcja jest idempotentna, ponieważ podczas zmiany będą jednocześnie działać zarówno nowa, jak i stara wersja funkcji.

Zmienianie nazwy funkcji

Aby zmienić nazwę funkcji, utwórz w źródle nową wersję funkcji o zmienionej nazwie, a następnie uruchom 2 oddzielne polecenia wdrażania. Pierwsze polecenie wdraża funkcję nazwaną o nowej nazwie, a drugie usuwa wcześniej wdrożoną wersję. Jeśli na przykład masz funkcję Node.js o nazwie webhook, którą chcesz zmienić na webhookNew, zmień kod w ten sposób:

// before
const functions = require('firebase-functions/v1');

exports.webhook = functions.https.onRequest((req, res) => {
    res.send("Hello");
});

// after
const functions = require('firebase-functions/v1');

exports.webhookNew = functions.https.onRequest((req, res) => {
    res.send("Hello");
});

Następnie uruchom te polecenia, aby wdrożyć nową funkcję:

# Deploy new function called webhookNew
firebase deploy --only functions:webhookNew

# Wait until deployment is done; now both webhookNew and webhook are running

# Delete webhook
firebase functions:delete webhook

Zmienianie regionu lub regionów funkcji

Jeśli zmieniasz określone regiony funkcji obsługującej ruch produkcyjny, możesz zapobiec utracie zdarzeń, wykonując te czynności w podanej kolejności:

  1. Zmień nazwę funkcji i jej region lub regiony.
  2. Wdróż funkcję o zmienionej nazwie, co spowoduje tymczasowe uruchomienie tego samego kodu w obu zestawach regionów.
  3. Usuń poprzednią funkcję.

Jeśli na przykład masz funkcję o nazwie webhook, która obecnie znajduje się w domyślnym regionie funkcji us-central1, i chcesz ją przenieść do asia-northeast1, musisz najpierw zmodyfikować kod źródłowy, aby zmienić nazwę funkcji i region.

// before
const functions = require('firebase-functions/v1');

exports.webhook = functions
    .https.onRequest((req, res) => {
            res.send("Hello");
    });

// after
const functions = require('firebase-functions/v1');

exports.webhookAsia = functions
    .region('asia-northeast1')
    .https.onRequest((req, res) => {
            res.send("Hello");
    });

Następnie wdróż, uruchamiając to polecenie:

firebase deploy --only functions:webhookAsia

Teraz działają 2 identyczne funkcje: webhook w regionie us-central1, i webhookAsia w regionie asia-northeast1.

Następnie usuń funkcję webhook:

firebase functions:delete webhook

Teraz jest tylko 1 funkcja – webhookAsia, która działa w regionie asia-northeast1.

Zmienianie typu aktywatora funkcji

W miarę rozwijania w czasie wdrożenia Cloud Functions for Firebase z różnych powodów może być konieczne zmienienie typu aktywatora funkcji. Możesz na przykład chcieć zmienić typ zdarzenia Firebase Realtime Database lub Cloud Firestore na inny.

Nie można zmienić typu zdarzenia funkcji, zmieniając tylko kod źródłowy i uruchamiając polecenie firebase deploy. Aby uniknąć błędów, zmień typ aktywatora funkcji, wykonując te czynności:

  1. Zmodyfikuj kod źródłowy, aby dodać nową funkcję z odpowiednim typem aktywatora.
  2. Wdróż funkcję, co spowoduje tymczasowe uruchomienie zarówno starej, jak i nowej funkcji.
  3. Jawnie usuń starą funkcję ze środowiska produkcyjnego za pomocą Firebase CLI.

Jeśli na przykład masz funkcję Node.js o nazwie objectChanged z typem zdarzenia onChange, a chcesz zmienić go na onFinalize, najpierw zmień nazwę funkcji i edytuj ją, aby miała typ zdarzenia onFinalize.

// before
const functions = require('firebase-functions/v1');

exports.objectChanged = functions.storage.object().onChange((object) => {
    return console.log('File name is: ', object.name);
});

// after
const functions = require('firebase-functions/v1');

exports.objectFinalized = functions.storage.object().onFinalize((object) => {
    return console.log('File name is: ', object.name);
});

Następnie uruchom te polecenia, aby najpierw utworzyć nową funkcję, a potem usunąć starą:

# Create new function objectFinalized
firebase deploy --only functions:objectFinalized

# Wait until deployment is done; now both objectChanged and objectFinalized are running

# Delete objectChanged
firebase functions:delete objectChanged

Ustawianie opcji środowiska wykonawczego

Cloud Functions for Firebase umożliwia wybieranie opcji środowiska wykonawczego, takich jak wersja środowiska wykonawczego Node.js , limit czasu dla funkcji, alokacja pamięci oraz minimalna i maksymalna liczba instancji funkcji.

Zalecamy, aby te opcje (z wyjątkiem wersji Node.js) były ustawiane w obiekcie konfiguracji w kodzie funkcji. Ten RuntimeOptions obiekt jest źródłem informacji o opcjach środowiska wykonawczego funkcji i zastąpi opcje ustawione za pomocą innej metody (np. konsoli Google Cloud lub gcloud CLI).

Jeśli w procesie programowania ręcznie ustawiasz opcje środowiska wykonawczego za pomocą Google Cloud konsoli lub gcloud CLI i nie chcesz, aby te wartości były zastępowane przy każdym wdrożeniu, ustaw opcję preserveExternalChanges na true. Gdy ta opcja jest ustawiona na true, Firebase łączy opcje środowiska wykonawczego ustawione w kodzie z ustawieniami aktualnie wdrożonej wersji funkcji w tej kolejności:

  1. Opcja jest ustawiona w kodzie funkcji: zastąp zmiany zewnętrzne.
  2. Opcja jest ustawiona na RESET_VALUE w kodzie funkcji: zastąp zmiany zewnętrzne wartością domyślną.
  3. Opcja nie jest ustawiona w kodzie funkcji, ale jest ustawiona w aktualnie wdrożonej funkcji: użyj opcji określonej we wdrożonej funkcji.

Używanie opcji preserveExternalChanges: true nie jest zalecane w większości przypadków, ponieważ kod nie będzie już pełnym źródłem informacji o opcjach środowiska wykonawczego funkcji. Jeśli jednak jej używasz, sprawdź konsolę Google Cloud lub użyj gcloud CLI, aby wyświetlić pełną konfigurację funkcji.

Ustawianie wersji Node.js

Firebase SDK for Cloud Functions umożliwia wybór środowiska wykonawczego Node.js. Możesz uruchamiać wszystkie funkcje w projekcie wyłącznie w środowisku wykonawczym odpowiadającym jednej z tych obsługiwanych wersji Node.js:

  • Node.js 22
  • Node.js 20
  • Node.js 18 (wycofana)

Ważne informacje o bieżącym wsparciu tych wersji Node.js znajdziesz w harmonogramie wsparcia.

Aby ustawić wersję Node.js:

Wersję możesz ustawić w polu engines w pliku package.json, który został utworzony w katalogu functions/ podczas inicjowania. Jeśli na przykład chcesz używać tylko wersji 20, edytuj ten wiersz w pliku package.json:

  "engines": {"node": "22"}

Jeśli używasz menedżera pakietów Yarn lub masz inne konkretne wymagania dotyczące pola engines, możesz zamiast tego ustawić środowisko wykonawcze dla Firebase SDK for Cloud Functions w firebase.json:

  {
    "functions": {
      "runtime": "nodejs22"
    }
  }

Interfejs wiersza poleceń używa wartości ustawionej w pliku firebase.json zamiast dowolnej wartości lub zakresu, które ustawisz osobno w pliku package.json.

Aktualizowanie środowiska wykonawczego Node.js

Aby zaktualizować środowisko wykonawcze Node.js:

  1. Upewnij się, że Twój projekt korzysta z planu taryfowego Blaze.
  2. Upewnij się, że używasz Firebase CLI w wersji 11.18.0 lub nowszej.
  3. Zmień wartość engines w pliku package.json, który został utworzony w katalogu functions/ podczas inicjowania. Jeśli na przykład aktualizujesz wersję 16 do wersji 18, wpis powinien wyglądać tak: "engines": {"node": "18"}
  4. Opcjonalnie przetestuj zmiany za pomocą Firebase Local Emulator Suite.
  5. Wdróż ponownie wszystkie funkcje.

Wybieranie systemu modułów Node.js

Domyślnym systemem modułów w Node.js jest CommonJS (CJS), ale obecne wersje Node.js obsługują też moduły ECMAScript (ESM). Cloud Functions obsługuje oba te systemy.

Domyślnie funkcje używają CommonJS. Oznacza to, że importy i eksporty wyglądają tak:

const functions = require("firebase-functions/v1");

exports.helloWorld = functions.https.onRequest(async (req, res) => res.send("Hello from Firebase!"));

Aby zamiast tego używać ESM, ustaw pole "type": "module" w pliku package.json :

  {
   ...
   "type": "module",
   ...
  }

Gdy to ustawisz, użyj składni import i export ESM:

import functions from "firebase-functions/v1";

export const helloWorld = functions.https.onRequest(async (req, res) => res.send("Hello from Firebase!"));

Oba systemy modułów są w pełni obsługiwane. Możesz wybrać ten, który najlepiej pasuje do Twojego projektu. Więcej informacji znajdziesz w dokumentacji Node.js na temat modułów.

Kontrolowanie zachowania przy skalowaniu

Domyślnie Cloud Functions for Firebase skaluje liczbę działających instancji na podstawie liczby żądań przychodzących, co może spowodować zmniejszenie liczby instancji do zera w okresach mniejszego ruchu. Jeśli jednak Twoja aplikacja wymaga krótszego czasu oczekiwania i chcesz ograniczyć liczbę uruchomień „na zimno”, możesz zmienić to domyślne działanie, określając minimalną liczbę instancji kontenera, które mają być utrzymywane w gotowości do obsługi żądań.

Podobnie możesz ustawić maksymalną liczbę instancji, aby ograniczyć skalowanie instancji w odpowiedzi na żądania przychodzące. Użyj tego ustawienia, aby kontrolować koszty lub ograniczyć liczbę połączeń z usługą wspierającą, np. z bazą danych.

Zmniejszanie liczby uruchomień „na zimno”

Aby ustawić minimalną liczbę instancji funkcji w kodzie źródłowym, użyj runWith metody. Ta metoda akceptuje obiekt JSON zgodny z RuntimeOptions interfejsem, który określa wartość minInstances. Ta funkcja ustawia na przykład minimalną liczbę 5 instancji, które mają być utrzymywane w gotowości:

exports.getAutocompleteResponse = functions
    .runWith({
      // Keep 5 instances warm for this latency-critical function
      minInstances: 5,
    })
    .https.onCall((data, context) => {
      // Autocomplete a user's search term
    });

Oto kilka kwestii, które należy wziąć pod uwagę podczas ustawiania wartości minInstances:

  • Jeśli Cloud Functions for Firebase skaluje Twoją aplikację powyżej ustawienia minInstances, dla każdej instancji powyżej tego progu nastąpi uruchomienie „na zimno”.
  • Uruchomienia „na zimno” mają największy wpływ na aplikacje z nagłymi skokami ruchu. Jeśli Twoja aplikacja ma nagłe skoki ruchu i ustawisz wartość minInstances na tyle wysoką, że uruchomienia „na zimno” będą rzadsze przy każdym wzroście ruchu, zauważysz znaczne skrócenie czasu oczekiwania. W przypadku aplikacji ze stałym ruchem uruchomienia „na zimno” nie powinny mieć znaczącego wpływu na wydajność.
  • Ustawianie minimalnej liczby instancji może mieć sens w środowiskach produkcyjnych, ale zwykle należy go unikać w środowiskach testowych. Aby skalować do zera w projekcie testowym, ale nadal ograniczać uruchomienia „na zimno” w projekcie produkcyjnym, możesz ustawić minInstances na podstawie zmiennej środowiskowej FIREBASE_CONFIG:

    // Get Firebase project id from `FIREBASE_CONFIG` environment variable
    const envProjectId = JSON.parse(process.env.FIREBASE_CONFIG).projectId;
    
    exports.renderProfilePage = functions
        .runWith({
          // Keep 5 instances warm for this latency-critical function
          // in production only. Default to 0 for test projects.
          minInstances: envProjectId === "my-production-project" ? 5 : 0,
        })
        .https.onRequest((req, res) => {
          // render some html
        });
    

Ograniczanie maksymalnej liczby instancji funkcji

Aby ustawić maksymalną liczbę instancji w kodzie źródłowym funkcji, użyj metody.runWith Ta metoda akceptuje obiekt JSON zgodny z RuntimeOptions interfejsem, który określa wartości dla maxInstances. Ta funkcja ustawia na przykład limit 100 instancji, aby nie przeciążać hipotetycznej starszej bazy danych:

exports.mirrorOrdersToLegacyDatabase = functions
    .runWith({
      // Legacy database only supports 100 simultaneous connections
      maxInstances: 100,
    })
    .firestore.document("orders/{orderId}")
    .onWrite((change, context) => {
      // Connect to legacy database
    });

Jeśli funkcja HTTP zostanie przeskalowana do limitu maxInstances, nowe żądania będą przez 30 sekund umieszczane w kolejce, a następnie odrzucane z kodem odpowiedzi 429 Too Many Requests, jeśli do tego czasu nie będzie dostępna żadna instancja.

Więcej informacji o sprawdzonych metodach korzystania z ustawień maksymalnej liczby instancji znajdziesz w tych sprawdzonych metodach korzystania z maxInstances.

Ustawianie konta usługi

Domyślne konto usługi dla funkcji 1. generacji, PROJECT_ID@appspot.gserviceaccount.com (nazywane App Engine default service account), ma szeroki zakres uprawnień, które umożliwiają interakcję z innymi usługami Firebase i Google Cloud.

Możesz zastąpić domyślne konto usługi i ograniczyć funkcję do dokładnych zasobów, których potrzebuje. Możesz to zrobić, tworząc niestandardowe konto usługi i przypisując je do odpowiedniej funkcji za pomocą metody .runWith(). Ta metoda przyjmuje obiekt z opcjami konfiguracji, w tym właściwość serviceAccount.

const functions = require("firebase-functions/v1");

exports.helloWorld = functions
    .runWith({
        // This function doesn't access other Firebase project resources, so it uses a limited service account.
        serviceAccount:
            "my-limited-access-sa@", // or prefer the full form: "my-limited-access-sa@my-project.iam.gserviceaccount.com"
    })
    .https.onRequest((request, response) => {
        response.send("Hello from Firebase!");
    });

Ustawianie limitu czasu i alokacji pamięci

W niektórych przypadkach funkcje mogą mieć specjalne wymagania dotyczące długiego limitu czasu lub dużego przydziału pamięci. Te wartości możesz ustawić w konsoli Google Cloud lub w kodzie źródłowym funkcji (tylko w Firebase).

Aby ustawić alokację pamięci i limit czasu w kodzie źródłowym funkcji, użyj parametru wprowadzonego w Firebase SDK for Cloud Functions 2.0.0.runWith Ta opcja środowiska wykonawczego akceptuje obiekt JSON zgodny z RuntimeOptions interfejsem, który określa wartości timeoutSeconds i memory. Ta funkcja pamięci masowej używa na przykład 1 GB pamięci i przekracza limit czasu po 300 sekundach:

exports.convertLargeFile = functions
    .runWith({
      // Ensure the function has enough memory and time
      // to process large files
      timeoutSeconds: 300,
      memory: "1GB",
    })
    .storage.object()
    .onFinalize((object) => {
      // Do some complicated things that take a lot of memory and time
    });

Maksymalna wartość timeoutSeconds to 540, czyli 9 minut. Ilość pamięci przyznanej funkcji odpowiada procesorowi przydzielonemu do funkcji, co zostało szczegółowo opisane na tej liście prawidłowych wartości memory:

  • 128MB – 200 MHz
  • 256MB – 400 MHz
  • 512MB – 800 MHz
  • 1GB – 1,4 GHz
  • 2GB – 2,4 GHz
  • 4GB – 4,8 GHz
  • 8GB – 4,8 GHz

Aby ustawić alokację pamięci i limit czasu w konsoli Google Cloud:

  1. W konsoli Google Cloud w menu po Cloud Functions stronie wybierz.
  2. Wybierz funkcję, klikając jej nazwę na liście funkcji.
  3. W menu u góry kliknij ikonę Edytuj.
  4. Wybierz **alokację pamięci** z menu rozwijanego oznaczonego jako Memory allocated.
  5. W menu kliknij Więcej , aby wyświetlić opcje zaawansowane, a następnie wpisz liczbę sekund w polu tekstowym Limit czasu.
  6. Aby zaktualizować funkcję, kliknij Zapisz.