Często będziesz potrzebować dodatkowej konfiguracji funkcji, np. kluczy interfejsu API innej firmy lub ustawień, które można dostosować. Pakiet Firebase SDK dla Cloud Functions oferuje wbudowaną konfigurację środowiska, która ułatwia przechowywanie i pobieranie tego typu danych w projekcie.
Możesz wybrać jedną z tych opcji:
- Konfiguracja sparametryzowana (zalecana w większości przypadków). Zapewnia ona konfigurację środowiska z silnym typowaniem i parametrami, które są weryfikowane podczas wdrażania, co zapobiega błędom i upraszcza debugowanie.
- Konfiguracja zmiennych środowiskowych na podstawie plików. W tym przypadku ręcznie tworzysz plik dotenv do wczytywania zmiennych środowiskowych.
W większości przypadków zalecamy konfigurację sparametryzowaną. Dzięki temu wartości konfiguracji są dostępne zarówno w czasie wykonywania, jak i wdrażania, a wdrożenie jest blokowane, dopóki wszystkie parametry nie mają prawidłowej wartości. Z kolei konfiguracja ze zmiennymi środowiskowymi nie jest dostępna w czasie wdrażania.
Konfiguracja sparametryzowana
Cloud Functions for Firebase udostępnia interfejs do deklaratywnego definiowania parametrów konfiguracji w bazie kodu. Wartość tych parametrów jest dostępna zarówno podczas wdrażania funkcji, gdy ustawiasz opcje wdrożenia i środowiska wykonawczego, jak i podczas wykonywania. Oznacza to, że interfejs wiersza poleceń zablokuje wdrożenie, dopóki wszystkie parametry nie będą miały prawidłowej wartości.
Aby zdefiniować parametry w kodzie, postępuj zgodnie z tym modelem:
const functions = require('firebase-functions/v1');
const { defineInt, defineString } = require('firebase-functions/params');
// Define some parameters
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
const welcomeMessage = defineString('WELCOME_MESSAGE');
// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
(req, res) => {
res.send(`${welcomeMessage.value()}! I am a function.`);
}
);
Podczas wdrażania funkcji ze sparametryzowanymi zmiennymi konfiguracji wiersz poleceń Firebase najpierw próbuje wczytać ich wartości z lokalnych plików .env. Jeśli nie ma ich w tych plikach i nie ustawiono wartości default, interfejs CLI poprosi o
wartości podczas wdrażania, a następnie automatycznie zapisze je w pliku
.env o nazwie .env.<project_ID> w katalogu functions/:
$ firebase deploy
i functions: preparing codebase default for deployment
? Enter a string value for ENVIRONMENT: prod
i functions: Writing new parameter values to disk: .env.projectId
…
$ firebase deploy
i functions: Loaded environment variables from .env.projectId
W zależności od przepływu pracy dewelopera może być przydatne dodanie wygenerowanego pliku .env.<project_ID> do systemu kontroli wersji.
Używanie parametrów w zakresie globalnym
Podczas wdrażania kod funkcji jest wczytywany i sprawdzany, zanim parametry uzyskają rzeczywiste wartości. Oznacza to, że pobieranie wartości parametrów w zakresie globalnym powoduje niepowodzenie wdrożenia. Jeśli chcesz użyć parametru do zainicjowania wartości globalnej, użyj wywołania zwrotnego inicjowania onInit(). To wywołanie zwrotne jest wykonywane przed uruchomieniem funkcji w środowisku produkcyjnym, ale nie jest wywoływane podczas wdrażania, dlatego jest bezpiecznym miejscem na dostęp do wartości parametru.
const { GoogleGenerativeAI } = require('@google/generative-ai');
const { defineSecret } = require('firebase-functions/params');
const { onInit } = require('firebase-functions/v1');
const apiKey = defineSecret('GOOGLE_API_KEY');
let genAI;
onInit(() => {
genAI = new GoogleGenerativeAI(apiKey.value());
})
Konfigurowanie działania interfejsu wiersza poleceń
Parametry można skonfigurować za pomocą obiektu Options, który określa, jak interfejs CLI będzie prosić o wartości. Ten przykład ustawia opcje, które sprawdzają format numeru telefonu, udostępniają prostą opcję wyboru i automatycznie wypełniają opcję wyboru z projektu w Firebase:
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE', {default: 'Hello World',
description: 'The greeting that is returned to the caller of this function'});
const onlyPhoneNumbers = defineString('PHONE_NUMBER', {input: {text:
{validationRegex: /\d{3}-\d{3}-\d{4}/, validationErrorMessage: "Please enter
a phone number in the format XXX-YYY-ZZZZ"}}});
const selectedOption = defineString('PARITY', {input: {select: {options:
[{value: "odd"}, {value: "even"}]}}})
const storageBucket = defineString('BUCKET', {input: {resource: {type:
"storage.googleapis.com/Bucket"}}, description: "This will automatically
populate the selector field with the deploying Cloud Project’s
storage buckets"})
Typy parametrów
Konfiguracja sparametryzowana zapewnia silne typowanie wartości parametrów, a także obsługuje obiekty tajne z usługi Cloud Secret Manager. Obsługiwane typy to:
- Obiekt tajny
- Ciąg znaków
- Wartość logiczna
- Liczba całkowita
- Liczba zmiennoprzecinkowa
Informacje o funkcjach definiowania parametrów znajdziesz w dokumentacji przestrzeni nazw params.
Wartości i wyrażenia parametrów
Firebase ocenia parametry zarówno podczas wdrażania, jak i podczas wykonywania funkcji. Ze względu na te 2 środowiska należy zachować szczególną ostrożność podczas porównywania wartości parametrów i używania ich do ustawiania opcji środowiska wykonawczego funkcji.
Aby przekazać parametr do funkcji jako opcję środowiska wykonawczego, przekaż go bezpośrednio:
const functions = require('firebase-functions/v1');
const { defineInt} = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
(req, res) => {
//…
Jeśli musisz porównać parametr, aby wiedzieć, którą opcję wybrać, musisz użyć wbudowanych komparatorów zamiast sprawdzać wartość:
const functions = require('firebase-functions/v1');
const { defineBool } = require('firebase-functions/params');
const environment = params.defineString(‘ENVIRONMENT’, {default: ‘dev’});
// use built-in comparators
const minInstancesConfig =environment.equals('PRODUCTION').thenElse(10, 1);
export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
(req, res) => {
//…
Do parametrów i wyrażeń parametrów, które są używane tylko w czasie wykonywania, można uzyskać dostęp za pomocą funkcji value:
const functions = require('firebase-functions/v1');
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE');
// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = functions.https.onRequest(
(req, res) => {
res.send(`${welcomeMessage.value()}! I am a function.`);
}
);
Wbudowane parametry
Pakiet Cloud Functions SDK oferuje 3 predefiniowane parametry dostępne w podpakiecie firebase-functions/params:
projectID– projekt w chmurze, w którym działa funkcja.databaseURL– adres URL instancji Bazy danych czasu rzeczywistego powiązanej z funkcją (jeśli jest włączona w projekcie w Firebase).storageBucket– zasobnik Cloud Storage powiązany z funkcją (jeśli jest włączony w projekcie w Firebase).
Te funkcje są pod każdym względem podobne do zdefiniowanych przez użytkownika parametrów ciągu znaków, z tym wyjątkiem, że ich wartości są zawsze znane wierszowi poleceń Firebase, więc nie będą wyświetlane podczas wdrażania ani zapisywane w plikach .env.
Parametry obiektu tajnego
Parametry typu Secret zdefiniowane za pomocą defineSecret() reprezentują parametry ciągu znaków
, których wartość jest przechowywana w usłudze Cloud Secret Manager. Zamiast sprawdzać lokalny plik .env i zapisywać w nim nową wartość, jeśli jej brakuje, parametry obiektu tajnego sprawdzają, czy obiekt tajny istnieje w usłudze Cloud Secret Manager, i interaktywnie proszą o wartość nowego obiektu tajnego podczas wdrażania.
Parametry obiektu tajnego zdefiniowane w ten sposób muszą być powiązane z poszczególnymi funkcjami, które powinny mieć do nich dostęp:
const functions = require('firebase-functions/v1');
const { defineSecret } = require('firebase-functions/params');
const discordApiKey = defineSecret('DISCORD_API_KEY');
export const postToDiscord = functions.runWith({ secrets: [discordApiKey] }).https.onRequest(
(req, res) => {
const apiKey = discordApiKey.value();
//…
Zmienne środowiskowe
Cloud Functions for Firebase obsługuje format pliku
dotenv
do wczytywania zmiennych środowiskowych określonych w pliku .env do środowiska wykonawczego aplikacji. Po wdrożeniu zmienne środowiskowe można odczytać za pomocą
process.env
interfejsu.
Aby skonfigurować środowisko w ten sposób, utwórz w projekcie plik .env, dodaj do niego odpowiednie zmienne i wdróż:
Utwórz plik
.envw katalogufunctions/:# Directory layout: # my-project/ # firebase.json # functions/ # .env # package.json # index.jsOtwórz plik
.envdo edycji i dodaj odpowiednie klucze. Przykład:PLANET=Earth AUDIENCE=HumansWdróż funkcje i sprawdź, czy zmienne środowiskowe zostały wczytane:
firebase deploy --only functions # ... # i functions: Loaded environment variables from .env. # ...
Po wdrożeniu niestandardowych zmiennych środowiskowych
kod funkcji może uzyskać do nich dostęp za pomocą
process.env
składni:
// Responds with "Hello Earth and Humans"
exports.hello = functions.https.onRequest((request, response) => {
response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});
Wdrażanie wielu zestawów zmiennych środowiskowych
Jeśli potrzebujesz alternatywnego zestawu zmiennych środowiskowych dla projektów Firebase (np. środowiska testowego i produkcyjnego), utwórz plik
.env.<project or
alias> i zapisz w nim
zmienne środowiskowe specyficzne dla projektu. Zmienne środowiskowe z plików .env i .env specyficznych dla projektu (jeśli istnieją) zostaną uwzględnione we wszystkich wdrożonych funkcjach.
Na przykład projekt może zawierać te 3 pliki z nieco innymi wartościami na potrzeby programowania i środowiska produkcyjnego:
.env
|
.env.dev
|
.env.prod
|
| PLANET=Earth
AUDIENCE=Humans |
AUDIENCE=Dev Humans | AUDIENCE=Prod Humans |
W zależności od wartości w tych osobnych plikach zestaw zmiennych środowiskowych wdrożonych z funkcjami będzie się różnić w zależności od projektu docelowego:
$ firebase use dev
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.dev.
# Deploys functions with following user-defined environment variables:
# PLANET=Earth
# AUDIENCE=Dev Humans
$ firebase use prod
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.prod.
# Deploys functions with following user-defined environment variables:
# PLANET=Earth
# AUDIENCE=Prod Humans
Zarezerwowane zmienne środowiskowe
Niektóre klucze zmiennych środowiskowych są zarezerwowane do użytku wewnętrznego. Nie używaj żadnego z tych kluczy w plikach .env:
- Wszystkie klucze zaczynające się od X_GOOGLE_
- Wszystkie klucze zaczynające się od EXT_
- Wszystkie klucze zaczynające się od FIREBASE_
- Dowolny klucz z tej listy:
- CLOUD_RUNTIME_CONFIG
- ENTRY_POINT
- GCP_PROJECT
- GCLOUD_PROJECT
- GOOGLE_CLOUD_PROJECT
- FUNCTION_TRIGGER_TYPE
- FUNCTION_NAME
- FUNCTION_MEMORY_MB
- FUNCTION_TIMEOUT_SEC
- FUNCTION_IDENTITY
- FUNCTION_REGION
- FUNCTION_TARGET
- FUNCTION_SIGNATURE_TYPE
- K_SERVICE
- K_REVISION
- PORT
- K_CONFIGURATION
Przechowywanie poufnych informacji o konfiguracji i uzyskiwanie do nich dostępu
Zmienne środowiskowe przechowywane w plikach .env mogą być używane do konfiguracji funkcji, ale nie należy ich traktować jako bezpiecznego sposobu przechowywania informacji poufnych, takich jak dane logowania do bazy danych czy klucze interfejsu API. Jest to szczególnie ważne, jeśli pliki .env są sprawdzane w systemie kontroli wersji.
Aby ułatwić przechowywanie poufnych informacji o konfiguracji, Cloud Functions for Firebase integruje się z Google Cloud Secret Manager. Ta zaszyfrowana usługa bezpiecznie przechowuje wartości konfiguracji, a jednocześnie umożliwia łatwy dostęp do nich z funkcji w razie potrzeby.
Tworzenie obiektu tajnego i używanie go
Aby utworzyć obiekt tajny, użyj interfejsu Firebase CLI.
Aby utworzyć obiekt tajny i go używać:
W katalogu głównym projektu lokalnego uruchom to polecenie:
firebase functions:secrets:set SECRET_NAME
Wpisz wartość dla SECRET_NAME.
Interfejs CLI wyświetli komunikat o powodzeniu i ostrzeżenie, że aby zmiana została zastosowana, musisz wdrożyć funkcje.
Przed wdrożeniem upewnij się, że kod funkcji umożliwia funkcji dostęp do obiektu tajnego za pomocą parametru
runWith:exports.processPayment = functions // Make the secret available to this function .runWith({ secrets: ["SECRET_NAME"] }) .onCall((data, context) => { const myBillingService = initializeBillingService( // reference the secret value process.env.SECRET_NAME ); // Process the payment });Wdróż Cloud Functions:
firebase deploy --only functions
Teraz możesz uzyskać do niego dostęp jak do każdej innej zmiennej środowiskowej.
Z kolei jeśli inna funkcja, która nie określa obiektu tajnego w runWith, spróbuje uzyskać do niego dostęp, otrzyma wartość nieokreśloną:
exports.anotherEndpoint = functions.https.onRequest((request, response) => {
response.send(`The secret API key is ${process.env.SECRET_NAME}`);
// responds with "The secret API key is undefined" because the `runWith` parameter is missing
});
Po wdrożeniu funkcja będzie mieć dostęp do wartości obiektu tajnego. Tylko funkcje, które wyraźnie uwzględniają obiekt tajny w parametrze runWith, będą mieć do niego dostęp jako do zmiennej środowiskowej. Pomaga to zapewnić, że wartości obiektów tajnych są dostępne tylko tam, gdzie są potrzebne, co zmniejsza ryzyko przypadkowego ujawnienia obiektu tajnego.
Zarządzanie obiektami tajnymi
Do zarządzania obiektami tajnymi używaj interfejsu Firebase CLI. Podczas zarządzania obiektami tajnymi w ten sposób pamiętaj, że niektóre zmiany w interfejsie CLI wymagają zmodyfikowania lub ponownego wdrożenia powiązanych funkcji. Więcej szczegółów:
- Za każdym razem, gdy ustawisz nową wartość obiektu tajnego, musisz ponownie wdrożyć wszystkie funkcje, które się do niego odwołują, aby mogły one pobrać najnowszą wartość.
- Jeśli usuniesz obiekt tajny, upewnij się, że żadna z wdrożonych funkcji się do niego nie odwołuje. Funkcje, które używają usuniętej wartości obiektu tajnego, będą działać bez zgłaszania błędów.
Oto podsumowanie poleceń interfejsu Firebase CLI do zarządzania obiektami tajnymi:
# Change the value of an existing secret firebase functions:secrets:set SECRET_NAME # View the value of a secret functions:secrets:access SECRET_NAME # Destroy a secret functions:secrets:destroy SECRET_NAME # View all secret versions and their state functions:secrets:get SECRET_NAME # Automatically clean up all secrets that aren't referenced by any of your functions functions:secrets:prune
W przypadku poleceń access i destroy możesz podać opcjonalny parametr wersji, aby zarządzać konkretną wersją. Przykład:
functions:secrets:access SECRET_NAME[@VERSION]
Więcej informacji o tych operacjach znajdziesz, wpisując polecenie z opcją -h, aby wyświetlić pomoc interfejsu CLI.
Jak rozliczane są obiekty tajne
Secret Manager umożliwia bezpłatne korzystanie z 6 aktywnych wersji obiektów tajnych. Oznacza to, że w projekcie Firebase możesz mieć bezpłatnie 6 obiektów tajnych miesięcznie.
Domyślnie interfejs Firebase CLI próbuje automatycznie niszczyć nieużywane wersje obiektów tajnych
, np. gdy wdrażasz funkcje z nową wersją
obiektu tajnego. Możesz też aktywnie usuwać nieużywane obiekty tajne za pomocą poleceń functions:secrets:destroy i functions:secrets:prune.
Secret Manager umożliwia 10 tys. bezpłatnych operacji dostępu do obiektu tajnego miesięcznie na
secret. Instancje funkcji odczytują tylko obiekty tajne określone w opcji secrets za każdym razem, gdy następuje zimny start. Jeśli masz wiele instancji funkcji odczytujących wiele obiektów tajnych, Twój projekt może przekroczyć ten limit. W takim przypadku opłata wyniesie 0,03 USD za 10 tys. operacji dostępu.
Więcej informacji znajdziesz w Secret Manager cenniku.
Obsługa emulatora
Konfiguracja środowiska za pomocą dotenv jest zaprojektowana tak, aby współpracować z lokalnym Cloud Functions emulatorem.
Gdy używasz lokalnego Cloud Functions emulatora, możesz zastąpić zmienne środowiskowe
projektu, konfigurując plik .env.local. Zawartość pliku
.env.local ma pierwszeństwo przed plikiem .env i plikiem .env specyficznym dla projektu.
Na przykład projekt może zawierać te 3 pliki z nieco innymi wartościami na potrzeby programowania i testowania lokalnego:
.env
|
.env.dev
|
.env.local
|
| PLANET=Earth
AUDIENCE=Humans |
AUDIENCE=Dev Humans | AUDIENCE=Local Humans |
Po uruchomieniu w kontekście lokalnym emulator wczytuje zmienne środowiskowe w ten sposób:
$ firebase emulators:start
i emulators: Starting emulators: functions
# Starts emulator with following environment variables:
# PLANET=Earth
# AUDIENCE=Local Humans
Obiekty tajne i dane logowania w emulatorze Cloud Functions
Emulator Cloud Functions obsługuje używanie obiektów tajnych do przechowywania poufnych informacji o konfiguracji i uzyskiwania do nich dostępu. Domyślnie emulator będzie próbował uzyskać dostęp do obiektów tajnych w środowisku produkcyjnym za pomocą domyślnych danych logowania aplikacji. W niektórych sytuacjach, np. w środowiskach CI, emulator może nie mieć dostępu do wartości obiektów tajnych z powodu ograniczeń uprawnień.
Podobnie jak w przypadku obsługi zmiennych środowiskowych w Cloud Functions emulatorze, możesz
zastąpić wartości obiektów tajnych, konfigurując plik .secret.local. Ułatwia to testowanie funkcji lokalnie, zwłaszcza jeśli nie masz dostępu do wartości obiektu tajnego.
Migracja z konfiguracji środowiska wykonawczego
Interfejs functions.config API został wycofany i zostanie wyłączony w marcu 2027 r.
Po tym terminie wdrożenia z functions.config będą się nie powodzić.
Aby zapobiec niepowodzeniom wdrożenia, przeprowadź migrację konfiguracji do usługi Cloud Secret Manager za pomocą interfejsu Firebase CLI. Jest to zdecydowanie zalecane jako najskuteczniejszy i najbezpieczniejszy sposób migracji konfiguracji.
Eksportowanie konfiguracji za pomocą interfejsu Firebase CLI
Użyj polecenia
config export, aby wyeksportować dotychczasową konfigurację środowiska do nowego obiektu tajnego w usłudze Cloud Secret Manager:$ firebase functions:config:export i This command retrieves your Runtime Config values (accessed via functions.config()) and exports them as a Secret Manager secret. i Fetching your existing functions.config() from your project... ✔ Fetched your existing functions.config(). i Configuration to be exported: ⚠ This may contain sensitive data. Do not share this output. { ... } ✔ What would you like to name the new secret for your configuration? RUNTIME_CONFIG ✔ Created new secret version projects/project/secrets/RUNTIME_CONFIG/versions/1```Aktualizowanie kodu funkcji w celu powiązania obiektów tajnych
Aby używać konfiguracji przechowywanej w nowym obiekcie tajnym w usłudze Cloud Secret Manager, użyj w kodzie funkcji interfejsu
defineJsonSecretAPI. Upewnij się też, że obiekty tajne są powiązane ze wszystkimi funkcjami, które ich potrzebują.Przed
const functions = require("firebase-functions/v1"); exports.myFunction = functions.https.onRequest((req, res) => { const apiKey = functions.config().someapi.key; // ... });Po
const { onRequest } = require("firebase-functions/v2/https"); const { defineJsonSecret } = require("firebase-functions/params"); const config = defineJsonSecret("RUNTIME_CONFIG"); exports.myFunction = onRequest( // Bind secret to your function { secrets: [config] }, (req, res) => { // Access secret values via .value() const apiKey = config.value().someapi.key; // ... });Wdrażanie funkcji
Wdróż zaktualizowane funkcje, aby zastosować zmiany i powiązać uprawnienia do obiektu tajnego.
firebase deploy --only functions:<your-function-name>
Automatycznie wypełniane zmienne środowiskowe
Istnieją zmienne środowiskowe, które są automatycznie wypełniane w środowisku wykonawczym funkcji i w funkcjach emulowanych lokalnie. Obejmują one zmienne wypełniane przez Google Cloud, a także zmienną środowiskową specyficzną dla Firebase:
process.env.FIREBASE_CONFIG: zawiera te informacje o konfiguracji projektu w Firebase:
{
databaseURL: 'https://DATABASE_NAME.firebaseio.com',
storageBucket: 'PROJECT_ID.firebasestorage.app ',
projectId: 'PROJECT_ID'
}
Pamiętaj, że wartości w rzeczywistej konfiguracji Firebase mogą się różnić w zależności od zasobów, które zostały udostępnione w projekcie.
Ta konfiguracja jest stosowana automatycznie, gdy inicjujesz pakiet Firebase Admin SDK bez argumentów. Jeśli piszesz funkcje w JavaScript, zainicjuj je w ten sposób:
const admin = require('firebase-admin');
admin.initializeApp();
Jeśli piszesz funkcje w TypeScript, zainicjuj je w ten sposób:
import * as functions from 'firebase-functions/v1';
import * as admin from 'firebase-admin';
import 'firebase-functions/v1';
admin.initializeApp();
Jeśli musisz zainicjować pakiet Admin SDK z domyślną konfiguracją projektu przy użyciu danych logowania konta usługi, możesz wczytać dane logowania z pliku i dodać je do FIREBASE_CONFIG w ten sposób:
serviceAccount = require('./serviceAccount.json');
const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
adminConfig.credential = admin.credential.cert(serviceAccount);
admin.initializeApp(adminConfig);