Für Apps, in denen derzeit Funktionen der 1. Generation verwendet werden, sollten Sie die Migration zur 2. Generation mithilfe der Anleitung in diesem Leitfaden in Betracht ziehen. Funktionen der 2. Generation verwenden Cloud Run, um unter anderem eine höhere Leistung, eine bessere Konfiguration und ein besseres Monitoring zu bieten.
Bei den Beispielen auf dieser Seite wird davon ausgegangen, dass Sie JavaScript mit CommonJS-Modulen (require
-Importe) verwenden. Dieselben Prinzipien gelten jedoch auch für JavaScript mit ESM (import … from
-Importe) und TypeScript.
Der Migrationsvorgang
Funktionen der 1. Generation und der 2. Generation können in derselben Datei nebeneinander bestehen. Dies ermöglicht die einfache Migration Schritt für Schritt, sobald Sie bereit sind. Wir empfehlen, jeweils nur eine Funktion zu migrieren und vor dem Fortfahren Tests und Prüfungen durchzuführen.
Versionen der Firebase CLI und von firebase-function
prüfen
Sie müssen mindestens Firebase CLI-Version 12.00
und firebase-functions
-Version 4.3.0
verwenden. Alle neueren 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.
Anhand dieses anderen Importpfads kann die Firebase-Befehlszeile ermitteln, ob der Funktionscode als Funktion der 1. oder 2. Generation bereitgestellt werden soll.
Das Unterpaket v2
ist modular. Wir empfehlen, nur das erforderliche 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 das SDK der 2. Generation modulare Importe bevorzugt, aktualisieren Sie die Triggerdefinitionen, um die geänderten Importe aus dem vorherigen Schritt widerzuspiegeln.
Die Argumente, die bei einigen Triggern an Callbacks übergeben werden, haben sich geändert. In diesem Beispiel wurden die Argumente für den onDocumentCreated
-Callback in einem einzigen event
-Objekt zusammengefasst. Außerdem haben einige Trigger praktische neue Konfigurationsfunktionen, z. B. die Option cors
des onRequest
-Triggers.
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
Bei Funktionen der 2. Generation wird die Unterstützung für functions.config
zugunsten einer sichereren Schnittstelle für die deklarative Definition von Konfigurationsparametern in Ihrer Codebasis eingestellt. Mit dem neuen params
-Modul blockiert die Befehlszeile die Bereitstellung, es sei denn, alle Parameter haben einen gültigen Wert. So wird verhindert, dass eine Funktion ohne Konfiguration bereitgestellt wird.
Zum Unterpaket params
migrieren
Wenn Sie bisher die Umgebungskonfiguration mit functions.config
verwendet haben, können Sie Ihre vorhandene Konfiguration zu einer parametrierten Konfiguration migrieren.
Vorher: 1. Generation
const functions = require("firebase-functions/v1");
exports.date = functions.https.onRequest((req, res) => {
const date = new Date();
const formattedDate =
date.toLocaleDateString(functions.config().dateformat);
// ...
});
Nachher: 2. Generation
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 festlegen
Beim ersten Bereitstellen werden Sie von der Firebase CLI aufgefordert, alle Parameterwerte anzugeben. Diese werden dann in einer dotenv-Datei gespeichert. Führen Sie firebase functions:config:export
aus, um die Werte aus functions.config zu exportieren.
Für zusätzliche Sicherheit können Sie auch Parametertypen und Validierungsregeln angeben.
Sonderfall: API-Schlüssel
Das params
-Modul ist in Cloud Secret Manager eingebunden, das eine detaillierte Zugriffssteuerung für vertrauliche Werte wie API-Schlüssel bietet. Weitere Informationen finden Sie unter Geheimnisparameter.
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());
// ...
}
);
Laufzeitoptionen festlegen
Die Konfiguration der Laufzeitoptionen hat sich zwischen der 1. und der 2. Generation geändert. Bei der 2. Generation können außerdem Optionen für alle Funktionen festgelegt werden.
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) => {
/* ... */
});
Gleichzeitigkeit verwenden
Ein wesentlicher Vorteil von Funktionen der 2. Generation besteht darin, dass eine einzelne Funktionsinstanz mehrere Anfragen gleichzeitig bedienen kann. So lässt sich die Anzahl der Kaltstarts für Endnutzer drastisch reduzieren. Standardmäßig ist die Gleichzeitigkeit 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 die Optimierung der Parallelität lässt sich die Leistung verbessern und die Kosten von Funktionen senken. Weitere Informationen zur Gleichzeitigkeit finden Sie unter Gleichzeitige Anfragen zulassen.
Nutzung globaler Variablen prüfen
Funktionen der 1. Generation, die nicht für die Parallelität entwickelt wurden, können globale Variablen verwenden, die bei jeder Anfrage festgelegt und gelesen werden. Wenn die Gleichzeitigkeit aktiviert ist und eine einzelne Instanz damit beginnt, mehrere Anfragen gleichzeitig zu verarbeiten, kann dies zu Fehlern in der Funktion führen, da gleichzeitige Anfragen mit dem Festlegen und Lesen globaler Variablen beginnen.
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, sobald Sie fertig sind.
Traffic zu den neuen Funktionen der 2. Generation migrieren
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 Traffic nach und nach 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. 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, prüfen Sie, ob 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 Schreibereignisse in Firestore reagiert, achten Sie darauf, dass Ihre App in einem konsistenten Zustand bleibt, wenn auf ein Schreibereignis zweimal reagiert wird, einmal durch die Funktion der 1. Generation und einmal durch die Funktion der 2. Generation.
- Benennen Sie die Funktion im Funktionscode um. Benennen Sie beispielsweise
resizeImage
inresizeImageSecondGen
um. - Binden Sie die Funktion so ein, dass sowohl die ursprüngliche Funktion der 1. Generation als auch die Funktion der 2. Generation ausgeführt werden.
- Bei aufrufbaren Funktionen, Task-Queues und HTTP-Triggern müssen Sie alle Clients auf die Funktion der 2. Generation verweisen. Aktualisieren Sie dazu den Clientcode mit dem Namen oder der URL der Funktion der 2. Generation.
- Bei Hintergrundtriggern reagieren sowohl 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:delete
der Firebase CLI.- Optional können Sie die Funktion der 2. Generation in den Namen der Funktion der 1. Generation umbenennen.