Les applications qui utilisent des fonctions de 1re génération doivent envisager de migrer vers la 2e génération en suivant les instructions de ce guide. Les fonctions de 2e génération utilisent Cloud Run pour offrir de meilleures performances, une meilleure configuration, une meilleure surveillance et plus encore.
Les exemples de cette page supposent que vous utilisez JavaScript avec des modules CommonJS (importations de style require), mais les mêmes principes s'appliquent à JavaScript avec ESM (importations de style import … from) et à TypeScript.
Le processus de migration
Les fonctions de 1re et 2e génération peuvent coexister dans le même fichier. Cela vous permet de migrer facilement, élément par élément, quand vous le souhaitez. Nous vous recommandons de migrer une fonction à la fois, en effectuant des tests et des vérifications avant de continuer.
Vérifier les versions de la CLI Firebase et de firebase-function
Assurez-vous d'utiliser au moins la version 12.00 de la CLI Firebase et la version 4.3.0 de firebase-functions. Toute version ultérieure sera compatible avec la 2e génération et la 1re génération.
Mettre à jour les importations
Les fonctions de 2e génération importent à partir du sous-package v2 dans le SDK firebase-functions.
Ce chemin d'importation différent est tout ce dont la CLI Firebase a besoin pour déterminer s'il faut déployer le code de votre fonction en tant que fonction de 1re ou de 2e génération.
Le sous-package v2 est modulaire. Nous vous recommandons de n'importer que le module spécifique dont vous avez besoin.
Avant : 1re génération
const functions = require("firebase-functions/v1");
Après : 2e génération
// explicitly import each trigger
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
Mettre à jour les définitions des déclencheurs
Étant donné que le SDK de deuxième génération favorise les importations modulaires, mettez à jour les définitions de déclencheurs pour refléter les importations modifiées de l'étape précédente.
Les arguments transmis aux rappels pour certains déclencheurs ont changé. Dans cet exemple, notez que les arguments du rappel onDocumentCreated ont été regroupés dans un seul objet event. De plus, certains déclencheurs disposent de nouvelles fonctionnalités de configuration pratiques, comme l'option cors du déclencheur onRequest.
Avant : 1re génération
const functions = require("firebase-functions/v1");
exports.date = functions.https.onRequest((req, res) => {
// ...
});
exports.uppercase = functions.firestore
.document("my-collection/{docId}")
.onCreate((change, context) => {
// ...
});
Après : 2e génération
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
exports.date = onRequest({cors: true}, (req, res) => {
// ...
});
exports.uppercase = onDocumentCreated("my-collection/{docId}", (event) => {
/* ... */
});
Utiliser une configuration paramétrée
Les fonctions de deuxième génération ne sont plus compatibles avec functions.config. Elles utilisent désormais une interface plus sécurisée pour définir les paramètres de configuration de manière déclarative dans votre codebase.
Avec le nouveau module params, la CLI bloque le déploiement, sauf si tous les paramètres ont une valeur valide. Cela permet de s'assurer qu'une fonction n'est pas déployée avec une configuration manquante.
Avant : 1re génération
const functions = require("firebase-functions/v1");
exports.getQuote = functions.https.onRequest(async (req, res) => {
const quote = await fetchMotivationalQuote(functions.config().apiKey);
// ...
});
Après : 2e génération
const {onRequest} = require("firebase-functions/v2/https");
const {defineSecret} = require("firebase-functions/params");
// Define the secret parameter
const apiKey = defineSecret("API_KEY");
exports.getQuote = onRequest(
// make the secret available to this function
{ secrets: [apiKey] },
async (req, res) => {
// retrieve the value of the secret
const quote = await fetchMotivationalQuote(apiKey.value());
// ...
}
);
Si vous disposez d'une configuration d'environnement existante avec functions.config, migrez cette configuration lors de votre mise à niveau vers la 2e génération.
L'API functions.config est obsolète et sera abandonnée en mars 2027.
Après cette date, les déploiements avec functions.config échoueront.
Pour éviter les échecs de déploiement, migrez votre configuration vers Cloud Secret Manager à l'aide de la CLI Firebase. Cette méthode est vivement recommandée, car elle est la plus efficace et la plus sécurisée pour migrer votre configuration.
Configurer l'exportation avec la CLI Firebase
Utilisez la commande
config exportpour exporter la configuration de votre environnement existant vers un nouveau secret dans 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```Mettre à jour le code de la fonction pour associer les secrets
Pour utiliser la configuration stockée dans le nouveau secret dans Cloud Secret Manager, utilisez l'API
defineJsonSecretdans la source de votre fonction. Assurez-vous également que les secrets sont liés à toutes les fonctions qui en ont besoin.Avant
const functions = require("firebase-functions/v1"); exports.myFunction = functions.https.onRequest((req, res) => { const apiKey = functions.config().someapi.key; // ... });Après
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; // ... });Déployer des fonctions
Déployez vos fonctions mises à jour pour appliquer les modifications et associer les autorisations secrètes.
firebase deploy --only functions:<your-function-name>
Définir les options d'exécution
La configuration des options d'exécution a changé entre la 1re et la 2e génération. La 2e génération ajoute également une nouvelle fonctionnalité permettant de définir des options pour toutes les fonctions.
Avant : 1re génération
const functions = require("firebase-functions/v1");
exports.date = functions
.runWith({
// Keep 5 instances warm for this latency-critical function
minInstances: 5,
})
// locate function closest to users
.region("asia-northeast1")
.https.onRequest((req, res) => {
// ...
});
exports.uppercase = functions
// locate function closest to users and database
.region("asia-northeast1")
.firestore.document("my-collection/{docId}")
.onCreate((change, context) => {
// ...
});
Après : 2e génération
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
const {setGlobalOptions} = require("firebase-functions/v2");
// locate all functions closest to users
setGlobalOptions({ region: "asia-northeast1" });
exports.date = onRequest({
// Keep 5 instances warm for this latency-critical function
minInstances: 5,
}, (req, res) => {
// ...
});
exports.uppercase = onDocumentCreated("my-collection/{docId}", (event) => {
/* ... */
});
Mettre à jour le compte de service par défaut (facultatif)
Alors que les fonctions de 1re génération utilisent le compte de service App Engine par défaut de Google pour autoriser l'accès aux API Firebase, les fonctions de 2e génération utilisent le compte de service Compute Engine par défaut. Cette différence peut entraîner des problèmes d'autorisation pour les fonctions migrées vers la 2e génération dans les cas où vous avez accordé des autorisations spéciales au compte de service de 1re génération. Si vous n'avez modifié aucune autorisation de compte de service, vous pouvez ignorer cette étape.
La solution recommandée consiste à attribuer explicitement le compte de service App Engine par défaut de 1re génération existant aux fonctions que vous souhaitez migrer vers la 2e génération, en remplaçant la valeur par défaut de la 2e génération. Pour ce faire, assurez-vous que chaque fonction migrée définit la valeur correcte pour serviceAccountEmail :
const {onRequest} = require("firebase-functions/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
const {setGlobalOptions} = require("firebase-functions");
// Use the App Engine default service account for all functions
setGlobalOptions({serviceAccountEmail: '<my-project-number>@<wbr>appspot.gserviceaccount.com'});
// Now I use the App Engine default service account.
exports.date = onRequest({cors: true}, (req, res) => {
// ...
});
// I do too!
exports.uppercase = onDocumentCreated("my-collection/{docId}", (event) => {
// ...
});
Vous pouvez également vous assurer de modifier les détails du compte de service pour qu'il dispose de toutes les autorisations nécessaires sur le compte de service App Engine par défaut (pour la 1re génération) et sur le compte de service Compute Engine par défaut (pour la 2e génération).
Utiliser la simultanéité
Un avantage important des fonctions de 2e génération est la capacité d'une seule instance de fonction à traiter plusieurs requêtes à la fois. Cela peut réduire considérablement le nombre de démarrages à froid rencontrés par les utilisateurs finaux. Par défaut, la simultanéité est définie sur 80, mais vous pouvez la définir sur n'importe quelle valeur comprise entre 1 et 1 000 :
const {onRequest} = require("firebase-functions/v2/https");
exports.date = onRequest({
// set concurrency value
concurrency: 500
},
(req, res) => {
// ...
});
Le réglage de la simultanéité peut améliorer les performances et réduire le coût des fonctions. En savoir plus sur la simultanéité dans Autoriser les requêtes simultanées
Auditer l'utilisation des variables globales
Les fonctions de 1re génération écrites sans tenir compte de la simultanéité peuvent utiliser des variables globales qui sont définies et lues à chaque requête. Lorsque la simultanéité est activée et qu'une seule instance commence à traiter plusieurs requêtes à la fois, cela peut introduire des bugs dans votre fonction, car les requêtes simultanées commencent à définir et à lire les variables globales simultanément.
Lors de la mise à niveau, vous pouvez définir le processeur de votre fonction sur gcf_gen1 et définir concurrency sur 1 pour restaurer le comportement de la 1re génération :
const {onRequest} = require("firebase-functions/v2/https");
exports.date = onRequest({
// TEMPORARY FIX: remove concurrency
cpu: "gcf_gen1",
concurrency: 1
},
(req, res) => {
// ...
});
Toutefois, cette solution n'est pas recommandée à long terme, car elle annule les avantages en termes de performances des fonctions de deuxième génération. Auditez plutôt l'utilisation des variables globales dans vos fonctions et supprimez ces paramètres temporaires lorsque vous êtes prêt.
Migrer le trafic vers les nouvelles fonctions 2nd gen
Comme lorsque vous modifiez la région ou le type de déclencheur d'une fonction, vous devrez donner un nouveau nom à la fonction de deuxième génération et y migrer lentement le trafic.
Il n'est pas possible de migrer une fonction de la 1re à la 2e génération avec le même nom et d'exécuter firebase deploy. Cela entraînera l'erreur suivante :
Upgrading from GCFv1 to GCFv2 is not yet supported. Please delete your old function or wait for this feature to be ready.
Avant de suivre ces étapes, assurez-vous que votre fonction est idempotente, car la nouvelle version et l'ancienne version de votre fonction s'exécuteront en même temps pendant le changement. Par exemple, si vous disposez d'une fonction de 1re génération qui répond aux événements d'écriture dans Firestore, assurez-vous que la réponse à une écriture deux fois (une fois par la fonction de 1re génération et une fois par la fonction de 2e génération) en réponse à ces événements laisse votre application dans un état cohérent.
- Renommez la fonction dans le code de vos fonctions. Par exemple, renommez
resizeImageenresizeImageSecondGen. - Déployez la fonction pour que la fonction d'origine de 1re génération et la fonction de 2e génération s'exécutent.
- Dans le cas des déclencheurs appelables, Task Queue et HTTP, commencez à rediriger tous les clients vers la fonction de 2e génération en mettant à jour le code client avec le nom ou l'URL de la fonction de 2e génération.
- Avec les déclencheurs d'arrière-plan, les fonctions de 1re et 2e génération répondent à chaque événement immédiatement après le déploiement.
- Une fois tout le trafic migré, supprimez la fonction de 1re génération à l'aide de la commande
firebase functions:deletede la CLI Firebase.- Vous pouvez également renommer la fonction de 2e génération pour qu'elle porte le même nom que la fonction de 1re génération.