Często funkcje wymagają dodatkowej konfiguracji, 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 silnie typizowaną konfigurację środowiska z parametrami, które są weryfikowane podczas wdrażania, co zapobiega błędom i upraszcza debugowanie.
- Konfiguracja zmiennych środowiskowych na podstawie pliku. W tym przypadku ręcznie tworzysz plik dotenv, aby wczytać zmienne środowiskowe.
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.
Node.js
const { onRequest } = require('firebase-functions/v2/https');
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 = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
res.send(`${welcomeMessage.value()}! I am a function.`);
}
);
Python
from firebase_functions import https_fn
from firebase_functions.params import IntParam, StringParam
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
WELCOME_MESSAGE = StringParam("WELCOME_MESSAGE")
# To use configured parameters inside the config for a function, provide them
# directly. To use them at runtime, call .value() on them.
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
return https_fn.Response(f'{WELCOME_MESSAGE.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 wiersza poleceń 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 jakichkolwiek funkcji w środowisku produkcyjnym, ale nie jest wywoływane podczas wdrażania, dlatego jest bezpiecznym miejscem na dostęp do wartości parametru.
Node.js
const { GoogleGenerativeAI } = require('@google/generative-ai');
const { defineSecret } = require('firebase-functions/params');
const { onInit } = require('firebase-functions/v2/core');
const apiKey = defineSecret('GOOGLE_API_KEY');
let genAI;
onInit(() => {
genAI = new GoogleGenerativeAI(apiKey.value());
})
Python
from firebase_functions.core import init
from firebase_functions.params import StringParam, PROJECT_ID
import firebase_admin
import vertexai
location = StringParam("LOCATION")
x = "hello"
@init
def initialize():
# Note: to write back to a global, you'll need to use the "global" keyword
# to avoid creating a new local with the same name.
global x
x = "world"
firebase_admin.initialize_app()
vertexai.init(PROJECT_ID.value, location.value)
Jeśli używasz parametrów typu Secret, pamiętaj, że są one dostępne tylko w procesie funkcji, które mają powiązany obiekt tajny. Jeśli obiekt tajny jest powiązany tylko z niektórymi funkcjami, przed jego użyciem sprawdź, czy secret.value() ma wartość fałszywą.
Konfigurowanie działania interfejsu wiersza poleceń
Parametry można skonfigurować za pomocą obiektu Options, który określa, jak interfejs wiersza poleceń 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:
Node.js
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: params.select(["odd", "even"])});
const memory = defineInt("MEMORY", {
description: "How much memory do you need?",
input: params.select({ "micro": 256, "chonky": 2048 }),
});
const extensions = defineList("EXTENSIONS", {
description: "Which file types should be processed?",
input: params.multiSelect(["jpg", "tiff", "png", "webp"]),
});
const storageBucket = defineString('BUCKET', {
description: "This will automatically
populate the selector field with the deploying Cloud Project’s
storage buckets",
input: params.PICK_STORAGE_BUCKET,
});
Python
from firebase_functions.params import (
StringParam,
ListParam,
TextInput,
SelectInput,
SelectOptions,
ResourceInput,
ResourceType,
)
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
WELCOME_MESSAGE = StringParam(
"WELCOME_MESSAGE",
default="Hello World",
description="The greeting that is returned to the caller of this function",
)
ONLY_PHONE_NUMBERS = StringParam(
"PHONE_NUMBER",
input=TextInput(
validation_regex="\d{3}-\d{3}-\d{4}",
validation_error_message="Please enter a phone number in the format XXX-YYY-XXX",
),
)
SELECT_OPTION = StringParam(
"PARITY",
input=SelectInput([SelectOptions(value="odd"), SelectOptions(value="even")]),
)
STORAGE_BUCKET = StringParam(
"BUCKET",
input=ResourceInput(type=ResourceType.STORAGE_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:
- Obiekt tajny
- Ciąg znaków
- Wartość logiczna
- Liczba całkowita
- Liczba zmiennoprzecinkowa
- Lista (Node.js)
- Obiekt tajny JSON (Node.js)
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:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineInt } = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
export const helloWorld = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
//…
Python
from firebase_functions import https_fn
from firebase_functions.params import IntParam
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
...
Dodatkowo, jeśli musisz porównać parametr, aby wiedzieć, którą opcję wybrać, musisz użyć wbudowanych komparatorów zamiast sprawdzać wartość:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const environment = params.defineString(‘ENVIRONMENT’, {default: 'dev'});
// use built-in comparators
const minInstancesConfig = environment.equals('PRODUCTION').thenElse(10, 1);
export const helloWorld = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
//…
Python
from firebase_functions import https_fn
from firebase_functions.params import IntParam, StringParam
ENVIRONMENT = StringParam("ENVIRONMENT", default="dev")
MIN_INSTANCES = ENVIRONMENT.equals("PRODUCTION").then(10, 0)
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
...
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:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
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 = onRequest(
(req, res) => {
res.send(`${welcomeMessage.value()}! I am a function.`);
}
);
Python
from firebase_functions import https_fn
from firebase_functions.params import StringParam
WELCOME_MESSAGE = StringParam("WELCOME_MESSAGE")
@https_fn.on_request()
def hello_world(req):
return https_fn.Response(f'{WELCOME_MESSAGE.value()}! I am a function!')
Parametry wbudowane
Pakiet Cloud Functions SDK oferuje 3 predefiniowane parametry dostępne w podpakiecie firebase-functions/params:
Node.js
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).
Python
PROJECT_ID– projekt w chmurze, w którym działa funkcja.DATABASE_URL– adres URL instancji Bazy danych czasu rzeczywistego powiązanej z funkcją (jeśli jest włączona w projekcie w Firebase).STORAGE_BUCKET– 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 muszą być powiązane z poszczególnymi funkcjami, które powinny mieć do nich dostęp:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineSecret } = require('firebase-functions/params');
const discordApiKey = defineSecret('DISCORD_API_KEY');
export const postToDiscord = onRequest(
{ secrets: [discordApiKey] },
(req, res) => {
const apiKey = discordApiKey.value();
//…
Python
from firebase_functions import https_fn
from firebase_functions.params import SecretParam
DISCORD_API_KEY = SecretParam('DISCORD_API_KEY')
@https_fn.on_request(secrets=[DISCORD_API_KEY])
def post_to_discord(req):
api_key = DISCORD_API_KEY.value
Ponieważ wartości obiektów tajnych są ukryte do czasu wykonania funkcji, nie można ich używać podczas konfigurowania funkcji.
Obiekty tajne w formacie JSON
Jeśli masz kilka wartości konfiguracji, które są logicznie powiązane (np. ustawienia usługi innej firmy), możesz je przechowywać razem jako uporządkowany obiekt JSON w jednym obiekcie tajnym za pomocą defineJsonSecret(). To podejście może pomóc w uporządkowaniu konfiguracji i efektywniejszym wykorzystaniu bezpłatnego pakietu Cloud Secret Manager, ponieważ umożliwia przechowywanie grupy powiązanych wartości konfiguracji w jednym obiekcie tajnym.
Wartość przechowywana w usłudze Secret Manager musi być prawidłowym ciągiem znaków JSON. Gdy uzyskasz dostęp do .value(), pakiet SDK automatycznie przeanalizuje ciąg znaków JSON i przekształci go w obiekt JavaScript.
Przykład:
const { onRequest } = require('firebase-functions/v2/https');
const { defineJsonSecret } = require('firebase-functions/params');
// Define a single secret to hold all configuration for some API
const someApiConfig = defineJsonSecret('SOMEAPI_CONFIG');
exports.myApi = onRequest(
{ secrets: [someApiConfig] },
(req, res) => {
// someApiConfig.value() automatically parses the JSON secret
const { apiKey, webhookSecret, clientId } = someApiConfig.value();
// Now you can use apiKey, webhookSecret, clientId
// ...
}
);
Aby utworzyć obiekt tajny SOMEAPI_CONFIG, ustaw jego wartość w usłudze Secret Manager na ciąg znaków JSON, np.:
{
"apiKey": "key_...",
"webhookSecret": "secret_...",
"clientId": "client_..."
}
Jeśli wartość obiektu tajnego nie jest prawidłowym plikiem JSON, dostęp do someApiConfig.value() spowoduje błąd w czasie wykonywania.
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ą interfejsu
process.env (w projektach opartych na Node.js) lub
os.environ (w
projektach opartych na Pythonie).
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:
Node.js
// Responds with "Hello Earth and Humans"
exports.hello = onRequest((request, response) => {
response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});
Python
import os
@https_fn.on_request()
def hello(req):
return https_fn.Response(
f"Hello {os.environ.get('PLANET')} and {os.environ.get('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 |
Biorąc pod uwagę 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 wiersza poleceń 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 jej dostęp do obiektu tajnego za pomocą opcji
secrets:Node.js
const { onRequest } = require('firebase-functions/v2/https'); exports.processPayment = onRequest( { secrets: ["SECRET_NAME"] }, (req, res) => { const myBillingService = initializeBillingService( // reference the secret value process.env.SECRET_NAME ); // Process the payment } );Python
import os from firebase_functions import https_fn @https_fn.on_request(secrets=["SECRET_NAME"]) def process_payment(req): myBillingService = initialize_billing(key=os.environ.get('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, spróbuje uzyskać do niego dostęp, otrzyma wartość niezdefiniowaną:
Node.js
exports.anotherEndpoint = onRequest((request, response) => { response.send(`The secret API key is ${process.env.SECRET_NAME}`); // responds with "The secret API key is undefined" because the `secrets` option is missing });Python
@https_fn.on_request() def another_endpoint(req): return https_fn.Response(f"The secret API key is {os.environ.get("SECRET_NAME")}") # Responds with "The secret API key is None" because the `secrets` 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 opcji secrets, 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 wiersza poleceń 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ą się nie powodzić bez wyświetlania komunikatu.
Oto podsumowanie poleceń interfejsu Firebase CLI do zarządzania obiektami tajnymi:
# Change the value of an existing secret firebase functions:secrets:set SECRET_NAME # Set secret from file firebase functions:secrets:set SECRET_NAME --data-file file.json # Validate secret value as json cat file.json | firebase functions:secrets:set SECRET_NAME --format=json # Pipe from stdin and set secret cat file.json | firebase functions:secrets:set SECRET_NAME --format=json # 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, przekazując -h wraz z poleceniem, aby wyświetlić pomoc interfejsu wiersza poleceń.
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 usuwać 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 uruchomienie „na zimno”. Jeśli masz wiele instancji funkcji, które odczytują wiele obiektów tajnych, Twój projekt może przekroczyć ten limit. W takim przypadku zostanie naliczona opłata w wysokości 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);