Aktualisieren Sie die Node.js-Funktionen der 1. Generation auf die 2. Generation

Apps, die derzeit Funktionen der 1. Generation verwenden, sollten anhand der Anweisungen in diesem Handbuch eine Migration auf die 2. Generation in Betracht ziehen. Funktionen der 2. Generation nutzen Cloud Run, um bessere Leistung, bessere Konfiguration, bessere Überwachung und mehr zu bieten.

Bei den Beispielen auf dieser Seite wird davon ausgegangen, dass Sie JavaScript mit CommonJS-Modulen verwenden (Stilimporte require ), aber die gleichen Prinzipien gelten für JavaScript mit ESM ( import … from Stilimporten) und TypeScript.

Der Migrationsprozess

Funktionen der 1. und 2. Generation können nebeneinander in derselben Datei vorhanden sein. Dies ermöglicht eine einfache, schrittweise Migration, je nach Bedarf. Wir empfehlen, jeweils eine Funktion zu migrieren und Tests und Überprüfungen durchzuführen, bevor Sie fortfahren.

Überprüfen Sie die Versionen der Firebase-CLI und firebase-function

Stellen Sie sicher, dass Sie mindestens Firebase CLI Version 12.00 und firebase-functions Version 4.3.0 verwenden. Jede neuere Version unterstützt sowohl die 2. als auch die 1. Generation.

Importe aktualisieren

Funktionen der 2. Generation werden aus dem v2 Unterpaket im firebase-functions SDK importiert. Dieser andere Importpfad ist alles, was die Firebase-CLI benötigt, um zu bestimmen, ob Ihr Funktionscode als Funktion der 1. oder 2. Generation bereitgestellt werden soll.

Das v2 -Unterpaket ist modular und wir empfehlen, nur das spezifische Modul zu importieren, das Sie benötigen.

Vorher: 1. Gen

const functions = require("firebase-functions");

Nachher: ​​2. Gen

// explicitly import each trigger
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

Triggerdefinitionen aktualisieren

Da das SDK der 2. Generation modulare Importe bevorzugt, aktualisieren Sie die Triggerdefinitionen, um die geänderten Importe aus dem vorherigen Schritt widerzuspiegeln.

Die an Rückrufe übergebenen Argumente für einige Trigger haben sich geändert. Beachten Sie in diesem Beispiel, dass die Argumente für den onDocumentCreated Rückruf in einem einzigen event konsolidiert wurden. Darüber hinaus verfügen einige Trigger über praktische neue Konfigurationsfunktionen, wie beispielsweise die Option cors des onRequest Triggers.

Vorher: 1. Gen

const functions = require("firebase-functions");

exports.date = functions.https.onRequest((req, res) => {
  // ...
});

exports.uppercase = functions.firestore
  .document("my-collection/{docId}")
  .onCreate((change, context) => {
    // ...
  });

Nachher: ​​2. Gen

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) => {
  /* ... */
});

Parametrisierte Konfiguration verwenden

Funktionen der 2. Generation verzichten auf die Unterstützung von functions.config zugunsten einer sichereren Schnittstelle zum deklarativen Definieren von Konfigurationsparametern in Ihrer Codebasis. Mit dem neuen params Modul blockiert die CLI die Bereitstellung, es sei denn, alle Parameter haben einen gültigen Wert, um sicherzustellen, dass eine Funktion nicht mit fehlender Konfiguration bereitgestellt wird.

Migrieren Sie zum Unterpaket params

Wenn Sie die Umgebungskonfiguration mit functions.config verwendet haben, können Sie Ihre vorhandene Konfiguration in eine parametrisierte Konfiguration migrieren.

Vorher: 1. Gen

const functions = require("firebase-functions");

exports.date = functions.https.onRequest((req, res) => {
  const date = new Date();
  const formattedDate =
date.toLocaleDateString(functions.config().dateformat);

  // ...
});

Nachher: ​​2. Gen

const {onRequest} = require("firebase-functions/v2/https");
const {defineString} = require("firebase-functions/params");

const dateFormat = defineString("DATE_FORMAT");

exports.date = onRequest((req, res) => {
  const date = new Date();
  const formattedDate = date.toLocaleDateString(dateFormat.value());

  // ...
});

Parameterwerte einstellen

Bei der ersten Bereitstellung fordert die Firebase-CLI alle Parameterwerte an und speichert die Werte in einer dotenv-Datei. Um Ihre Functions.config-Werte zu exportieren, führen Sie firebase functions:config:export aus.

Für zusätzliche Sicherheit können Sie auch Parametertypen und Validierungsregeln angeben.

Sonderfall: API-Schlüssel

Das params Modul lässt sich in Cloud Secret Manager integrieren, der eine differenzierte Zugriffskontrolle auf vertrauliche Werte wie API-Schlüssel bietet. Weitere Informationen finden Sie unter geheime Parameter .

Vorher: 1. Gen

const functions = require("firebase-functions");

exports.getQuote = functions.https.onRequest(async (req, res) => {
  const quote = await fetchMotivationalQuote(functions.config().apiKey);
  // ...
});

Nachher: ​​2. Gen

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());
    // ...
  }
);

Legen Sie Laufzeitoptionen fest

Die Konfiguration der Laufzeitoptionen hat sich zwischen der 1. und 2. Generation geändert. Die 2. Generation bietet außerdem eine neue Möglichkeit zum Festlegen von Optionen für alle Funktionen.

Vorher: 1. Gen

const functions = require("firebase-functions");

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) => {
    // ...
  });

Nachher: ​​2. Gen

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) => {
  /* ... */
});

Nutzen Sie Parallelität

Ein wesentlicher Vorteil von Funktionen der 2. Generation ist die Fähigkeit einer einzelnen Funktionsinstanz, mehr als eine Anfrage gleichzeitig zu bedienen. Dadurch kann die Anzahl der Kaltstarts für Endbenutzer drastisch reduziert werden. Standardmäßig ist die Parallelität auf 80 eingestellt, Sie können sie jedoch auf einen beliebigen Wert zwischen 1 und 1000 festlegen:

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

exports.date = onRequest({
    // set concurrency value
    concurrency: 500
  },
  (req, res) => {
    // ...
});

Die Optimierung der Parallelität kann die Leistung verbessern und die Kosten von Funktionen senken. Weitere Informationen zur Parallelität finden Sie unter Gleichzeitige Anfragen zulassen .

Überwachen Sie die Verwendung globaler Variablen

Funktionen der 1. Generation, die ohne Berücksichtigung der Parallelität geschrieben wurden, verwenden möglicherweise globale Variablen, die bei jeder Anfrage festgelegt und gelesen werden. Wenn Parallelität aktiviert ist und eine einzelne Instanz beginnt, mehrere Anfragen gleichzeitig zu verarbeiten, kann dies zu Fehlern in Ihrer Funktion führen, da gleichzeitige Anfragen gleichzeitig globale Variablen festlegen und lesen.

Während des Upgrades können Sie die CPU Ihrer Funktion auf gcf_gen1 und concurrency auf 1 setzen, um das Verhalten der 1. Generation wiederherzustellen:

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

exports.date = onRequest({
    // TEMPORARY FIX: remove concurrency
    cpu: "gcf_gen1",
    concurrency: 1
  },
  (req, res) => {
    // ...
});

Dies wird jedoch nicht als langfristige Lösung empfohlen, da dadurch die Leistungsvorteile der Funktionen der 2. Generation verloren gehen. Überwachen Sie stattdessen die Verwendung globaler Variablen in Ihren Funktionen und entfernen Sie diese temporären Einstellungen, wenn Sie bereit sind.

Migrieren Sie den Datenverkehr auf die neuen Funktionen der 2. Generation

Genau wie beim Ändern der Region oder des Triggertyps einer Funktion müssen Sie der Funktion der 2. Generation einen neuen Namen geben und den Datenverkehr langsam dorthin migrieren.

Es ist nicht möglich, eine Funktion mit demselben Namen von der 1. auf die 2. Generation zu aktualisieren und firebase deploy auszuführen. Dies führt zu folgendem Fehler:

Upgrading from GCFv1 to GCFv2 is not yet supported. Please delete your old function or wait for this feature to be ready.

Bevor Sie diese Schritte ausführen, stellen Sie zunächst sicher, dass Ihre Funktion idempotent ist, da während der Änderung sowohl die neue als auch die alte Version Ihrer Funktion gleichzeitig ausgeführt werden. Wenn Sie beispielsweise über eine Funktion der 1. Generation verfügen, die auf Schreibereignisse in Firestore reagiert, stellen Sie sicher, dass die Reaktion auf einen Schreibvorgang zweimal, einmal durch die Funktion der 1. Generation und einmal durch die Funktion der 2. Generation, als Reaktion auf diese Ereignisse Ihre App in einem Zustand hinterlässt konsistenter Zustand.

  1. Benennen Sie die Funktion in Ihrem Funktionscode um. Benennen Sie beispielsweise resizeImage in resizeImageSecondGen um.
  2. Stellen Sie die Funktion bereit, sodass sowohl die ursprüngliche Funktion der 1. Generation als auch die Funktion der 2. Generation ausgeführt werden.
    1. Beginnen Sie bei aufrufbaren Triggern, Aufgabenwarteschlangen- und HTTP-Triggern damit, alle Clients auf die Funktion der 2. Generation zu verweisen, indem Sie den Clientcode mit dem Namen oder der URL der Funktion der 2. Generation aktualisieren.
    2. Mit Hintergrundauslösern reagieren sowohl die Funktionen der 1. als auch der 2. Generation sofort nach der Bereitstellung auf jedes Ereignis.
  3. Wenn der gesamte Datenverkehr migriert ist, löschen Sie die Funktion der 1. Generation mit dem firebase functions:delete der Firebase-CLI.
    1. Benennen Sie optional die Funktion der 2. Generation um, sodass sie mit dem Namen der Funktion der 1. Generation übereinstimmt.