Vous aurez souvent besoin d'une configuration supplémentaire pour vos fonctions, telles que des clés d'API tierces ou des paramètres réglables. Le SDK Firebase pour Cloud Functions offre une configuration d'environnement intégrée pour faciliter le stockage et la récupération de ce type de données pour votre projet.
Vous pouvez choisir entre trois options :
- Configuration paramétrée (recommandée pour la plupart des scénarios). Cela fournit une configuration d'environnement fortement typée avec des paramètres qui sont validés au moment du déploiement, ce qui évite les erreurs et simplifie le débogage.
- Configuration basée sur fichier des variables d'environnement . Avec cette approche, vous créez manuellement un fichier dotenv pour charger les variables d'environnement.
- Configuration de l'environnement d'exécution avec l'interface de ligne de commande Firebase et
functions.config
(Cloud Functions (1re génération) uniquement).
Pour la plupart des cas d'utilisation, une configuration paramétrée est recommandée. Cette approche rend les valeurs de configuration disponibles à la fois au moment de l'exécution et du déploiement, et le déploiement est bloqué à moins que tous les paramètres aient une valeur valide. Inversement, la configuration avec des variables d'environnement n'est pas disponible au moment du déploiement.
Configuration paramétrée
Cloud Functions for Firebase fournit une interface permettant de définir les paramètres de configuration de manière déclarative dans votre base de code. La valeur de ces paramètres est disponible à la fois pendant le déploiement de la fonction, lors de la définition des options de déploiement et d'exécution, et pendant l'exécution. Cela signifie que la CLI bloquera le déploiement à moins que tous les paramètres aient une valeur valide.
Pour définir des paramètres dans votre code, suivez ce modèle :
const functions = require('firebase-functions');
const { defineInt, defineString } = require('firebase-functions/params');
// Define some parameters
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
const welcomeMessage = defineString('WELCOME_MESSAGE');
// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
(req, res) => {
res.send(`${welcomeMessage.value()}! I am a function.`);
}
);
Lors du déploiement d'une fonction avec des variables de configuration paramétrées, la CLI Firebase tente d'abord de charger leurs valeurs à partir de fichiers .env locaux. S'ils ne sont pas présents dans ces fichiers et qu'aucune valeur default
n'est définie, la CLI demandera les valeurs lors du déploiement, puis enregistrera automatiquement leurs valeurs dans un fichier .env
nommé .env.<project_ID>
dans votre répertoire 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
En fonction de votre workflow de développement, il peut être utile d'ajouter le fichier .env.<project_ID>
généré au contrôle de version.
Configurer le comportement de la CLI
Les paramètres peuvent être configurés avec un objet Options
qui contrôle la manière dont la CLI demandera des valeurs. L'exemple suivant définit des options pour valider le format d'un numéro de téléphone, pour fournir une option de sélection simple et pour remplir automatiquement une option de sélection à partir du projet Firebase :
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE', {default: 'Hello World',
description: 'The greeting that is returned to the caller of this function'});
const onlyPhoneNumbers = defineString('PHONE_NUMBER', {input: {text:
{validationRegex: /\d{3}-\d{3}-\d{4}/, validationErrorMessage: "Please enter
a phone number in the format XXX-YYY-ZZZZ"}}});
const selectedOption = defineString('PARITY', {input: {select: {options:
[{value: "odd"}, {value: "even"}]}}})
const storageBucket = defineString('BUCKET', {input: {resource: {type:
"storage.googleapis.com/Bucket"}}, description: "This will automatically
populate the selector field with the deploying Cloud Project’s
storage buckets"})
Types de paramètres
La configuration paramétrée fournit un typage fort pour les valeurs de paramètre et prend également en charge les secrets de Cloud Secret Manager. Les types pris en charge sont :
- Secret
- Chaîne
- booléen
- Entier
- Flotter
Valeurs et expressions des paramètres
Firebase évalue vos paramètres à la fois au moment du déploiement et pendant l'exécution de votre fonction. En raison de ces environnements doubles, des précautions supplémentaires doivent être prises lors de la comparaison des valeurs de paramètres et lors de leur utilisation pour définir les options d'exécution de vos fonctions.
Pour transmettre un paramètre à votre fonction en tant qu'option d'exécution, transmettez-le directement :
const functions = require('firebase-functions');
const { defineInt} = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO\_WORLD\_MININSTANCES');
export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
(req, res) => {
//…
De plus, si vous devez comparer un paramètre afin de savoir quelle option choisir, vous devrez utiliser des comparateurs intégrés au lieu de vérifier la valeur :
const functions = require('firebase-functions');
const { defineBool } = require('firebase-functions/params');
const environment = params.defineString(‘ENVIRONMENT’, {default: ‘dev’});
// use built-in comparators
const minInstancesConfig =environment.equals('PRODUCTION').thenElse(10, 1);
export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
(req, res) => {
//…
Les paramètres et les expressions de paramètre qui ne sont utilisés qu'au moment de l'exécution sont accessibles avec leur fonction value
:
const functions = require('firebase-functions');
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE');
// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloWorld = functions.https.onRequest(
(req, res) => {
res.send(`${welcomeMessage.value()}! I am a function.`);
}
);
Paramètres intégrés
Le SDK Cloud Functions propose trois paramètres prédéfinis, disponibles dans le sous-package firebase-functions/params
:
-
projectId
— le projet Cloud dans lequel la fonction s'exécute. -
databaseUrl
— l'URL de l'instance Realtime Database associée à la fonction (si activée sur le projet Firebase). -
storageBucket
— le bucket Cloud Storage associé à la fonction (si activé sur le projet Firebase).
Ceux-ci fonctionnent comme des paramètres de chaîne définis par l'utilisateur à tous égards, sauf que, puisque leurs valeurs sont toujours connues de la CLI Firebase, leurs valeurs ne seront jamais demandées lors du déploiement ni enregistrées dans des fichiers .env
.
Paramètres secrets
Les paramètres de type Secret
, définis à l'aide defineSecret()
, représentent des paramètres de chaîne dont la valeur est stockée dans Cloud Secret Manager. Au lieu de vérifier par rapport à un fichier .env
local et d'écrire une nouvelle valeur dans le fichier s'il est manquant, les paramètres de secret vérifient leur existence dans Cloud Secret Manager et demandent de manière interactive la valeur d'un nouveau secret lors du déploiement.
Les paramètres secrets définis de cette manière doivent être liés à des fonctions individuelles qui doivent y avoir accès :
const functions = require('firebase-functions');
const { defineSecret } = require('firebase-functions/params');
const discordApiKey = defineSecret('DISCORD_API_KEY');
export const postToDiscord = functions.runWith({ secrets: [discordApiKey] }).https.onRequest(
(req, res) => {
const apiKey = discordApiKey.value();
//…
Étant donné que les valeurs des secrets sont masquées jusqu'à l'exécution de la fonction, vous ne pouvez pas les utiliser lors de la configuration de votre fonction.
Variables d'environnement
Cloud Functions pour Firebase est compatible avec le format de fichier dotenv pour le chargement des variables d'environnement spécifiées dans un fichier .env
dans l'environnement d'exécution de votre application. Une fois déployées, les variables d'environnement peuvent être lues via l'interface process.env
.
Pour configurer votre environnement de cette manière, créez un fichier .env
dans votre projet, ajoutez les variables souhaitées et déployez :
Créez un fichier
.env
dans votre répertoirefunctions/
:# Directory layout: # my-project/ # firebase.json # functions/ # .env # package.json # index.js
Ouvrez le fichier
.env
pour le modifier et ajoutez les clés souhaitées. Par exemple:PLANET=Earth AUDIENCE=Humans
Déployez les fonctions et vérifiez que les variables d'environnement ont été chargées :
firebase deploy --only functions # ... # i functions: Loaded environment variables from .env. # ...
Une fois vos variables d'environnement personnalisées déployées, votre code de fonction peut y accéder avec la syntaxe 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}`);
});
Déploiement de plusieurs ensembles de variables d'environnement
Si vous avez besoin d'un ensemble alternatif de variables d'environnement pour vos projets Firebase (comme la mise en scène ou la production), créez un .env. <project or alias >
fichier et écrivez-y vos variables d'environnement spécifiques au projet. Les variables d'environnement des fichiers .env
et spécifiques au projet .env
(s'ils existent) seront incluses dans toutes les fonctions déployées.
Par exemple, un projet pourrait inclure ces trois fichiers contenant des valeurs légèrement différentes pour le développement et la production :
.env | .env.dev | .env.prod |
PLANÈTE=Terre PUBLIC=Humains | AUDIENCE=Dev Humains | PUBLIC=Prod Humains |
Étant donné les valeurs de ces fichiers séparés, l'ensemble des variables d'environnement déployées avec vos fonctions variera en fonction de votre projet cible :
$ 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 d'environnement réservées
Certaines clés de variables d'environnement sont réservées à un usage interne. N'utilisez aucune de ces clés dans vos fichiers .env
:
- Toutes les clés commençant par X_GOOGLE_
- Toutes les clés commençant par EXT_
- Toutes les clés commençant par FIREBASE_
- N'importe quelle clé de la liste suivante :
- CLOUD_RUNTIME_CONFIG
- POINT D'ACCÈS
- GCP_PROJECT
- GCLOUD_PROJECT
- GOOGLE_CLOUD_PROJECT
- FUNCTION_TRIGGER_TYPE
- FUNCTION_NAME
- FUNCTION_MEMORY_Mo
- FUNCTION_TIMEOUT_SEC
- FUNCTION_IDENTITY
- FUNCTION_REGION
- FUNCTION_TARGET
- FUNCTION_SIGNATURE_TYPE
- K_SERVICE
- K_REVISION
- PORT
- K_CONFIGURATION
Stockez et accédez aux informations de configuration sensibles
Les variables d'environnement stockées dans les fichiers .env
peuvent être utilisées pour la configuration des fonctions, mais vous ne devez pas les considérer comme un moyen sécurisé de stocker des informations sensibles telles que les informations d'identification de la base de données ou les clés API. Ceci est particulièrement important si vous archivez vos fichiers .env
dans le contrôle de code source.
Pour vous aider à stocker des informations de configuration sensibles, Cloud Functions for Firebase s'intègre à Google Cloud Secret Manager . Ce service crypté stocke les valeurs de configuration en toute sécurité, tout en permettant un accès facile à partir de vos fonctions en cas de besoin.
Créer et utiliser un secret
Pour créer un secret, utilisez la CLI Firebase.
Pour créer et utiliser un secret :
À partir de la racine de votre répertoire de projet local, exécutez la commande suivante :
firebase functions:secrets:set SECRET_NAME
Saisissez une valeur pour SECRET_NAME .
La CLI renvoie un message de réussite et avertit que vous devez déployer des fonctions pour que la modification prenne effet.
Avant de déployer, assurez-vous que le code de vos fonctions permet à la fonction d'accéder au secret à l'aide du paramètre
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 });
Déployez des fonctions cloud :
firebase deploy --only functions
Vous pourrez désormais y accéder comme n'importe quelle autre variable d'environnement. Inversement, si une autre fonction qui ne spécifie pas le secret dans runWith
tente d'accéder au secret, elle reçoit une valeur indéfinie :
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
});
Une fois votre fonction déployée, elle aura accès à la valeur secrète. Seules les fonctions qui incluent spécifiquement un secret dans leur paramètre runWith
auront accès à ce secret en tant que variable d'environnement. Cela vous aide à vous assurer que les valeurs secrètes ne sont disponibles que là où elles sont nécessaires, ce qui réduit le risque de fuite accidentelle d'un secret.
Gestion des secrets
Utilisez la CLI Firebase pour gérer vos secrets. Lors de la gestion des secrets de cette manière, gardez à l'esprit que certaines modifications de l'interface de ligne de commande vous obligent à modifier et/ou à redéployer les fonctions associées. Spécifiquement:
- Chaque fois que vous définissez une nouvelle valeur pour un secret, vous devez redéployer toutes les fonctions qui font référence à ce secret pour qu'elles récupèrent la dernière valeur.
- Si vous supprimez un secret, assurez-vous qu'aucune de vos fonctions déployées ne fait référence à ce secret. Les fonctions qui utilisent une valeur secrète qui a été supprimée échoueront silencieusement.
Voici un résumé des commandes Firebase CLI pour la gestion des 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
Pour les commandes access
et destroy
, vous pouvez fournir le paramètre de version facultatif pour gérer une version particulière. Par exemple:
functions:secrets:access SECRET_NAME[@VERSION]
Pour plus d'informations sur ces opérations, transmettez -h
avec la commande pour afficher l'aide de la CLI.
Comment les secrets sont facturés
Secret Manager autorise 6 versions secrètes actives sans frais. Cela signifie que vous pouvez avoir 6 secrets par mois dans un projet Firebase sans frais.
Par défaut, la CLI Firebase tente de détruire automatiquement les versions secrètes inutilisées, le cas échéant, par exemple lorsque vous déployez des fonctions avec une nouvelle version du secret. En outre, vous pouvez activement nettoyer les secrets inutilisés à l'aide functions:secrets:destroy
et functions:secrets:prune
.
Secret Manager autorise 10 000 opérations d'accès mensuelles non facturées sur un secret. Les instances de fonction lisent uniquement les secrets spécifiés dans leur paramètre runWith
chaque fois qu'elles démarrent à froid. Si vous avez beaucoup d'instances de fonction lisant beaucoup de secrets, votre projet peut dépasser cette allocation, auquel cas vous serez facturé 0,03 $ pour 10 000 opérations d'accès.
Pour plus d'informations, consultez Tarification de Secret Manager .
Prise en charge de l'émulateur
La configuration de l'environnement avec dotenv est conçue pour interagir avec un émulateur Cloud Functions local .
Lorsque vous utilisez un émulateur Cloud Functions local, vous pouvez remplacer les variables d'environnement de votre projet en configurant un fichier .env.local
. Le contenu de .env.local
a priorité sur .env
et le fichier .env
spécifique au projet.
Par exemple, un projet pourrait inclure ces trois fichiers contenant des valeurs légèrement différentes pour le développement et les tests locaux :
.env | .env.dev | .env.local |
PLANÈTE=Terre PUBLIC=Humains | AUDIENCE=Dev Humains | PUBLIC = Humains locaux |
Lorsqu'il est démarré dans le contexte local, l'émulateur charge les variables d'environnement comme indiqué :
$ firebase emulators:start
i emulators: Starting emulators: functions
# Starts emulator with following environment variables:
# PLANET=Earth
# AUDIENCE=Local Humans
Secrets et identifiants dans l'émulateur Cloud Functions
L'émulateur Cloud Functions prend en charge l'utilisation de secrets pour stocker et accéder aux informations de configuration sensibles . Par défaut, l'émulateur essaiera d'accéder à vos secrets de production en utilisant les informations d'identification par défaut de l'application . Dans certaines situations telles que les environnements CI, l'émulateur peut ne pas accéder aux valeurs secrètes en raison de restrictions d'autorisation.
Comme pour la prise en charge de l'émulateur Cloud Functions pour les variables d'environnement, vous pouvez remplacer les valeurs secrètes en configurant un fichier .secret.local
. Cela vous permet de tester facilement vos fonctions localement, surtout si vous n'avez pas accès à la valeur secrète.
Migration depuis la configuration de l'environnement
Si vous avez utilisé la configuration de l'environnement avec functions.config
, vous pouvez migrer votre configuration existante en tant que variables d'environnement (au format dotenv ). La CLI Firebase fournit une commande d'exportation qui génère la configuration de chaque alias ou projet répertorié dans le fichier .firebaserc
de votre répertoire (dans l'exemple ci-dessous, local
, dev
et prod
) sous forme de fichiers .env
.
Pour migrer, exportez vos configurations d'environnement existantes à l'aide de la commande 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
Notez que, dans certains cas, vous serez invité à entrer un préfixe pour renommer les clés de variables d'environnement exportées. En effet, toutes les configurations ne peuvent pas être transformées automatiquement car elles peuvent être invalides ou être une clé de variable d'environnement réservée .
Nous vous recommandons d'examiner attentivement le contenu des fichiers .env
générés avant de déployer vos fonctions ou d'archiver les fichiers .env
dans le contrôle de code source. Si des valeurs sont sensibles et ne doivent pas être divulguées, supprimez-les de vos fichiers .env
et stockez-les en toute sécurité dans Secret Manager à la place.
Vous devrez également mettre à jour votre code de fonctions. Toutes les fonctions qui utilisent functions.config
devront désormais utiliser process.env
à la place, comme indiqué dans Upgrade to 2nd gen .
Configuration de l'environnement
Avant la publication de la prise en charge des variables d'environnement dans firebase-functions v3.18.0
, l'utilisation functions.config()
était l'approche recommandée pour la configuration de l'environnement. Cette approche est toujours prise en charge, mais nous recommandons à tous les nouveaux projets d'utiliser à la place des variables d'environnement, car elles sont plus simples à utiliser et améliorent la portabilité de votre code.
Définir la configuration de l'environnement avec la CLI
Pour stocker les données d'environnement, vous pouvez utiliser la commande firebase functions:config:set
dans la CLI Firebase . Chaque clé peut être dotée d'un espace de noms à l'aide de points pour regrouper la configuration associée. Gardez à l'esprit que seuls les caractères minuscules sont acceptés dans les clés ; les caractères majuscules ne sont pas autorisés.
Par exemple, pour stocker l'ID client et la clé API pour "Some Service", vous pouvez exécuter :
firebase functions:config:set someservice.key="THE API KEY" someservice.id="THE CLIENT ID"
Récupérer la configuration actuelle de l'environnement
Pour inspecter ce qui est actuellement stocké dans la configuration de l'environnement pour votre projet, vous pouvez utiliser firebase functions:config:get
. Il affichera JSON quelque chose comme ceci :
{
"someservice": {
"key":"THE API KEY",
"id":"THE CLIENT ID"
}
}
Cette fonctionnalité est basée sur l' API de configuration de Google Cloud Runtime .
Utilisez functions.config
pour accéder à la configuration de l'environnement dans une fonction
Certaines configurations sont automatiquement fournies sous l'espace de noms firebase
réservé. La configuration de l'environnement est disponible dans votre fonction en cours d'exécution via functions.config()
. Pour utiliser la configuration ci-dessus, votre code pourrait ressembler à ceci :
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}
});
});
Utiliser la configuration de l'environnement pour initialiser un module
Certains modules Node sont prêts sans aucune configuration. D'autres modules nécessitent une configuration supplémentaire pour s'initialiser correctement. Nous vous recommandons de stocker cette configuration dans des variables de configuration d'environnement plutôt que de la coder en dur. Cela vous aide à garder votre code beaucoup plus portable, ce qui vous permet d'ouvrir la source de votre application ou de basculer facilement entre les versions de production et de mise en scène.
Par exemple, pour utiliser le module Slack Node SDK , vous pouvez écrire ceci :
const functions = require('firebase-functions');
const IncomingWebhook = require('@slack/client').IncomingWebhook;
const webhook = new IncomingWebhook(functions.config().slack.url);
Avant le déploiement, définissez la variable de configuration d'environnement slack.url
:
firebase functions:config:set slack.url=https://hooks.slack.com/services/XXX
Commandes d'environnement supplémentaires
-
firebase functions:config:unset key1 key2
supprime les clés spécifiées de la configuration -
firebase functions:config:clone --from <fromProject>
clone l'environnement d'un autre projet dans le projet actuellement actif.
Variables d'environnement renseignées automatiquement
Certaines variables d'environnement sont automatiquement renseignées dans l'exécution des fonctions et dans les fonctions émulées localement. Celles-ci incluent celles renseignées par Google Cloud , ainsi qu'une variable d'environnement spécifique à Firebase :
process.env.FIREBASE_CONFIG
: fournit les informations de configuration de projet Firebase suivantes :
{
databaseURL: 'https://databaseName.firebaseio.com',
storageBucket: 'projectId.appspot.com',
projectId: 'projectId'
}
Cette configuration est appliquée automatiquement lorsque vous initialisez le SDK Firebase Admin sans arguments. Si vous écrivez des fonctions en JavaScript, initialisez comme ceci :
const admin = require('firebase-admin');
admin.initializeApp();
Si vous écrivez des fonctions en TypeScript, initialisez comme ceci :
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import 'firebase-functions';
admin.initializeApp();
Si vous devez initialiser le SDK Admin avec la configuration de projet par défaut à l'aide des informations d'identification du compte de service, vous pouvez charger les informations d'identification à partir d'un fichier et les ajouter à FIREBASE_CONFIG
comme ceci :
serviceAccount = require('./serviceAccount.json');
const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
adminConfig.credential = admin.credential.cert(serviceAccount);
admin.initializeApp(adminConfig);