Apps, die Funktionen der 1. Generation verwenden, sollten gemäß der Anleitung in diesem Leitfaden zur 2. Generation migrieren. Funktionen der 2. Generation verwenden Cloud Run, um eine bessere Leistung, bessere Konfiguration, besseres Monitoring und mehr zu bieten.
In den Beispielen auf dieser Seite wird davon ausgegangen, dass Sie JavaScript mit CommonJS-Modulen (require-Importe) verwenden. Die gleichen Prinzipien gelten jedoch auch für JavaScript mit ESM (import … from-Importe) und TypeScript.
Der Migrationsvorgang
Funktionen der 1. und 2. Generation können in derselben Datei nebeneinander vorhanden sein. So können Sie die Migration ganz einfach nach und nach durchführen, wenn Sie bereit sind. Wir empfehlen, jeweils nur eine Funktion zu migrieren und vor dem Fortfahren Tests und Überprüfungen durchzuführen.
Versionen von Firebase CLI und firebase-function prüfen
Achten Sie darauf, dass Sie mindestens die Firebase CLI-Version 12.00 und die firebase-functions-Version 4.3.0 verwenden. Neuere Versionen unterstützen sowohl die 2. als auch die 1. Generation.
Importe aktualisieren
Funktionen der 2. Generation werden aus dem Unterpaket v2 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 Unterpaket v2 ist modular aufgebaut. Wir empfehlen, nur das benötigte Modul zu importieren.
Vorher: 1. Generation
const functions = require("firebase-functions/v1");
Nachher: 2. Generation
// explicitly import each trigger
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
Triggerdefinitionen aktualisieren
Da im SDK der 2. Generation modulare Importe bevorzugt werden, müssen Sie die Triggerdefinitionen entsprechend den geänderten Importen aus dem vorherigen Schritt aktualisieren.
Die Argumente, die an Callbacks für einige Trigger übergeben werden, haben sich geändert. In diesem Beispiel wurden die Argumente für den onDocumentCreated-Callback in einem einzelnen event-Objekt zusammengefasst. Außerdem haben einige Trigger praktische neue Konfigurationsfunktionen, z. B. die Option cors des Triggers onRequest.
Vorher: 1. Generation
const functions = require("firebase-functions/v1");
exports.date = functions.https.onRequest((req, res) => {
// ...
});
exports.uppercase = functions.firestore
.document("my-collection/{docId}")
.onCreate((change, context) => {
// ...
});
Nachher: 2. Generation
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 unterstützen functions.config nicht mehr. Stattdessen wird eine sicherere Schnittstelle zum deklarativen Definieren von Konfigurationsparametern in Ihrem Code unterstützt.
Mit dem neuen Modul params wird die Bereitstellung durch die CLI blockiert, sofern nicht alle Parameter einen gültigen Wert haben. So wird verhindert, dass eine Funktion ohne Konfiguration bereitgestellt wird.
Vorher: 1. Generation
const functions = require("firebase-functions/v1");
exports.getQuote = functions.https.onRequest(async (req, res) => {
const quote = await fetchMotivationalQuote(functions.config().apiKey);
// ...
});
Nachher: 2. Generation
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());
// ...
}
);
Wenn Sie eine vorhandene Umgebungskonfiguration mit functions.config haben, migrieren Sie diese Konfiguration im Rahmen des Upgrades auf die 2. Generation.
Die functions.config API wird eingestellt und im März 2027 deaktiviert.
Nach diesem Datum schlagen Bereitstellungen mit functions.config fehl.
Um Bereitstellungsfehler zu vermeiden, migrieren Sie Ihre Konfiguration mit der Firebase CLI zu Cloud Secret Manager. Dies ist die effizienteste und sicherste Methode zum Migrieren Ihrer Konfiguration und wird daher dringend empfohlen.
Exportkonfiguration mit der Firebase-Befehlszeile exportieren
Verwenden Sie den Befehl
config export, um Ihre vorhandene Umgebungskonfiguration in ein neues Secret in Cloud Secret Manager zu exportieren:$ 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```Funktionscode aktualisieren, um Secrets zu binden
Wenn Sie die im neuen Secret in Cloud Secret Manager gespeicherte Konfiguration verwenden möchten, verwenden Sie die
defineJsonSecretAPI im Quellcode Ihrer Funktion. Achten Sie außerdem darauf, dass Secrets an alle Funktionen gebunden sind, die sie benötigen.Vorher
const functions = require("firebase-functions/v1"); exports.myFunction = functions.https.onRequest((req, res) => { const apiKey = functions.config().someapi.key; // ... });Nachher
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; // ... });Funktionen bereitstellen
Stellen Sie Ihre aktualisierten Funktionen bereit, um die Änderungen zu übernehmen und die Secret-Berechtigungen zu binden.
firebase deploy --only functions:<your-function-name>
Laufzeitoptionen festlegen
Die Konfiguration von Laufzeitoptionen hat sich zwischen der 1. und der 2. Generation geändert. In der 2. Generation wurde außerdem eine neue Funktion zum Festlegen von Optionen für alle Funktionen hinzugefügt.
Vorher: 1. Generation
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) => {
// ...
});
Nachher: 2. Generation
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) => {
/* ... */
});
Standarddienstkonto aktualisieren (optional)
Während Funktionen der 1. Generation das Google App Engine-Standarddienstkonto verwenden, um den Zugriff auf Firebase APIs zu autorisieren, verwenden Funktionen der 2. Generation das Compute Engine-Standarddienstkonto. Dieser Unterschied kann zu Berechtigungsproblemen bei Funktionen führen, die zur 2. Generation migriert wurden, wenn Sie dem Dienstkonto der 1. Generation spezielle Berechtigungen erteilt haben. Wenn Sie keine Dienstkontoberechtigungen geändert haben, können Sie diesen Schritt überspringen.
Die empfohlene Lösung besteht darin, das vorhandene App Engine-Standarddienstkonto der 1. Generation explizit Funktionen zuzuweisen, die Sie zur 2. Generation migrieren möchten, und so den Standard der 2. Generation zu überschreiben. Dazu müssen Sie dafür sorgen, dass für jede migrierte Funktion der richtige Wert für serviceAccountEmail festgelegt wird:
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) => {
// ...
});
Alternativ können Sie die Dienstkontodetails so ändern, dass sie alle erforderlichen Berechtigungen sowohl für das App Engine-Standarddienstkonto (1. Generation) als auch für das Compute Engine-Standarddienstkonto (2. Generation) enthalten.
Gleichzeitigkeit verwenden
Ein wesentlicher Vorteil von Funktionen der 2. Generation ist die Möglichkeit, dass eine einzelne Funktionsinstanz mehrere Anfragen gleichzeitig verarbeiten kann. So kann die Anzahl der Kaltstarts für Endnutzer erheblich reduziert werden. Standardmäßig ist die Nebenläufigkeit auf 80 festgelegt. Sie können sie jedoch auf einen beliebigen Wert zwischen 1 und 1.000 festlegen:
const {onRequest} = require("firebase-functions/v2/https");
exports.date = onRequest({
// set concurrency value
concurrency: 500
},
(req, res) => {
// ...
});
Durch Anpassen der Parallelität können Sie die Leistung verbessern und die Kosten für Funktionen senken. Weitere Informationen zur Gleichzeitigkeit finden Sie unter Gleichzeitige Anfragen zulassen.
Verwendung globaler Variablen prüfen
Funktionen der 1. Generation, die nicht für die gleichzeitige Ausführung konzipiert wurden, verwenden möglicherweise globale Variablen, die bei jeder Anfrage festgelegt und gelesen werden. Wenn die Nebenläufigkeit aktiviert ist und eine einzelne Instanz beginnt, mehrere Anfragen gleichzeitig zu verarbeiten, kann dies zu Fehlern in Ihrer Funktion führen, da gleichzeitige Anfragen globale Variablen gleichzeitig festlegen und lesen.
Während des Upgrades können Sie die CPU Ihrer Funktion auf gcf_gen1 und concurrency auf 1 festlegen, 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 die Leistungsvorteile von Funktionen der 2. Generation dadurch verloren gehen. Prüfen Sie stattdessen die Verwendung globaler Variablen in Ihren Funktionen und entfernen Sie diese temporären Einstellungen, wenn Sie bereit sind.
Traffic zu den neuen 2nd gen-Funktionen migrieren
Genau wie beim Ändern der Region oder des Triggertyps einer Funktion müssen Sie der 2nd gen-Funktion einen neuen Namen geben und den Traffic langsam darauf umstellen.
Es ist nicht möglich, eine Funktion der 1. Generation mit demselben Namen auf die 2. Generation zu aktualisieren und firebase deploy auszuführen. Andernfalls wird folgender Fehler ausgegeben:
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, müssen Sie dafür sorgen, 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 eine Funktion der 1. Generation haben, die auf Schreibvorgänge in Firestore reagiert, muss Ihre App in einem konsistenten Zustand bleiben, wenn auf diese Ereignisse zweimal reagiert wird, einmal von der Funktion der 1. Generation und einmal von der Funktion der 2. Generation.
- Benennen Sie die Funktion im Code Ihrer Funktionen um. Benennen Sie beispielsweise
resizeImageinresizeImageSecondGenum. - Stellen Sie die Funktion bereit, sodass sowohl die ursprüngliche Funktion der 1. Generation als auch die Funktion der 2. Generation ausgeführt werden.
- Bei aufrufbaren, Task Queue- und HTTP-Triggern müssen Sie alle Clients auf die Funktion der 2. Generation verweisen, indem Sie den Clientcode mit dem Namen oder der URL der Funktion der 2. Generation aktualisieren.
- Bei Hintergrundtriggern reagieren sowohl die Funktionen der 1. als auch der 2. Generation sofort nach der Bereitstellung auf jedes Ereignis.
- Wenn der gesamte Traffic migriert wurde, löschen Sie die Funktion der 1. Generation mit dem Befehl
firebase functions:deleteder Firebase CLI.- Benennen Sie die Funktion der 2. Generation optional so um, dass sie mit dem Namen der Funktion der 1. Generation übereinstimmt.