Zarządzaj funkcjami


Funkcje możesz wdrażać, usuwać i modyfikować za pomocą poleceń wiersza poleceń Firebase lub ustawiając opcje czasu wykonywania w kodzie źródłowym funkcji.

Wdrażanie funkcji

Aby wdrożyć funkcje, uruchom to polecenie wiersza poleceń Firebase:

firebase deploy --only functions

Domyślnie wiersz poleceń Firebase wdraża wszystkie funkcje w Twoim źródle w tym samym czasie. Jeśli Twój projekt zawiera więcej niż 5 funkcji, zalecamy użycie parametru --only z określonymi nazwami funkcji, aby wdrożyć tylko zmodyfikowane przez Ciebie funkcje. Wdrażanie określonych funkcji w ten sposób 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 tego uniknąć, stosuj funkcje w grupach liczących co najwyżej 10 elementów.

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

Domyślnie interfejs wiersza poleceń Firebase szuka kodu źródłowego w folderze functions/. Jeśli wolisz, możesz uporządkować funkcje w kodzie źródłowym lub w kilku zestawach plików.

Usuwanie funkcji

Funkcję, która została już wdrożona, możesz usunąć na jeden z tych sposobów:

  • wyraźnie w interfejsie wiersza poleceń Firebase za pomocą polecenia functions:delete.
  • wyraźnieGoogle Cloud konsoli.
  • Domyślnie, usuwając funkcję ze źródła przed wdrożeniem.

Przed usunięciem funkcji z produkcji musisz potwierdzić wszystkie operacje usuwania.

Wyraźne usuwanie funkcji w CLI Firebase obsługuje wiele argumentów, a także grupy funkcji i pozwala określić funkcję działającą w określonym regionie. Możesz też zignorować prośbę o potwierdzenie.

# Delete all functions that match the specified name in all regions.
firebase functions:delete myFunction
# Delete a specified function running in a specific region.
firebase functions:delete myFunction --region us-east-1
# Delete more than one function
firebase functions:delete myFunction myOtherFunction
# Delete a specified functions group.
firebase functions:delete groupA
# Bypass the confirmation prompt.
firebase functions:delete myFunction --force

Przy domyślnym usuwaniu funkcji firebase deploy analizuje kod źródłowy i usuwa z wersji produkcyjnej wszystkie funkcje, które zostały usunięte z pliku.

Zmiana nazwy, regionu lub aktywatora funkcji

Jeśli zmieniasz nazwy regionów lub ich inicjatory lub zmieniasz je w przypadku funkcji, które obsługują ruch produkcyjny, wykonaj czynności opisane w tym rozdziale, aby uniknąć utraty zdarzeń podczas modyfikacji. Zanim wykonasz te czynności, upewnij się, że funkcja jest idempotentna, ponieważ podczas zmiany będą działać jednocześnie nowa i stara wersja funkcji.

Zmiana nazwy funkcji

Aby zmienić nazwę funkcji, utwórz nową wersję funkcji w źródle i uruchom 2 osobne polecenia wdrożenia. Pierwsze polecenie wdraża funkcję o nowej nazwie, a drugie usuwa wcześniej wdrożony wariant. Jeśli np. masz funkcję Node.js o nazwie webhook, którą chcesz zmienić na webhookNew, zmodyfikuj 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

Zmiana regionu lub regionów funkcji

Jeśli zmieniasz określone regiony w przypadku funkcji, która obsługuje ruch produkcyjny, możesz zapobiec utracie zdarzeń, wykonując te czynności w kolejności:

  1. Zmień nazwę funkcji i w razie potrzeby zmień jej region lub regiony.
  2. Wdróż przemianowaną funkcję, 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 znajduje się obecnie w domyślnym regionie funkcji us-central1, i chcesz ją przenieść do regionu asia-northeast1, musisz najpierw zmodyfikować kod źródłowy, aby zmienić nazwę funkcji i zaktualizować 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óż, wykonując te czynności:

firebase deploy --only functions:webhookAsia

Teraz są uruchomione 2 identyczne funkcje: webhook w kontekście us-central1webhookAsia w kontekście asia-northeast1.

Następnie usuń webhook:

firebase functions:delete webhook

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

Zmiana typu wyzwalacza funkcji

W miarę rozwijania wdrożenia Cloud Functions for Firebase może być konieczna zmiana typu wyzwalacza z różnych powodów. Możesz na przykład zmienić jeden typ zdarzenia Firebase Realtime Database lub Cloud Firestore na inny.

Nie można zmienić typu zdarzenia funkcji, po prostu zmieniając kod źródłowy i uruchamiając firebase deploy. Aby uniknąć błędów, zmień typ okna funkcji:

  1. Zmodyfikuj kod źródłowy, aby uwzględnić nową funkcję z wybranym typem wyzwalacza.
  2. Wdroż funkcję, co spowoduje tymczasowe uruchomienie zarówno starej, jak i nowej funkcji.
  3. Usuń starą funkcję z produkcji za pomocą interfejsu wiersza poleceń Firebase.

Jeśli np. masz funkcję Node.js o nazwie objectChanged, która ma stary typ zdarzenia onChange, a chcesz ją zmienić na onFinalize, najpierw zmień nazwę funkcji i zmodyfikuj 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 utwórz nową funkcję, zanim usuniesz 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 wybranie opcji czasu wykonywania, takich jak wersja środowiska wykonawczego Node.js i czas oczekiwania na wykonanie funkcji, alokacja pamięci oraz minimalna i maksymalna liczba wystąpień funkcji.

Zgodnie ze sprawdzoną metodą te opcje (z wyjątkiem wersji Node.js) powinny być ustawiane w obiekcie konfiguracji w kodzie funkcji. Ten obiekt RuntimeOptions jest źródłem informacji o opcjach czasu wykonywania funkcji i zastąpi opcje ustawione za pomocą dowolnej innej metody (np. w konsoli Google Cloud lub w interfejsie wiersza poleceń gcloud).

Jeśli Twój proces rozwoju obejmuje ręczne ustawianie opcji czasu wykonywania w konsoli Google Cloud lub interfejsie wiersza poleceń gcloud 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 scala opcje środowiska wykonawczego określone w kodzie z ustawieniami obecnie wdrożonej wersji funkcji z tym priorytetem:

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

Nie zalecamy używania opcji preserveExternalChanges: true w większości scenariuszy, ponieważ Twój kod nie będzie już pełnym źródłem informacji o opcjach środowiska wykonawczego funkcji. Jeśli go używasz, wyświetl pełną konfigurację funkcji w konsoli Google Cloud lub za pomocą interfejsu wiersza poleceń gcloud.

Ustawianie wersji Node.js

Pakiet SDK Firebase dla usługi Cloud Functions umożliwia wybranie środowiska wykonawczego Node.js. Możesz zdecydować, aby wszystkie funkcje w projekcie były wykonywane wyłącznie w środowisku wykonawczym odpowiadającym jednej z tych obsługiwanych wersji Node.js:

  • Node.js 20 (wersja przedpremierowa)
  • Node.js 18
  • Node.js 16
  • Node.js 14

Aby ustawić wersję Node.js:

Wersję możesz ustawić w polu engines w pliku package.json, który został utworzony w katalogu functions/ podczas inicjalizacji. Aby na przykład używać tylko wersji 18, w pliku package.json zmodyfikuj ten wiersz:

  "engines": {"node": "18"}

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

  {
    "functions": {
      "runtime": "nodejs18" // or nodejs14, nodejs16 or nodejs20
    }
  }

CLI używa wartości ustawionej w parasm firebase.json zamiast wartości lub zakresu ustawionego oddzielnie w parasm package.json.

Uaktualnianie środowiska wykonawczego Node.js

Aby uaktualnić środowisko wykonawcze Node.js:

  1. Upewnij się, że Twój projekt jest objęty abonamentem Blaze.
  2. Upewnij się, że używasz Firebase CLI w wersji 11.18.0 lub nowszej.
  3. Zmień wartość engines w pliku package.json utworzonym w katalogu functions/ podczas inicjalizacji. Jeśli na przykład przechodzisz z wersji 16 na wersję 18, wpis powinien wyglądać tak: "engines": {"node": "18"}
  4. Opcjonalnie możesz przetestować zmiany za pomocą Firebase Local Emulator Suite.
  5. ponownie wdrożyć wszystkie funkcje.

Kontrolowanie zachowania przy skalowaniu

Domyślnie usługa Cloud Functions for Firebase skaluje liczbę uruchomionych instancji na podstawie liczby żądań przychodzących. W czasie zmniejszonego ruchu może zmniejszyć liczbę instancji do zera. 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ę, aby ograniczyć skalowanie instancji w odpowiedzi na przychodzące żądania. Użyj tego ustawienia, aby kontrolować koszty lub ograniczyć liczbę połączeń z usługą wspierającą, np. z bazą danych.

Zmniejsz liczbę uruchomień „na zimno”

Aby ustawić minimalną liczbę instancji funkcji w źródle kodu, użyj metody runWith. Ta metoda przyjmuje obiekt JSON zgodny z interfejsem RuntimeOptions, który definiuje wartość minInstances. Na przykład ta funkcja ustawia minimalną liczbę instancji na 5, aby utrzymać je 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
    });

Podczas ustawiania wartości parametru minInstances warto wziąć pod uwagę te kwestie:

  • Jeśli Cloud Functions for Firebase zwiększy skalę aplikacji powyżej ustawienia minInstances, uruchomienie „na zimno” będzie się odbywać w przypadku każdego wystąpienia powyżej tego progu.
  • Uruchomienia „na zimno” mają największy wpływ na aplikacje z nieregularnym ruchem. Jeśli ruch w Twojej aplikacji jest nieregularny i ustawisz wartość minInstances na tyle wysoką, że zmniejszy się liczba zimnych uruchomień przy każdym wzroście natężenia ruchu, zauważysz znacznie mniejsze opóźnienie. W przypadku aplikacji o stałym natężeniu ruchu uruchomienia „na zimno” prawdopodobnie nie będą miały dużego wpływu na wydajność.
  • Ustawienie minimalnej liczby instancji może być uzasadnione w środowiskach produkcyjnych, ale zazwyczaj nie zaleca się tego w środowiskach testowych. Aby zmniejszyć liczbę uruchomień „na zimno” w projekcie produkcyjnym, ale nie zmieniać skali w projekcie testowym, 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 przyjmuje obiekt JSON zgodny z interfejsem RuntimeOptions, który definiuje wartości dla maxInstances. Na przykład ta funkcja ustawia limit 100 instansji, 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 zwiększona do limitu maxInstances, nowe żądania są umieszczane w kolejce na 30 sekund, a następnie odrzucane z kodem odpowiedzi 429 Too Many Requests, jeśli do tego czasu nie będzie dostępnej instancji.

Aby dowiedzieć się więcej o sprawdzonych metodach korzystania z ustawień maksymalnej liczby instancji, zapoznaj się z tymi sprawdzonymi metodami korzystania z maxInstances.

Ustawianie czasu oczekiwania i przydziału pamięci

W niektórych przypadkach funkcje mogą mieć specjalne wymagania dotyczące długiego limitu czasu lub dużej alokacji 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 runWith, który został wprowadzony w pakiecie SDK Firebase w wersji Cloud Functions 2.0.0. Ta opcja czasu wykonywania akceptuje obiekt JSON zgodny z interfejsem RuntimeOptions, który definiuje wartości timeoutSecondsmemory. Ta funkcja wykorzystuje 1 GB pamięci i wygasa 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ść dla timeoutSeconds to 540, czyli 9 minut. Ilość pamięci przyznanej funkcji odpowiada procesowi przydzielonemu funkcji, jak pokazano na tej liście prawidłowych wartości funkcji 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 Google Cloud wybierz Cloud Functions z menu po lewej stronie.
  2. Wybierz funkcję, klikając jej nazwę na liście funkcji.
  3. W menu u góry kliknij ikonę Edytuj.
  4. W menu Przydzielona pamięć wybierz przydział pamięci.
  5. Kliknij Więcej, aby wyświetlić opcje zaawansowane, i wpisz liczbę sekund w polu tekstowym Limit czasu.
  6. Aby zaktualizować funkcję, kliknij Zapisz.