Często funkcje wymagają dodatkowej konfiguracji, np. kluczy interfejsu API innych firm lub ustawień, które można dostosować. Pakiet SDK Firebase dla Cloud Functions oferuje wbudowaną konfigurację środowiska, która ułatwia przechowywanie i pobieranie tego typu danych w projekcie.
Do wyboru masz te opcje:
- Konfiguracja z parametrami (zalecana w większości przypadków). Zapewnia to silnie typowaną konfigurację środowiska z parametrami, które są weryfikowane w momencie wdrażania, co zapobiega błędom i upraszcza debugowanie.
- Konfiguracja zmiennych środowiskowych oparta na plikach. W tym podejściu ręcznie tworzysz plik dotenv do wczytywania zmiennych środowiskowych.
W większości przypadków zalecana jest konfiguracja sparametryzowana. Dzięki temu wartości konfiguracji są dostępne zarówno w czasie działania, jak i wdrażania, a wdrożenie jest blokowane, dopóki wszystkie parametry nie będą miały 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 wdrażania i środowiska wykonawczego, jak i podczas wykonywania. Oznacza to, że interfejs wiersza poleceń zablokuje wdrożenie, jeśli nie wszystkie parametry będą miały prawidłową wartość.
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 zmiennymi konfiguracji z parametrami 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 default, interfejs wiersza poleceń poprosi o podanie 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 procesu programowania warto dodać wygenerowany plik .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 uruchamiane przed uruchomieniem jakichkolwiek funkcji w środowisku produkcyjnym, ale nie jest wywoływane podczas wdrażania, więc jest to bezpieczne miejsce do uzyskiwania dostępu 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 powiązały dany obiekt tajny. Jeśli klucz tajny jest powiązany tylko z niektórymi funkcjami, przed użyciem sprawdź, czy secret.value() ma wartość fałsz.
Konfigurowanie działania interfejsu wiersza poleceń
Parametry można skonfigurować za pomocą obiektu Options, który kontroluje sposób, w jaki interfejs wiersza poleceń będzie prosić o wartości. W tym przykładzie ustawiono opcje sprawdzania formatu numeru telefonu, udostępniania prostej opcji wyboru i automatycznego wypełniania opcji 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 z parametrami zapewnia silne typowanie wartości parametrów, a także obsługuje obiekty tajne z Cloud Secret Managera. Obsługiwane typy to:
- Obiekt tajny
- Ciąg znaków
- Wartość logiczna
- Liczba całkowita
- Liczba zmiennoprzecinkowa
- Lista (Node.js)
- Obiekt tajny JSON (Node.js)
Informacje o funkcjach służących do 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 podwójne ś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):
...
Jeśli musisz porównać parametr, aby dowiedzieć się, którą opcję wybrać, użyj 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 działania, 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 SDK Cloud Functions udostępnia 3 wstępnie zdefiniowane parametry, które są dostępne w pakiecie podrzędnym 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).
Działają one pod każdym względem jak parametry ciągu znaków zdefiniowane przez użytkownika, z tym wyjątkiem, że ich wartości są zawsze znane interfejsowi wiersza poleceń Firebase, więc nigdy nie będą wyświetlane prośby o ich podanie podczas wdrażania ani nie będą 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 Cloud Secret Manager. Zamiast sprawdzać lokalny plik .env i zapisywać w nim nową wartość, jeśli jej brakuje, parametry obiektów tajnych sprawdzają, czy istnieją w Cloud Secret Manager, i interaktywnie proszą o wartość nowego obiektu tajnego podczas wdrażania.
Parametry obiektów tajnych 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
Wartości obiektów tajnych są ukryte do momentu wykonania funkcji, więc nie można ich używać podczas konfigurowania funkcji.
Uporządkowane obiekty tajne 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(). Takie podejście może pomóc w uporządkowaniu konfiguracji i efektywniejszym wykorzystaniu poziomu bezpłatnego Cloud Secret Managera dzięki przechowywaniu grupy powiązanych wartości konfiguracji w jednym obiekcie tajnym.
Wartość przechowywana w Secret Manager musi być prawidłowym ciągiem znaków JSON. Gdy uzyskasz dostęp do .value(), pakiet SDK automatycznie przeanalizuje ciąg JSON i przekształci go w obiekt w JavaScripcie.
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, musisz ustawić jego wartość w Secret Managerze na ciąg JSON, np.:
{
"apiKey": "key_...",
"webhookSecret": "secret_...",
"clientId": "client_..."
}
Jeśli wartość obiektu tajnego nie jest prawidłowym plikiem JSON, uzyskanie dostępu do someApiConfig.value() spowoduje błąd w czasie działania.
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 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 innego zestawu zmiennych środowiskowych dla projektów Firebase (np. przejściowych i produkcyjnych), utwórz plik .env.<project or
alias> i zapisz w nim zmienne środowiskowe dla konkretnego projektu. Zmienne środowiskowe z plików .env i plików .env powiązanych z projektem (jeśli istnieją) zostaną uwzględnione we wszystkich wdrożonych funkcjach.
Projekt może na przykład zawierać te 3 pliki z nieco innymi wartościami dla środowiska programistycznego i 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 informacji o konfiguracji poufnej 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ą przechowywane 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, gdy jest to potrzebne.
Tworzenie i używanie obiektu tajnego
Aby utworzyć obiekt tajny, użyj interfejsu wiersza poleceń Firebase.
Aby utworzyć obiekt tajny i go użyć:
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 zmiany zostały wprowadzone, 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 ...Wdrażanie Cloud Functions:
firebase deploy --only functions
Teraz możesz uzyskać do niego dostęp jak do każdej innej zmiennej środowiskowej. Jeśli natomiast inna funkcja, która nie określa obiektu tajnego, spróbuje uzyskać do niego dostęp, otrzyma niezdefiniowaną wartość:
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 miała dostęp do wartości obiektu tajnego. Tylko funkcje, które w opcji secrets zawierają konkretny obiekt tajny, będą miały do niego dostęp jako do zmiennej środowiskowej. Dzięki temu masz pewność, że wartości obiektów tajnych są dostępne tylko tam, gdzie są potrzebne, co zmniejsza ryzyko przypadkowego wycieku.
Zarządzanie obiektami tajnymi
Do zarządzania obiektami tajnymi używaj interfejsu wiersza poleceń Firebase. 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 ustawiasz nową wartość obiektu tajnego, musisz ponownie wdrożyć wszystkie funkcje, które odwołują się do tego obiektu, aby mogły one pobrać najnowszą wartość.
- Jeśli usuniesz obiekt tajny, upewnij się, że żadna z wdrożonych funkcji nie odwołuje się do niego. Funkcje, które używają usuniętej wartości obiektu tajnego, będą kończyć się niepowodzeniem bez powiadomienia.
Oto podsumowanie poleceń interfejsu wiersza poleceń Firebase 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]
Aby dowiedzieć się więcej o tych operacjach, przekaż -h z poleceniem, aby wyświetlić pomoc dotyczącą interfejsu wiersza poleceń.
Jak rozliczane są obciążenia za 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 wiersza poleceń Firebase próbuje automatycznie niszczyć nieużywane wersje obiektów tajnych, gdy jest to odpowiednie, np. gdy wdrażasz funkcje z nową wersją obiektu tajnego. Możesz też aktywnie czyścić nieużywane obiekty tajne za pomocą functions:secrets:destroy i functions:secrets:prune.
Secret Manager umożliwia wykonanie 10 000 bezpłatnych operacji dostępu do obiektu tajnego miesięcznie. Instancje funkcji odczytują tylko tajne klucze określone w opcji secrets przy każdym uruchomieniu „na zimno”. Jeśli masz wiele instancji funkcji odczytujących 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 każde 10 000 operacji dostępu.
Więcej informacji znajdziesz w artykule Ceny Secret Manager.
Obsługa emulatora
Konfiguracja środowiska za pomocą dotenv została zaprojektowana do współdziałania z lokalnym emulatorem Cloud Functions.
Jeśli używasz lokalnego emulatora Cloud Functions, możesz zastąpić zmienne środowiskowe w projekcie, konfigurując plik .env.local. Zawartość pliku .env.local ma pierwszeństwo przed plikiem .env i plikiem .env powiązanym z projektem.
Na przykład projekt może zawierać te 3 pliki z nieco innymi wartościami do 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 następujący sposób:
$ firebase emulators:start
i emulators: Starting emulators: functions
# Starts emulator with following environment variables:
# PLANET=Earth
# AUDIENCE=Local Humans
Utajnione informacje i dane logowania w emulatorze Cloud Functions
Emulator Cloud Functions obsługuje korzystanie z obiektów tajnych do przechowywania poufnych informacji konfiguracyjnych i uzyskiwania do nich dostępu. Domyślnie emulator będzie próbował uzyskać dostęp do obiektów tajnych w środowisku produkcyjnym przy użyciu domyślnego uwierzytelniania 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 przez emulator Cloud Functions, możesz zastąpić wartości obiektów tajnych, konfigurując plik .secret.local. Dzięki temu możesz łatwo testować funkcje lokalnie, zwłaszcza jeśli nie masz dostępu do wartości obiektu tajnego.
Migracja z konfiguracji środowiska wykonawczego
Interfejs API functions.config został wycofany i zostanie wyłączony w marcu 2027 r.
Po tym terminie wdrożenia z użyciem functions.config będą kończyć się niepowodzeniem.
Aby zapobiec błędom wdrażania, przenieś konfigurację do Cloud Secret Managera za pomocą interfejsu wiersza poleceń Firebase. Jest to zdecydowanie zalecany, najbardziej wydajny i bezpieczny sposób migracji konfiguracji.
Eksportowanie konfiguracji za pomocą interfejsu wiersza poleceń Firebase
Użyj polecenia
config export, aby wyeksportować istniejącą konfigurację środowiska do nowego obiektu tajnego w 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żyć konfiguracji przechowywanej w nowym obiekcie tajnym w usłudze Cloud Secret Manager, użyj interfejsu API
defineJsonSecretw źródle funkcji. 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 obiektów tajnych.
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 te wypełnione przez Google Cloud, a także zmienną środowiskową Firebase:
process.env.FIREBASE_CONFIG: udostępnia 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 udostępnionych w projekcie.
Ta konfiguracja jest stosowana automatycznie, gdy inicjujesz pakiet SDK Firebase Admin bez argumentów. Jeśli piszesz funkcje w języku 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 do 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);