Muitas vezes você precisará de configurações adicionais para suas funções, como chaves de API de terceiros ou configurações ajustáveis. O SDK do Firebase para Cloud Functions oferece configuração de ambiente integrada para facilitar o armazenamento e a recuperação desse tipo de dados para seu projeto.
Você pode escolher entre três opções:
- Configuração parametrizada (recomendada para a maioria dos cenários). Isso fornece configuração de ambiente fortemente tipada com parâmetros que são validados no momento da implantação, o que evita erros e simplifica a depuração.
- Configuração baseada em arquivo de variáveis de ambiente . Com essa abordagem, você cria manualmente um arquivo dotenv para carregar variáveis de ambiente.
- Configuração do ambiente de execução com Firebase CLI e
functions.config
(somente Cloud Functions (1ª geração)).
Para a maioria dos casos de uso, a configuração parametrizada é recomendada. Essa abordagem disponibiliza valores de configuração em tempo de execução e de implantação, e a implantação é bloqueada, a menos que todos os parâmetros tenham um valor válido. Por outro lado, a configuração com variáveis de ambiente não está disponível no momento da implantação.
Configuração parametrizada
O Cloud Functions para Firebase fornece uma interface para definir parâmetros de configuração de forma declarativa dentro da sua base de código. O valor desses parâmetros está disponível durante a implantação da função, ao definir opções de implantação e tempo de execução e durante a execução. Isso significa que a CLI bloqueará a implantação, a menos que todos os parâmetros tenham um valor válido.
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.`);
}
);
Pitão
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!')
Ao implantar uma função com variáveis de configuração parametrizadas, a CLI do Firebase primeiro tenta carregar seus valores de arquivos .env locais. Se eles não estiverem presentes nesses arquivos e nenhum default
for definido, a CLI solicitará os valores durante a implantação e, em seguida, salvará automaticamente seus valores em um arquivo .env
chamado .env.<project_ID>
em seu diretório 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
Dependendo do seu fluxo de trabalho de desenvolvimento, pode ser útil adicionar o arquivo .env.<project_ID>
gerado ao controle de versão.
Configurar o comportamento da CLI
Os parâmetros podem ser configurados com um objeto Options
que controla como a CLI solicitará valores. O exemplo a seguir define opções para validar o formato de um número de telefone, fornecer uma opção de seleção simples e preencher uma opção de seleção automaticamente no projeto do 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,
});
Pitão
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",
)
Tipos de parâmetros
A configuração parametrizada fornece digitação forte para valores de parâmetros e também oferece suporte a segredos do Cloud Secret Manager. Os tipos suportados são:
- Segredo
- Corda
- boleano
- Inteiro
- Flutuador
- Lista (Node.js)
Valores e expressões de parâmetros
O Firebase avalia seus parâmetros no momento da implantação e durante a execução da função. Devido a esses ambientes duplos, alguns cuidados extras devem ser tomados ao comparar valores de parâmetros e ao usá-los para definir opções de tempo de execução para suas funções.
Para passar um parâmetro para sua função como uma opção de tempo de execução, passe-o diretamente:
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) => {
//…
Pitão
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):
...
Além disso, se precisar comparar com um parâmetro para saber qual opção escolher, você precisará usar comparadores integrados em vez de verificar o valor:
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) => {
//…
Pitão
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):
...
Parâmetros e expressões de parâmetros que são usados apenas em tempo de execução podem ser acessados com sua função 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.`);
}
);
Pitão
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!')
Parâmetros integrados
O SDK do Cloud Functions oferece três parâmetros predefinidos, disponíveis no subpacote firebase-functions/params
:
Node.js
-
projectID
— o projeto do Cloud no qual a função está sendo executada. -
databaseURL
— o URL da instância do Realtime Database associada à função (se habilitado no projeto Firebase). -
storageBucket
— o bucket do Cloud Storage associado à função (se ativado no projeto do Firebase).
Pitão
-
PROJECT_ID
— o projeto do Cloud no qual a função está em execução. -
DATABASE_URL
— o URL da instância do Realtime Database associada à função (se habilitado no projeto Firebase). -
STORAGE_BUCKET
— o bucket do Cloud Storage associado à função (se ativado no projeto do Firebase).
Eles funcionam como parâmetros de string definidos pelo usuário em todos os aspectos, exceto que, como seus valores são sempre conhecidos pela Firebase CLI, seus valores nunca serão solicitados na implantação nem salvos em arquivos .env
.
Parâmetros secretos
Parâmetros do tipo Secret
, definidos usando defineSecret()
, representam parâmetros de string que possuem um valor armazenado no Cloud Secret Manager. Em vez de verificar um arquivo .env
local e gravar um novo valor no arquivo, se estiver ausente, os parâmetros secretos verificam a existência no Cloud Secret Manager e solicitam interativamente o valor de um novo segredo durante a implantação.
Os parâmetros secretos definidos desta forma devem estar vinculados a funções individuais que devem ter acesso a eles:
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();
//…
Pitão
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()
Como os valores dos segredos ficam ocultos até a execução da função, você não pode usá-los ao configurar sua função.
Variáveis ambientais
O Cloud Functions para Firebase oferece suporte ao formato de arquivo dotenv para carregar variáveis de ambiente especificadas em um arquivo .env
no ambiente de execução do aplicativo. Depois de implantadas, as variáveis de ambiente podem ser lidas por meio da interface process.env
(em projetos baseados em Node.js) ou os.environ
(em projetos baseados em Python).
Para configurar seu ambiente desta forma, crie um arquivo .env
em seu projeto, adicione as variáveis desejadas e implante:
Crie um arquivo
.env
em seu diretóriofunctions/
:# Directory layout: # my-project/ # firebase.json # functions/ # .env # package.json # index.js
Abra o arquivo
.env
para edição e adicione as chaves desejadas. Por exemplo:PLANET=Earth AUDIENCE=Humans
Implante funções e verifique se as variáveis de ambiente foram carregadas:
firebase deploy --only functions # ... # i functions: Loaded environment variables from .env. # ...
Depois que suas variáveis de ambiente personalizadas forem implantadas, seu código de função poderá acessá-las:
Node.js
// Responds with "Hello Earth and Humans"
exports.hello = onRequest((request, response) => {
response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});
Pitão
import os
@https_fn.on_request()
def hello(req):
return https_fn.Response(
f"Hello {os.environ.get('PLANET')} and {os.environ.get('AUDIENCE')}"
)
Implantando vários conjuntos de variáveis de ambiente
Se você precisar de um conjunto alternativo de variáveis de ambiente para seus projetos do Firebase (como preparação versus produção), crie um .env. <project or alias >
e escreva nele as variáveis de ambiente específicas do projeto. As variáveis de ambiente dos arquivos .env
e .env
específicos do projeto (se existirem) serão incluídas em todas as funções implantadas.
Por exemplo, um projeto poderia incluir estes três arquivos contendo valores ligeiramente diferentes para desenvolvimento e produção:
.env | .env.dev | .env.prod |
PLANETA=Terra AUDIÊNCIA=Humanos | AUDIÊNCIA = Desenvolvedores Humanos | AUDIÊNCIA = Prod Humanos |
Dados os valores nesses arquivos separados, o conjunto de variáveis de ambiente implantadas com suas funções irá variar dependendo do seu projeto de destino:
$ 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
Variáveis de ambiente reservadas
Algumas chaves de variáveis de ambiente são reservadas para uso interno. Não use nenhuma dessas chaves em seus arquivos .env
:
- Todas as chaves começando com X_GOOGLE_
- Todas as chaves começando com EXT_
- Todas as chaves começando com FIREBASE_
- Qualquer chave da lista a seguir:
- CLOUD_RUNTIME_CONFIG
- PONTO DE ENTRADA
- 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_REVISÃO
- PORTA
- K_CONFIGURAÇÃO
Armazene e acesse informações de configuração confidenciais
Variáveis de ambiente armazenadas em arquivos .env
podem ser usadas para configuração de funções, mas você não deve considerá-las uma forma segura de armazenar informações confidenciais, como credenciais de banco de dados ou chaves de API. Isso é especialmente importante se você verificar seus arquivos .env
no controle de origem.
Para ajudar você a armazenar informações confidenciais de configuração, o Cloud Functions for Firebase se integra ao Google Cloud Secret Manager . Este serviço criptografado armazena valores de configuração com segurança, ao mesmo tempo que permite fácil acesso a partir de suas funções quando necessário.
Crie e use um segredo
Para criar um segredo, use a CLI do Firebase.
Para criar e usar um segredo:
Na raiz do diretório local do projeto, execute o seguinte comando:
firebase functions:secrets:set SECRET_NAME
Insira um valor para SECRET_NAME .
A CLI ecoa uma mensagem de sucesso e avisa que você deve implementar funções para que a mudança entre em vigor.
Antes de implantar, certifique-se de que seu código de funções permita que a função acesse o segredo usando o parâmetro
runWith
: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 } );
Pitão
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 ...
Implante funções de nuvem:
firebase deploy --only functions
Agora você poderá acessá-lo como qualquer outra variável de ambiente. Por outro lado, se outra função que não especifica o segredo em
runWith
tentar acessar o segredo, ela receberá um valor indefinido: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 `runWith` parameter is missing });
Pitão
@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.
Assim que sua função for implantada, ela terá acesso ao valor secreto. Somente funções que incluam especificamente um segredo em seu parâmetro runWith
terão acesso a esse segredo como uma variável de ambiente. Isso ajuda você a garantir que os valores secretos estejam disponíveis apenas onde forem necessários, reduzindo o risco de vazamento acidental de um segredo.
Gerenciando segredos
Use a CLI do Firebase para gerenciar seus segredos. Ao gerenciar segredos dessa maneira, lembre-se de que algumas alterações da CLI exigem que você modifique e/ou reimplante funções associadas. Especificamente:
- Sempre que você definir um novo valor para um segredo, deverá reimplantar todas as funções que fazem referência a esse segredo para que elas obtenham o valor mais recente.
- Se você excluir um segredo, certifique-se de que nenhuma das funções implantadas faça referência a esse segredo. As funções que usam um valor secreto que foi excluído falharão silenciosamente.
Aqui está um resumo dos comandos Firebase CLI para gerenciamento de segredos:
# 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
Para os comandos access
e destroy
, você pode fornecer o parâmetro opcional version para gerenciar uma versão específica. Por exemplo:
functions:secrets:access SECRET_NAME[@VERSION]
Para obter mais informações sobre essas operações, passe -h
com o comando para visualizar a ajuda da CLI.
Como os segredos são cobrados
O Secret Manager permite 6 versões de segredos ativos sem nenhum custo. Isso significa que você pode ter 6 segredos por mês em um projeto do Firebase sem nenhum custo.
Por padrão, a CLI do Firebase tenta destruir automaticamente versões de segredo não utilizadas quando apropriado, como quando você implanta funções com uma nova versão do segredo. Além disso, você pode limpar ativamente segredos não utilizados usando functions:secrets:destroy
e functions:secrets:prune
.
O Secret Manager permite 10.000 operações de acesso mensais não faturadas em um segredo. As instâncias de função leem apenas os segredos especificados em seu parâmetro runWith
sempre que são inicializadas a frio. Se você tiver muitas instâncias de função lendo muitos segredos, seu projeto poderá exceder esse limite e, nesse ponto, será cobrado US$ 0,03 por 10.000 operações de acesso.
Para obter mais informações, consulte Preços do Secret Manager .
Suporte ao emulador
A configuração do ambiente com dotenv foi projetada para interoperar com um emulador local do Cloud Functions .
Ao usar um emulador local do Cloud Functions, você pode substituir variáveis de ambiente do seu projeto configurando um arquivo .env.local
. O conteúdo de .env.local
tem precedência sobre .env
e o arquivo .env
específico do projeto.
Por exemplo, um projeto poderia incluir estes três arquivos contendo valores ligeiramente diferentes para desenvolvimento e testes locais:
.env | .env.dev | .env.local |
PLANETA=Terra AUDIÊNCIA=Humanos | AUDIÊNCIA = Desenvolvedores Humanos | AUDIÊNCIA=Humanos Locais |
Quando iniciado no contexto local, o emulador carrega as variáveis de ambiente conforme mostrado:
$ firebase emulators:start
i emulators: Starting emulators: functions
# Starts emulator with following environment variables:
# PLANET=Earth
# AUDIENCE=Local Humans
Segredos e credenciais no emulador do Cloud Functions
O emulador do Cloud Functions oferece suporte ao uso de segredos para armazenar e acessar informações confidenciais de configuração . Por padrão, o emulador tentará acessar seus segredos de produção usando credenciais padrão do aplicativo . Em determinadas situações, como ambientes de CI, o emulador pode falhar ao acessar valores secretos devido a restrições de permissão.
Semelhante ao suporte do emulador do Cloud Functions para variáveis de ambiente, é possível substituir valores de segredos configurando um arquivo .secret.local
. Isso facilita o teste de suas funções localmente, especialmente se você não tiver acesso ao valor secreto.
Migrando da configuração do ambiente
Se você estiver usando a configuração de ambiente com functions.config
, poderá migrar sua configuração existente como variáveis de ambiente (no formato dotenv ). A CLI do Firebase fornece um comando de exportação que gera a configuração de cada alias ou projeto listado no arquivo .firebaserc
do seu diretório (no exemplo abaixo, local
, dev
e prod
) como arquivos .env
.
Para migrar, exporte as configurações de ambiente existentes usando o comando firebase functions:config:export
:
firebase functions:config:export i Importing configs from projects: [project-0, project-1] ⚠ The following configs keys could not be exported as environment variables: ⚠ project-0 (dev): 1foo.a => 1FOO\_A (Key 1FOO\_A must start with an uppercase ASCII letter or underscore, and then consist of uppercase ASCII letters, digits, and underscores.) Enter a PREFIX to rename invalid environment variable keys: CONFIG\_ ✔ Wrote functions/.env.prod ✔ Wrote functions/.env.dev ✔ Wrote functions/.env.local ✔ Wrote functions/.env
Observe que, em alguns casos, você será solicitado a inserir um prefixo para renomear chaves de variáveis de ambiente exportadas. Isso ocorre porque nem todas as configurações podem ser transformadas automaticamente, pois podem ser inválidas ou podem ser uma chave de variável de ambiente reservada .
Recomendamos que você revise cuidadosamente o conteúdo dos arquivos .env
gerados antes de implantar suas funções ou verificar os arquivos .env
no controle do código-fonte. Se algum valor for confidencial e não deve vazar, remova-o dos arquivos .env
e armazene-o com segurança no Secret Manager .
Você também precisará atualizar seu código de funções. Quaisquer funções que usem functions.config
agora precisarão usar process.env
, conforme mostrado em Variáveis de ambiente .