欢迎参加我们将于 2022 年 10 月 18 日举办的 Firebase 峰会(线上线下同时进行),了解 Firebase 如何帮助您加快应用开发速度、满怀信心地发布应用并在之后需要时轻松地扩大应用规模。立即报名

Gérer les fonctions

Vous pouvez déployer, supprimer et modifier des fonctions à l'aide des commandes CLI Firebase ou en définissant des options d'exécution dans le code source de vos fonctions.

Déployer des fonctions

Pour déployer des fonctions, exécutez cette commande CLI Firebase :

$ firebase deploy --only functions

Par défaut, la CLI Firebase déploie toutes les fonctions dans index.js en même temps. Si votre projet contient plus de 5 fonctions, nous vous recommandons d'utiliser l'indicateur --only avec des noms de fonction spécifiques pour déployer uniquement les fonctions que vous avez modifiées. Le déploiement de fonctions spécifiques de cette manière accélère le processus de déploiement et vous aide à éviter de vous heurter à des quotas de déploiement. Par exemple:

$ firebase deploy --only functions:addMessage,functions:makeUppercase

Lors du déploiement d'un grand nombre de fonctions, vous pouvez dépasser le quota standard et recevoir des messages d'erreur HTTP 429 ou 500. Pour résoudre ce problème, déployez les fonctions par groupes de 10 ou moins.

Consultez la référence Firebase CLI pour la liste complète des commandes disponibles.

Par défaut, la CLI Firebase recherche dans le dossier functions/ le code source. Si vous préférez, vous pouvez organiser les fonctions dans des bases de code ou plusieurs ensembles de fichiers.

Supprimer les fonctions

Vous pouvez supprimer des fonctions précédemment déployées de ces manières :

  • explicitement dans la CLI Firebase avec functions:delete
  • en utilisant explicitement le menu contextuel dans la liste des fonctions de la console Firebase
  • implicitement en supprimant la fonction de index.js avant le déploiement.

Toutes les opérations de suppression vous invitent à confirmer avant de retirer la fonction de la production.

La suppression de fonction explicite dans la CLI Firebase prend en charge plusieurs arguments ainsi que des groupes de fonctions, et vous permet de spécifier une fonction s'exécutant dans une région particulière. En outre, vous pouvez remplacer l'invite de confirmation.

# Delete all functions that match the specified name in all regions.
$ firebase functions:delete myfunction

# Delete a specified function running in a specific region.
$ firebase functions:delete myfunction --region us-east-1

# Delete more than one function
$ firebase functions:delete myfunction myotherfunction

# Delete a specified functions group.
$ firebase functions:delete groupA

# Bypass the confirmation prompt.
$ firebase functions:delete myfunction --force

Avec la suppression de fonction implicite, firebase deploy analyse index.js et supprime de la production toutes les fonctions qui ont été supprimées du fichier.

Modifier le nom, la région ou le déclencheur d'une fonction

Si vous renommez ou modifiez les régions ou le déclencheur pour les fonctions qui gèrent le trafic de production, suivez les étapes de cette section pour éviter de perdre des événements lors de la modification. Avant de suivre ces étapes, assurez-vous d'abord que votre fonction est idempotente , car la nouvelle version et l'ancienne version de votre fonction s'exécuteront en même temps pendant la modification.

Renommer une fonction

Pour renommer une fonction, créez une nouvelle version renommée de la fonction dans index.js , puis exécutez deux commandes de déploiement distinctes. La première commande déploie la fonction nouvellement nommée et la deuxième commande supprime la version précédemment déployée. Par exemple, si vous avez une fonction appelée webhook que vous souhaitez remplacer par webhookNew , révisez le code comme suit :

// before
const {onRequest} = require('firebase-functions/v2/https');

exports.webhook = onRequest((req, res) => {
    res.send("Hello");
});

// after
const {onRequest} = require('firebase-functions/v2/https');

exports.webhooknew = onRequest((req, res) => {
    res.send("Hello");
});

Exécutez ensuite les commandes suivantes pour déployer la nouvelle fonction :

# Deploy new function called webhookNew
$ firebase deploy --only functions:webhooknew

# Wait until deployment is done; now both webhooknew and webhook are running

# Delete webhook
$ firebase functions:delete webhook

Modifier la région ou les régions d'une fonction

Si vous modifiez les régions spécifiées pour une fonction qui gère le trafic de production, vous pouvez éviter la perte d'événements en exécutant ces étapes dans l'ordre :

  1. Renommez la fonction et modifiez sa région ou ses régions comme vous le souhaitez.
  2. Déployez la fonction renommée, ce qui entraîne l'exécution temporaire du même code dans les deux ensembles de régions.
  3. Supprimer la fonction précédente.

Par exemple, si vous avez une fonction appelée webhook qui se trouve actuellement dans la région de fonctions par défaut de us-central1 , et que vous souhaitez la migrer vers asia-northeast1 , vous devez d'abord modifier votre code source pour renommer la fonction et réviser la région .

// before
const {onRequest} = require('firebase-functions/v2/https');

exports.webhook = onRequest((req, res) => {
    res.send("Hello");
});

// after
const {onRequest} = require('firebase-functions/v2/https');

exports.webhookasia = onRequest({
        region: 'asia-northeast1'
    }, (req, res) => {
    res.send("Hello");
});

Déployez ensuite en exécutant :

$ firebase deploy --only functions:webhookAsia

Maintenant, deux fonctions identiques sont en cours d'exécution : webhook s'exécute dans us-central1 et webhookasia s'exécute dans asia-northeast1 .

Ensuite, supprimez webhook :

$ firebase functions:delete webhook

Maintenant, il n'y a qu'une seule fonction - webhookasia , qui s'exécute dans asia-northeast1 .

Modifier le type de déclencheur d'une fonction

Au fur et à mesure que vous développez votre déploiement Cloud Functions pour Firebase, vous devrez peut-être modifier le type de déclencheur d'une fonction pour diverses raisons. Par exemple, vous voudrez peut-être :

  • Passez de l'événement de stockage hérité onChange à onFinalize , onDelete , onArchive et onMetadataUpdate . (En savoir plus à ce sujet dans le guide de mise à niveau bêta vers v1 ou v2 ).
  • Passez d'un type d'événement Firebase Realtime Database ou Cloud Firestore à un autre, tel que l'événement générique onWrite à l'événement granulaire onCreate .

Il n'est pas possible de modifier le type d'événement d'une fonction en modifiant simplement le code source et en exécutant firebase deploy . Pour éviter les erreurs, modifiez le type de déclencheur d'une fonction en suivant cette procédure :

  1. Modifiez le code source pour inclure une nouvelle fonction avec le type de déclencheur souhaité.
  2. Déployez la fonction, ce qui entraîne l'exécution temporaire de l'ancienne et de la nouvelle fonction.
  3. Supprimez explicitement l'ancienne fonction de la production à l'aide de la CLI Firebase.

Par exemple, si vous aviez une fonction objectchanged qui a le type d'événement hérité onMetadataUpdated et que vous souhaitez le changer en onObjectFinalized , renommez d'abord la fonction et modifiez-la pour qu'elle ait le type d'événement onObjectFinalized .

// before
const {onMetadataUpdated} = require('firebase-functions/v2/storage');

exports.objectchanged = onMetadataUpdated((event) => {
    return console.log('File name is: ', event.data.name);
});

// after
const {onObjectFinalized} = require('firebase-functions/v2/storage');

exports.objectchanged = onObjectFinalized((event) => {
    return console.log('File name is: ', event.data.name);
});

Exécutez ensuite les commandes suivantes pour créer d'abord la nouvelle fonction, avant de supprimer l'ancienne fonction :

# Create new function objectFinalized
$ firebase deploy --only functions:objectFinalized

# Wait until deployment is done; now both objectChanged and objectFinalized are running

# Delete objectChanged
$ firebase functions:delete objectChanged

Définir les options d'exécution

Cloud Functions pour Firebase vous permet de sélectionner des options d'exécution telles que la version d'exécution de Node.js et le délai d'expiration par fonction, l'allocation de mémoire et les instances de fonction minimum/maximum.

Définir la version de Node.js

Le SDK Firebase pour Cloud Functions v2 permet une sélection d'environnements d'exécution Node.js. Vous pouvez choisir d'exécuter toutes les fonctions d'un projet exclusivement sur l'environnement d'exécution correspondant à l'une de ces versions Node.js prises en charge :

  • Node.js 16
  • Node.js 14
  • Node.js 12
  • Node.js 10

Pour définir la version de Node.js :

Définissez la version dans le champ engines du fichier package.json qui a été créé dans votre répertoire functions/ lors de l'initialisation. Par exemple, pour n'utiliser que la version 16, modifiez cette ligne dans package.json :

  "engines": {"node": "16"}

Le champ engines est obligatoire ; il doit spécifier l'une des versions prises en charge de Node.js pour que vous puissiez déployer et exécuter des fonctions. Actuellement firebase init functions définissent ce champ sur 16 .

Mettez à niveau votre environnement d'exécution Node.js

Pour mettre à niveau votre environnement d'exécution Node.js :

  1. Assurez-vous que votre projet est sur le plan tarifaire Blaze .
  2. Assurez-vous que vous utilisez Firebase CLI v9.17.0 ou une version ultérieure.
  3. Modifiez la valeur des engines dans le fichier package.json qui a été créé dans votre répertoire functions/ lors de l'initialisation. Par exemple, si vous effectuez une mise à niveau de la version 10 vers la version 16, l'entrée devrait ressembler à ceci : "engines": {"node": "16"}
  4. Redéployez les fonctions à l'aide de Firebase CLI v9.17.0 ou version ultérieure.

Contrôler le comportement de mise à l'échelle

Par défaut, Cloud Functions pour Firebase adapte le nombre d'instances en cours d'exécution en fonction du nombre de requêtes entrantes, pouvant éventuellement réduire à zéro instance en période de trafic réduit. Toutefois, si votre application nécessite une latence réduite et que vous souhaitez limiter le nombre de démarrages à froid, vous pouvez modifier ce comportement par défaut en spécifiant un nombre minimum d'instances de conteneur à conserver au chaud et prêtes à répondre aux demandes.

De même, vous pouvez définir un nombre maximal pour limiter la mise à l'échelle des instances en réponse aux demandes entrantes. Utilisez ce paramètre pour contrôler vos coûts ou pour limiter le nombre de connexions à un service de sauvegarde tel qu'une base de données.

En utilisant ces paramètres avec le paramètre de simultanéité par instance (nouveau dans la v2), vous pouvez contrôler et ajuster le comportement de mise à l'échelle de vos fonctions. La nature de votre application et de votre fonction déterminera quels paramètres sont les plus rentables et se traduiront par les meilleures performances.

Pour certaines applications à faible trafic, une option de CPU inférieure sans multi-concurrence est optimale. Pour d'autres où les démarrages à froid sont un problème critique, la définition d'une simultanéité élevée et d'instances minimales signifie qu'un ensemble d'instances est toujours maintenu au chaud pour gérer les pics de trafic importants.

Pour les applications à plus petite échelle qui reçoivent très peu de trafic, la définition d'instances maximales faibles avec une simultanéité élevée signifie que l'application peut gérer des rafales de trafic sans encourir de coûts excessifs.

Autoriser les requêtes simultanées

Dans Cloud Functions pour Firebase v1, chaque instance pouvait gérer une requête à la fois. Le comportement de mise à l'échelle était donc défini uniquement avec les paramètres minInstances et maxInstances . En plus de contrôler le nombre d'instances, dans Cloud Functions pour Firebase v2, vous pouvez contrôler le nombre de requêtes que chaque instance peut traiter simultanément avec l'option de concurrency . La valeur par défaut de la simultanéité est 80, mais vous pouvez la définir sur n'importe quel entier compris entre 1 et 1000.

Les fonctions avec des paramètres de simultanéité plus élevés peuvent absorber des pics de trafic sans démarrage à froid, car chaque instance dispose probablement d'une certaine marge. Si une instance est configurée pour gérer jusqu'à 50 requêtes simultanées mais n'en gère actuellement que 25, elle peut gérer un pic de 25 requêtes supplémentaires sans nécessiter le démarrage à froid d'une nouvelle instance. En revanche, avec un paramètre de simultanéité de seulement 1, ce pic de demandes pourrait entraîner 25 démarrages à froid.

Lorsque vous testez des paramètres de simultanéité plus élevés dans Cloud Functions pour Firebase v2, gardez à l'esprit les points suivants :

  • Des paramètres de simultanéité plus élevés peuvent nécessiter un CPU et une RAM plus élevés pour des performances optimales jusqu'à atteindre une limite pratique. Une fonction qui effectue un traitement lourd d'images ou de vidéos, par exemple, peut manquer de ressources pour gérer 1 000 requêtes simultanées, même lorsque ses paramètres de CPU et de RAM sont maximisés.
  • Étant donné que Cloud Functions pour Firebase v2 est optimisé par Cloud Run, vous pouvez également consulter les conseils de Google Cloud pour optimiser la simultanéité .
  • Assurez-vous de tester soigneusement la multiconcurrence dans un environnement de test avant de passer à la multiconcurrence en production.

Réduire le nombre de démarrages à froid

Pour définir le nombre minimum d'instances pour une fonction dans le code source, utilisez l'option minInstances . Par exemple, cette fonction définit un minimum de 5 instances à garder au chaud :

  const { onCall } = require("firebase-functions/v2/https");

  exports.getAutocompleteResponse = onCall(
    {
      // Keep 5 instances warm for this latency-critical function
      minInstances: 5,
    },
    (event) => {
      // Autocomplete user’s search term
    }
  );

Voici quelques éléments à prendre en compte lors de la définition d'une valeur pour minInstances :

  • Si Cloud Functions pour Firebase fait évoluer votre application au-delà de votre paramètre minInstances , vous subirez un démarrage à froid pour chaque instance au-dessus de ce seuil.
  • Les démarrages à froid ont l'effet le plus grave sur les applications avec un trafic irrégulier. Si votre application présente des pics de trafic et que vous définissez une valeur minInstances suffisamment élevée pour que les démarrages à froid soient réduits à chaque augmentation du trafic, vous constaterez une latence considérablement réduite. Pour les applications avec un trafic constant, les démarrages à froid ne sont pas susceptibles d'affecter gravement les performances.
  • La définition d'instances minimales peut être utile pour les environnements de production, mais doit généralement être évitée dans les environnements de test. Pour passer à zéro dans votre projet de test tout en réduisant les démarrages à froid dans votre projet de production, vous pouvez définir minInstances en fonction de la variable d'environnement FIREBASE_CONFIG :

    // Get Firebase project ID from `FIREBASE_CONFIG` environment variable
    const envProjectId = JSON.parse(process.env.FIREBASE_CONFIG).projectId;
    
    exports.renderProfilePage = onRequest(
      {
        // Keep 5 instances warm for this latency-critical function
        // in production only. Default to 0 for test projects.
        minInstances: envProjectId === "my-production-project" ? 5 : 0,
      },
      (req, res) => {
        // render some html
      }
    );
    

Limiter le nombre maximum d'instances pour une fonction

Pour définir le nombre maximal d'instances dans le code source de la fonction, utilisez l'option maxInstances . Par exemple, cette fonction fixe une limite de 100 instances afin de ne pas submerger une hypothétique ancienne base de données :

  const { onMessagePublished } = require("firebase-functions/v2/pubsub");

  exports.mirrorevents = onMessagePublished(
    { topic: "topic-name", maxInstances: 100 },
    (event) => {
      // Connect to legacy database
    }
  );

Si une fonction HTTP est mise à l'échelle jusqu'à la limite maxInstances , les nouvelles demandes sont mises en file d'attente pendant 30 secondes, puis rejetées avec un code de réponse de 429 Too Many Requests si aucune instance n'est disponible à ce moment-là.

Pour en savoir plus sur les bonnes pratiques d'utilisation des paramètres d'instances maximales, consultez ces bonnes pratiques d'utilisation de maxInstances .

Définir le délai d'attente et l'allocation de mémoire

Dans certains cas, vos fonctions peuvent avoir des exigences particulières pour une longue valeur de délai d'attente ou une grande allocation de mémoire. Vous pouvez définir ces valeurs soit dans Google Cloud Console, soit dans le code source de la fonction (Firebase uniquement).

Pour définir l'allocation de mémoire et le délai d'expiration dans le code source des fonctions, utilisez GlobalOptions.memory et GlobalOptions.timeoutSeconds pour personnaliser la machine virtuelle exécutant vos fonctions. Par exemple, cette fonction Cloud Storage utilise 1 Gio de mémoire et expire au bout de 300 secondes :

  exports.convertLargeFile = onObjectFinalized({
    timeoutSeconds: 300,
    memory: "1GiB",
  }, (event) => {
    // Do some complicated things that take a lot of memory and time
  });

La valeur maximale de timeoutSeconds est 540 ou 9 minutes.

Pour définir l'allocation de mémoire et le délai d'expiration dans Google Cloud Console :

  1. Dans Google Cloud Console, sélectionnez Cloud Functions pour Firebase dans le menu de gauche.
  2. Sélectionnez une fonction en cliquant sur son nom dans la liste des fonctions.
  3. Cliquez sur l'icône Modifier dans le menu supérieur.
  4. Sélectionnez une allocation de mémoire dans le menu déroulant intitulé Mémoire allouée .
  5. Cliquez sur Plus pour afficher les options avancées et saisissez un nombre de secondes dans la zone de texte Délai d'expiration.
  6. Cliquez sur Enregistrer pour mettre à jour la fonction.

Remplacer les valeurs par défaut du processeur

Jusqu'à 2 Go de mémoire allouée, chaque fonction dans Cloud Functions pour Firebase v2 utilise par défaut un processeur, puis passe à 2 processeurs pour 4 et 8 Go. Notez que ce comportement est très différent du comportement par défaut de la v1, ce qui pourrait entraîner des coûts légèrement plus élevés pour les fonctions à faible mémoire, comme indiqué dans le tableau suivant :

RAM allouée CPU par défaut version 1 (fractionnel) Processeur par défaut de la version 2 Augmentation de prix par ms
128 Mo 1/12 1 10,5x
256 Mo 1/6 1 5,3x
512 Mo 1/3 1 2,7x
1 Go 7/12 1 1,6x
2 Go 1 1 1 fois
4 Go 2 2 1 fois
8 Go 2 2 1 fois
16 GB n / A 4 n / A

Si vous préférez conserver le comportement v1 pour vos fonctions v2, définissez les valeurs par défaut v1 comme option globale :

// Turn off Firebase defaults
setGlobalOptions({ cpu: 'gcfv1' });

Pour les fonctions gourmandes en CPU, la v2 offre la possibilité de configurer une CPU supplémentaire. Vous pouvez augmenter le processeur par fonction, comme indiqué :

// Boost CPU in a function:
export const analyzeImage = onObjectFinalized({ cpu: 2 }, (event) => {
  // computer vision goes here
});