A menudo, necesitarás una configuración adicional para tus funciones, como claves de API de terceros o parámetros de configuración ajustables. El SDK de Firebase para Cloud Functions ofrece una configuración de entorno integrada para facilitar el almacenamiento y la recuperación de este tipo de datos para tu proyecto.
Puedes elegir entre la configuración basada en archivos de las variables de entorno
(recomendado) o la configuración del entorno de ejecución con Firebase CLI
y functions.config
. Ambos enfoques se describen en esta guía.
Variables de entorno
Cloud Functions para Firebase admite el formato de archivo
dotenv
para cargar variables de entorno especificadas en un archivo .env
en el
entorno de ejecución de la aplicación. Una vez que se implementan, estas variables se pueden leer mediante la
interfaz
process.env
.
Para configurar tu entorno de esta manera, crea un archivo .env
en tu proyecto,
agrega las variables que desees y, luego, implementa como se describe a continuación:
Crea un archivo
.env
en tu directoriofunctions/
:# Directory layout: # my-project/ # firebase.json # functions/ # .env # package.json # index.js
Abre el archivo
.env
para editarlo y agrega las claves que desees. Por ejemplo:PLANET=Earth AUDIENCE=Humans
Implementa funciones y verifica que se hayan cargado las variables de entorno:
firebase deploy --only functions # ... # i functions: Loaded environment variables from .env. # ...
Una vez que se implementen las variables de entorno personalizadas,
el código de la función podrá acceder a ellas con
la sintaxis process.env
:
// Responds with "Hello Earth and Humans"
exports.hello = functions.https.onRequest((request, response) => {
response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});
Implementa varios conjuntos de variables de entorno
Si necesitas un conjunto alternativo de variables de entorno para tus proyectos
de Firebase (como los de etapa de pruebas y los de producción), crea un
archivo .env.<project or
alias>
y escribe allí las
variables específicas del proyecto. Si existen variables de entorno de
.env
y archivos .env
específicos del proyecto,
se incluirán en todas las funciones que se implementen.
Por ejemplo, un proyecto podría incluir estos tres archivos que contienen valores ligeramente distintos para el desarrollo y la producción:
.env
|
.env.dev
|
.env.prod
|
PLANET=Earth
AUDIENCE=Humans |
AUDIENCE=Dev Humans | AUDIENCE=Prod Humans |
Dados los valores en esos archivos separados, el conjunto de variables de entorno que se implementaron con las funciones variará según el proyecto 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
Variables de entorno reservadas
Algunas claves de variables de entorno están reservadas para uso interno. No uses ninguna de
las siguientes claves en los archivos .env
:
- Todas las claves que comienzan con X_GOOGLE_
- Todas las claves que comienzan con EXT_
- Todas las claves que comienzan con FIREBASE_
- Cualquier clave de la siguiente lista:
- 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
Almacena información de configuración sensible y accede a ella
Las variables de entorno que se almacenan en archivos .env
se pueden usar para configurar
funciones, pero no debes considerarlas como una forma segura de almacenar información sensible,
como las credenciales de la base de datos o las claves de API. Esto es muy importante
si revisas tus archivos .env
en el control de la fuente.
Para ayudarte a almacenar esta información, Cloud Functions para Firebase se integra en Secret Manager de Google Cloud. Este servicio encriptado almacena valores de configuración de manera segura y, a la vez, te permite acceder a ellos fácilmente desde tus funciones cuando sea necesario.
Crea y usa un Secret
Usa Firebase CLI para crear un Secret.
Si quieres crear y usar un Secret, sigue estos pasos:
Desde la raíz del directorio del proyecto local, ejecuta el siguiente comando:
firebase functions:secrets:set SECRET_NAME
Ingresa un valor para SECRET_NAME.
La CLI repite un mensaje de éxito y advierte que debes implementar funciones para que se efectúe el cambio.
Antes de la implementación, asegúrate de que el código de las funciones permita que se acceda al Secret mediante el parámetro
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 });
Implementa Cloud Functions con los siguientes comandos:
firebase deploy --only functions
Ahora podrás acceder a él como a cualquier otra variable de entorno.
Sin embargo, si otra función que no especifica el Secret en
runWith
intenta acceder a este, recibe un valor indefinido:
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
});
Una vez que se implemente la función, tendrá acceso al valor del Secret. Solo
las funciones que incluyen específicamente un Secret en su parámetro runWith
tendrán
acceso a él como una variable de entorno. Esto te garantiza
que los valores de los Secrets solo estén disponibles donde sean necesarios, lo que reduce el riesgo de
filtrar uno por accidente.
Administra Secrets
Usa Firebase CLI para administrar tus Secrets. Cuando administres Secrets de esta manera, ten en cuenta que algunos cambios de la CLI requieren que modifiques o vuelvas a implementar funciones asociadas. En particular, haz lo siguiente:
- Cada vez que configuras un valor nuevo para un Secret, debes volver a implementar todas las funciones que hagan referencia a este para captar el valor más reciente.
- Si borras un Secret, asegúrate de que ninguna de las funciones que se implementaron haga referencia a este. Las funciones que usen un valor del Secret que se borró fallarán silenciosamente.
Este es un resumen de los comandos de Firebase CLI para la administración de Secrets:
# 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 los comandos access
y destroy
, puedes proporcionar el parámetro de versión
opcional a fin de administrar una en particular. Por ejemplo:
functions:secrets:access SECRET_NAME[@VERSION]
Si quieres obtener más información sobre estas operaciones, pasa -h
con el comando para
consultar la ayuda de la CLI.
Cómo se facturan los Secrets
Secret Manager permite 6 versiones activas de los Secrets sin costo. Esto significa que puedes tener 6 Secrets por mes en un proyecto de Firebase gratis.
Según la configuración predeterminada, Firebase CLI intenta destruir automáticamente las versiones de los Secrets
sin usar cuando corresponda, como cuando implementas funciones con una versión nueva
del Secret. Además, puedes limpiar activamente aquellos sin usar con
functions:secrets:destroy
y functions:secrets:prune
.
Secret Manager permite 10,000 operaciones de acceso mensual sin facturar en un
Secret. Las instancias de función solo leen los secretos especificados en su parámetro runWith
cada vez que se inician en frío. Si tienes varias instancias de función
que leen muchos Secrets, es posible que tu proyecto exceda este permiso. En ese momento,
se te cobrarán $0.03 cada 10,000 operaciones de acceso.
Consulta Precios de Secret Manager para obtener más información.
Compatibilidad con el emulador
La configuración del entorno con dotenv está diseñada para interoperar con un emulador de Cloud Functions local.
Cuando usas un emulador de Cloud Functions local, puedes anular las variables
de entorno del proyecto configurando un archivo .env.local
. El contenido de
.env.local
tiene prioridad sobre .env
y el archivo .env
específico del proyecto.
Por ejemplo, un proyecto podría incluir estos tres archivos que contienen valores ligeramente distintos para el desarrollo y las pruebas locales:
.env
|
.env.dev
|
.env.local
|
PLANET=Earth
AUDIENCE=Humans |
AUDIENCE=Dev Humans | AUDIENCE=Local Humans |
Cuando se inicia en el contexto local, el emulador carga las variables de entorno como se muestra a continuación:
$ firebase emulators:start
i emulators: Starting emulators: functions
# Starts emulator with following environment variables:
# PLANET=Earth
# AUDIENCE=Local Humans
Secrets y credenciales en el emulador de Cloud Functions
El emulador de Cloud Functions admite el uso de Secrets para almacenar información de configuración sensible y acceder a ella. De forma predeterminada, el emulador intentará acceder a los Secrets de producción con las credenciales predeterminadas de la aplicación. En algunas situaciones, como los entornos de CI, es posible que el emulador no pueda acceder a los valores de los Secrets debido a restricciones de permisos.
De manera similar a la compatibilidad del emulador de Cloud Functions con las variables de entorno, puedes
anular los valores de los Secrets configurando un archivo .secret.local
. Esto te permite
probar las funciones de forma local, en particular, si no tienes acceso
al valor del Secret.
Migra desde la configuración del entorno
Si usaste la configuración del entorno con functions.config
, puedes
migrar tu configuración existente como variables de entorno (en formato
dotenv).
Firebase CLI proporciona un comando de exportación que muestra la configuración
de cada alias o proyecto que aparece en el directorio del archivo .firebaserc
(en el siguiente ejemplo, local
, dev
y prod
) como archivos .env
.
Para migrar, exporta la configuración del entorno existente con el 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
Ten en cuenta que, en algunos casos, se te pedirá que ingreses un prefijo para cambiar el nombre de las claves de variable de entorno que se exportaron. Esto se debe a que no todas las opciones de configuración se pueden transformar automáticamente, ya que puede que no sean válidas o sean una clave de variable de entorno reservada.
Te recomendamos que revises con detenimiento el contenido de los archivos .env
que se generaron antes de implementar las funciones o que revises los archivos .env
en el control de la fuente. Si
algún valor es sensible y no se debe filtrar, quítalo de los archivos .env
y almacénalo de forma segura en
Secret Manager.
También debes actualizar el código de las funciones. Cualquiera que use
functions.config
ahora deberá usar process.env
, como se indica en
Variables de entorno.
Configuración del entorno
Antes de que se lanzara la compatibilidad con variables de entorno en firebase-functions
v3.18.0
, usar functions.config()
era el enfoque recomendado para
configurar entornos. Aún se admite este método, pero recomendamos
que todos los proyectos nuevos usen variables de entorno, ya que son más fáciles de ejecutar
y mejorar la portabilidad del código.
Establece la configuración del entorno con la CLI
Para almacenar datos del entorno, puedes usar el comando firebase functions:config:set
en Firebase CLI.
Es posible asignar espacios de nombres a cada clave con el uso de puntos a fin de agrupar los elementos de configuración relacionados. Recuerda que solo se aceptan caracteres en minúscula en las claves, los caracteres en mayúscula no están permitidos.
Por ejemplo, para almacenar el ID de cliente y la clave de API de "Some Service", podrías ejecutar lo siguiente:
firebase functions:config:set someservice.key="THE API KEY" someservice.id="THE CLIENT ID"
Recupera la configuración actual del entorno
Para inspeccionar lo que se almacena actualmente en la configuración del entorno de tu proyecto, puedes
usar firebase functions:config:get
. Como resultado, verás un archivo JSON similar al
siguiente:
{
"someservice": {
"key":"THE API KEY",
"id":"THE CLIENT ID"
}
}
Esta función se basa en la API de configuración de Google Cloud Runtime.
Usa functions.config
para acceder a la configuración del entorno en una función
Parte de la configuración se proporciona de forma automática bajo el espacio de nombres firebase
reservado. La configuración del entorno está disponible dentro de la función en ejecución a través de functions.config()
.
Para usar la configuración anterior, el código debería ser similar al siguiente:
const functions = require('firebase-functions');
const request = require('request-promise');
exports.userCreated = functions.database.ref('/users/{id}').onWrite(event => {
let email = event.data.child('email').val();
return request({
url: 'https://someservice.com/api/some/call',
headers: {
'X-Client-ID': functions.config().someservice.id,
'Authorization': `Bearer ${functions.config().someservice.key}`
},
body: {email: email}
});
});
Utiliza la configuración del entorno para inicializar un módulo
Algunos módulos Node están listos y no necesitan configuración. Otros módulos necesitan una configuración adicional para inicializarse correctamente. Te recomendamos almacenar esta configuración en las variables de entorno en lugar de codificarla de forma fija (hard-coded). Esto ayuda a mantener el código mucho más portátil, lo que permite asignar un código abierto a la aplicación o alternar con facilidad las versiones de producción y prueba.
Por ejemplo, a fin de utilizar el módulo del SDK de Slack para Node, puedes escribir esto:
const functions = require('firebase-functions');
const IncomingWebhook = require('@slack/client').IncomingWebhook;
const webhook = new IncomingWebhook(functions.config().slack.url);
Antes de la implementación, configura la variable de configuración del entorno slack.url
:
firebase functions:config:set slack.url=https://hooks.slack.com/services/XXX
Comandos de entorno adicionales
firebase functions:config:unset key1 key2
quita las claves especificadas de la configuración.firebase functions:config:clone --from <fromProject>
clona el entorno de otro proyecto en el proyecto activo actualmente.
Variables de entorno propagadas automáticamente
Hay variables de entorno que se propagan automáticamente durante el tiempo de ejecución de las funciones y en funciones emuladas de manera local. Entre ellas, se incluyen las que propaga Google Cloud y una variable de entorno específica de Firebase:
process.env.FIREBASE_CONFIG
: proporciona la siguiente información de configuración del proyecto de Firebase:
{
databaseURL: 'https://databaseName.firebaseio.com',
storageBucket: 'projectId.appspot.com',
projectId: 'projectId'
}
Esta configuración se aplica automáticamente cuando inicializas el SDK de Firebase Admin sin argumentos. Si escribes funciones en JavaScript, inicializa de la siguiente manera:
const admin = require('firebase-admin');
admin.initializeApp();
Si escribes funciones en TypeScript, inicializa de la siguiente manera:
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import 'firebase-functions';
admin.initializeApp();
Si necesitas inicializar el SDK de Admin con la configuración predeterminada del proyecto mediante el uso de las credenciales de la cuenta de servicio, puedes cargar las credenciales desde un archivo y agregarlas a FIREBASE_CONFIG
de la siguiente manera:
serviceAccount = require('./serviceAccount.json');
const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
adminConfig.credential = admin.credential.cert(serviceAccount);
admin.initializeApp(adminConfig);