In dieser Anleitung erfahren Sie, wie Sie Ihre Erweiterungen von der eingestellten Umgebung Firebase Extensions zu einer Funktion migrieren, die Ihre Nutzer in ihrem eigenen Cloud Functions für die Firebase-Codebasis (2. Generation) installieren und bereitstellen.
Dies ist der empfohlene Migrationspfad. Firebase führt eine Liste von Erweiterungen mit offiziellen npm-Entsprechungen. In diesem Leitfaden erfahren Sie, wie Sie Ihre eigene erstellen.
In dieser Anleitung wird die Erweiterung Firestore in BigQuery streamen (firestore-bigquery-export) als Beispiel verwendet. Jeder Abschnitt endet mit einem Beispiel, das zeigt, wie die Erweiterung vor der Migration aussah und wie sie nach der Migration als @firebase/firestore-bigquery-export-Paket aussieht.
Registrieren, um weitere Informationen und Hilfe bei der Migration von Erweiterungen zu erhalten
Wenn Sie Fragen zur Migration von Firebase Extensions haben, können Sie uns unter firebase-extensions-migrator-support-external@google.com erreichen. Wir senden dieser Gruppe auch eine E-Mail, wenn wir die Anleitung mit weiteren Informationen zum Verpacken, Testen und Verteilen Ihrer Funktionen der 2. Generation aktualisieren.
Wenn Sie dieser Gruppe beitreten möchten, senden Sie eine Nachricht an firebase-extensions-migrator-support-external+subscribe@google.com. Sie erhalten dann eine E-Mail mit einer Beitrittsanfrage. Sie müssen auf diese E‑Mail antworten und dürfen nicht auf die Schaltfläche „Dieser Gruppe beitreten“ klicken.
Hinweis
Für diese Migration verwenden Sie die folgenden Funktionen von Cloud Functions:
Parametrisierte Konfiguration: Jeder Parameter, den Sie in
extension.yamldeklarieren, wird zu einem definierten Parameter in Ihrem Paketcode.Deklarative IAM-Rollen und erforderliche APIs Jede Rolle, die Sie in
extension.yamldeklarieren, wird zu einemrequiresRole(...)-Aufruf und jede API zu einemrequiresAPI(...)-Aufruf in Ihrem Funktionscode. Bei der Bereitstellung weist die Firebase-Befehlszeile dem Dienstkonto einer verwalteten Laufzeitumgebung die deklarierten Rollen zu und aktiviert die deklarierten APIs in Ihrem Namen.Lebenszyklusereignisse für Cloud Functions-Codebases: Cloud Functions Codebases unterstützen jetzt Lebenszyklusereignisse analog zu Firebase Extensions. Deklarieren Sie die Einrichtung bei der Installation und beim Update mit den Lebenszyklus-Hooks
afterFirstDeploy(...)undafterRedeploy(...). Diese ersetzen dielifecycleEvents, die Sie inextension.yamldeklarieren.
Erweiterung inventarisieren
Erstellen Sie zuerst ein Inventar Ihrer Erweiterung. Das ist eine vollständige Liste aller Elemente, die in der Erweiterung deklariert, ausgeliefert und dokumentiert werden. So hat jedes Verhalten ein definiertes Ziel in der Funktion der 2. Generation und nichts geht bei der Migration verloren.
Prüfen Sie die folgenden Punkte und notieren Sie sich, was Sie finden:
extension.yaml, in der Sie Ihre Parameter, Funktionen, Ereignisse, IAM-Rollen, erforderlichen APIs, Secrets und Lebenszyklus-Hooks deklarieren.functions/, die Ihren Funktionscode, Ihre Abhängigkeiten, Ihre Build-Konfiguration, Ihre Trigger und Ihre Aufgabenwarteschlangenfunktionen enthält.README.md,PREINSTALL.mdundPOSTINSTALL.mdmit Einrichtungsanleitungen, Warnungen und Abrechnungshinweisen.scripts/, das alle Import-, Backfill-, IAM-, Reparatur- oder Migrationsdienstprogramme sowie alle anderen Tools enthält, die Sie zusammen mit der Erweiterung bereitstellen.
Entscheiden Sie dann für jedes Element in extension.yaml, wo es im npm-Paket platziert werden soll:
Nutzerkonfiguration in Cloud Functions-Parameter umwandeln (Abschnitt 5).
Secrets in Cloud Functions-Secrets umwandeln (Abschnitt 6).
IAM-Rollen in
requiresRole(...)-Deklarationen umwandeln (Abschnitt 8).Erforderliche Google-APIs in
requiresAPI(...)-Deklarationen konvertieren (Abschnitt 8).Installations- und Update-Hooks in
afterFirstDeploy(...)- undafterRedeploy(...)-Deklarationen umwandeln (Abschnitt 8).
Beispiel:Firestore-Daten in BigQuery streamen
Beim Lesen von „firestore-bigquery-export/extension.yaml“ und „functions/“ wird Folgendes ermittelt:
| In extension.yaml | Anzahl / Wert | Wohin gelangen sie? |
|---|---|---|
| params | 25 (COLLECTION_PATH, DATASET_ID, TABLE_ID, DATASET_LOCATION, VIEW_TYPE, …) | Cloud Functions-Parameter (Abschnitt 5) |
| APIs | bigquery.googleapis.com | requiresAPI(...) (Abschnitt 7) |
| Rollen | bigquery.dataEditor, datastore.user, bigquery.user | requiresRole(...) (Abschnitt 7) |
| Ressourcen | 1 Ereignistrigger (fsexportbigquery) + Aufgabenwarteschlangen-Funktionen (initBigQuerySync, setupBigQuerySync) | Exportierte Paketfunktionen (Abschnitt 3) |
| lifecycleEvents | onInstall → initBigQuerySync; onUpdate / onConfigure → setupBigQuerySync | afterFirstDeploy / afterRedeploy (Abschnitt 9) |
| scripts/ | import/ (Backfill), gen-schema-view/ | Als Skripts beibehalten (nicht relevant für diesen Artikel) |
In der Erweiterung wird kein Typ deklariert: secret params. Daher gibt es in Abschnitt 6 dieses Leitfadens nichts zu migrieren. Der Ereignistrigger gehört bereits zur 2. Generation. Nur die Task-Queue-Funktionen gehören noch zur 1. Generation (relevant in Abschnitt 3).
package.json aktualisieren
Aktualisieren Sie die package.json-Datei Ihrer Erweiterung. Wenn Sie eine Erweiterung migrieren, kann dies das Stammverzeichnis package.json sein. Wenn Sie viele Erweiterungen in einem Repository migrieren, geben Sie jeder Erweiterung ein eigenes Paket.
Mindestens erforderliche SDK-Versionen. Deklarieren Sie „firebase-functions“ >= 7.3 und „firebase-admin“ >= 14.2.0 als Abhängigkeiten. Deklarieren Sie Ihre Version von firebase-functions auch als Peer-Abhängigkeit.
{
"name": "<package-name>",
"version": "1.0.0",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"default": "./lib/index.js"
}
},
"engines": {
"node": ">=22"
},
"peerDependencies": {
"firebase-functions": "^7.3.0"
},
"dependencies": {
"firebase-functions": "^7.3.0",
"firebase-admin": "^14.2.0"
}
}
Deklarieren Sie „firebase-functions“ zusätzlich zu Ihrer normalen Abhängigkeit als Peer-Abhängigkeit, damit das Cloud Functions-Projekt Ihrer Nutzer dieselbe SDK-Version hat, mit der Ihre Bibliothek geschrieben wurde.
Beispiel:Firestore-Daten in BigQuery streamen
Vorher Die Datei „functions/package.json“ der Erweiterung ist privat, enthält die Erweiterungs-ID und deklariert „firebase-functions“ als direkte Abhängigkeit:
{
"name": "firestore-bigquery-export",
"main": "lib/index.js",
"private": true,
"dependencies": {
"@firebaseextensions/firestore-bigquery-change-tracker": "^2.0.4",
"firebase-admin": "^14.2.0",
"firebase-functions": "^6.3.2"
}
}
Nachher Ein veröffentlichbares Paket: Bereichsname, eine Exportzuordnung und firebase-functions wurde nach peerDependencies verschoben:
{
"name": "@firebase/firestore-bigquery-export",
"version": "0.1.0",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"exports": {
".": { "types": "./lib/index.d.ts", "default": "./lib/index.js" }, },
"engines": { "node": ">=22" },
"peerDependencies": { "firebase-functions": "^7.3.0" },
"dependencies": {
"@firebaseextensions/firestore-bigquery-change-tracker": "^2.0.4",
"firebase-admin": "^14.2.0",
"firebase-functions": "^7.3.0"
}
}
Funktionen von der 1. Generation auf die 2. Generation upgraden
Wenn in Ihrer Erweiterung weiterhin Funktionen der 1. Generation exportiert werden, konvertieren Sie jede Funktion in ihr Äquivalent der 2. Generation. Importieren Sie die firebase-functions/...-Module und übergeben Sie Laufzeiteinstellungen in den Funktionsoptionen.
Mit der gepatchten Ereignis-Destrukturierung der 2. Generation können Sie den Aufwand für das Umschreiben minimieren und die Logik Ihrer Funktion beibehalten, da das SDK der 2. Generation die V1-Parameter jetzt als Felder im Ereignisobjekt verfügbar macht. So können Sie destrukturierte/benannte Parameter verwenden und Ihre Geschäftslogik unverändert lassen.
Vorher 1. Generation:
import * as functions from "firebase-functions/v1";
export const sync = functions.firestore
.document("{collectionId}/{documentId}")
.onWrite(async (change, context) => {
await handleWrite(change.before, change.after, context.params);
});
Nachher 2. Generation:
import { onDocumentWritten } from "firebase-functions/firestore";
export const syncV2 = onDocumentWritten(
{ document: "{collectionId}/{documentId}" },
async ({change,context}) =>
await handleWrite(change.before, change.after, context.params);
);
Eine umfassende Liste der Unterschiede zwischen Funktionen der 1. und 2. Generation finden Sie im Cloud Functions-Versionsvergleich.
Erweiterungsparameter und Secrets konvertieren
Parameter konvertieren
Jeder Parameter, den Sie in extension.yaml deklarieren, wird zu einem Cloud Functions-Parameter.
Direkte Umgebungsvariablen lesen:
const collectionPath = process.env.COLLECTION_PATH;
in Cloud Functions-Parameter:
import { defineString } from "firebase-functions/params";
import { onDocumentWritten} from "firebase-functions/firestore";
const collectionPath = defineString("COLLECTION_PATH");
// Pass the param directly when used as a placeholder (e.g. trigger path)
export const sync = onDocumentWritten(
{ document: collectionPath },
async (event) => {
// Call .value() to read the string inside a handler
const path = collectionPath.value();
await handleWrite(path, event);
}
);
Verwenden Sie collectionPath.value(), um den String in einem Handler zu lesen. Verwenden Sie collectionPath direkt dort, wo ein Platzhalter erwartet wird, z. B. in einem Funktionsauslöserpfad.
Die Firebase-Befehlszeile erkennt Ihre Parameter und liest ihre Werte aus .env, .env.projectId oder fordert Ihre Nutzer während der Bereitstellung auf, sie einzugeben. Behalten Sie die Parameternamen bei, damit Werte aus einer vorhandenen Installation übernommen werden.
Es ist wichtig, dass Sie die in Ihrem Code deklarierten Parameternamen nicht ändern. Bei der Erweiterungsmigration wird der vorhandene Parameterwert des Endnutzers automatisch beibehalten, aber nur, wenn die Namen unverändert sind.
Beispiel: Firestore-Daten in BigQuery streamen
Vorher Ein in extension.yaml deklarierter Parameter, der in config.ts als Umgebungsvariable gelesen wird:
# extension.yaml
- param: COLLECTION_PATH
label: Collection path
type: string
required: true
// functions/src/config.ts
collectionPath: process.env.COLLECTION_PATH,
Nachher Ein defineString; die CLI erkennt es und liest aus .env:
// src/config.ts
import { defineString } from "firebase-functions/params";
collectionPath: defineString("COLLECTION_PATH", {
label: "Collection path",
// We now support "nonEmpty: true" to ensure a value other than the empty string
// is entered, analagous to "required: true" in extensions.yaml
input: { text: { nonEmpty: true} }
}),
Der Parametername ist unverändert, sodass eine vorhandene .env-Datei weiterhin funktioniert.
Secrets konvertieren
In extension.yaml deklarieren Sie Secrets mit type: secret. Die Extensions-Laufzeit speichert und bindet sie, sodass Ihr Erweiterungscode process.env.PARAM_NAME direkt lesen kann. In einer typischen Cloud Functions-Codebasis deklarieren und binden Sie jedes Secret explizit:
import { defineSecret } from "firebase-functions/params";
import { onRequest } from "firebase-functions/https";
const apiKey = defineSecret("API_KEY");
export const fn = onRequest({ secrets: [apiKey] }, handler);
Nachdem Ihre Erweiterung zu einem npm-Paket/Kit migriert wurde, werden geheime Verweise in der .env-Datei des Endnutzers verwaltet. Es ist wichtig, dass Sie die in Ihrem Code deklarierten Namen der Secrets nicht
ändern. Während der Migration werden die Geheimnisse der Endnutzer entsprechend migriert.
Beispiel:E-Mail über Trigger von Cloud Firestore senden
Vorher MAIL_COLLECTION und SMTP_PASSWORD werden als Rohumgebungsvariablen in config.ts gelesen:
# extension.yaml
- param: MAIL_COLLECTION
label: Email documents collection
type: string
default: mail
required: true
- param: SMTP_PASSWORD
label: SMTP password
type: secret
// functions/src/config.ts
mailCollection: process.env.MAIL_COLLECTION,
smtpPassword: process.env.SMTP_PASSWORD,
Nachher Eine defineString- und eine defineSecret-Datei. Die CLI erkennt beide und liest aus .env.
import { defineString, defineSecret } from "firebase-functions/params";
import { onDocumentWritten } from "firebase-functions/firestore";
const mailCollection = defineString("MAIL_COLLECTION",{ label: "Email documents collection",
default: "mail"
});
const smtpPassword = defineSecret("SMTP_PASSWORD", { label: "SMTP password" });
export const processQueue = onDocumentWritten(
{ document: `${mailCollection}/{documentId}`, secrets: [smtpPassword] },
async (event) => {
const collection = mailCollection.value();
const password = smtpPassword.value();
// ...
}
);
Interne Aufgabenwarteschlangenaufrufe migrieren
Einige Erweiterungen stellen Aufgaben in ihren eigenen Aufgabenwarteschlangen in ihrem Funktionscode mithilfe von Firebase Admin SDK in die Warteschlange. Das ist etwas anderes als das Empfangen einer zugewiesenen Aufgabe (siehe die Abschnitte Funktionen aktualisieren und Lifecycle-Hooks konvertieren). Hier ist Ihr Code der Producer, der queue.enqueue(...) aufruft.
In früheren Versionen von Admin SDK mussten Erweiterungen ihre eigene Erweiterungsinstanz-ID als zweiten Parameter übergeben, um eine Task Queue-Funktion in derselben Erweiterung aufzurufen. Ab `firebase-admin` 14.2.0 ist dies weder erforderlich noch empfehlenswert. Die Task Queue API zielt jetzt standardmäßig auf Aufgabenwarteschlangen im selben Kontext (z.B. Erweiterung) ab. Sie können diesen Parameter in Ihrem Code sowohl als Erweiterung als auch als eigenständige Funktion entfernen. Durch das Entfernen dieses Parameters wird die Portabilität und Vorwärtskompatibilität sichergestellt.
Alles andere am Enqueue-Aufruf – der Ressourcenpfad „locations/region/functions/name“, die Aufgaben-Payload und Ihre Wiederholungslogik – bleibt gleich.
Weitere Informationen zum Einreihen von Funktionen mit Cloud Tasks finden Sie unter /docs/functions/task-functions.
Vorher Erweiterung der 1. Generation
import { getFunctions } from "firebase-admin/functions";
const queue = getFunctions().taskQueue(
`locations/${config.location}/functions/syncBigQuery`,
process.env.EXT_INSTANCE_ID, // extension instance ID, injected by the runtime
);
await queue.enqueue(taskData);
Nachher Erweiterung der 2. Generation
import { getFunctions } from "firebase-admin/functions";
const queue = getFunctions().taskQueue(
`locations/${process.env.FUNCTION_REGION}/functions/syncBigQuery`);
await queue.enqueue(taskData);
Wenn Ihr Enqueue-Aufruf auf eine mit einem Präfix versehene Codebasis abzielt, hat der ermittelte Funktionsname ebenfalls ein Präfix (z. B. orders-syncBigQuery).
Erforderliche APIs und IAM-Rollen deklarieren
Verschieben Sie die IAM- und API-Anforderungen Ihrer Erweiterung aus „extension.yaml“ in den Code:
import { requiresAPI, requiresRole } from "firebase-functions"
requiresAPI("bigquery.googleapis.com", "Needed to write changelog rows");
requiresRole("roles/bigquery.dataEditor");
requiresRole("roles/bigquery.user");
Bei der deklarativen Sicherheit wird mit der Firebase-Befehlszeile ein verwaltetes Laufzeit-Dienstkonto für die Codebasis erstellt oder aktualisiert und ihm die Vereinigung aller deklarierten Rollen zugewiesen. Dokumentieren Sie für Ihre Nutzer, dass alle Funktionen im Code mit diesen Rollen ausgeführt werden, sofern die endgültige API kein eingeschränkteres Modell unterstützt.
Beispiel:Firestore-Daten in BigQuery streamen
Vorher In „extension.yaml“ deklariert; die Extensions-Laufzeit hat die API aktiviert und einem verwalteten Konto die Rollen zugewiesen:
apis:
- apiName: bigquery.googleapis.com
roles:
- role: bigquery.dataEditor
- role: datastore.user
- role: bigquery.user
Nachher Im Code mit „requiresAPI“ und „requiresRole“ deklariert:
import { requiresAPI, requiresRole } from "firebase-functions/";
requiresAPI("bigquery.googleapis.com",
"Needed to write changelog rows and views");
requiresRole("roles/biguqery.dataEditor");
requiresRole("roles/datastore.user");
requiresRole("roles/bigquery.user");
Convert-Lebenszyklus-Hooks
Wenn Ihre Erweiterung getExtensions().runtime() aufruft, z. B. setProcessingState oder setFatalError, löschen Sie diese Aufrufe, da sie einen Fehler auslösen, wenn sie von einer normal bereitgestellten Funktion der 2. Generation aufgerufen werden. Der Lebenszyklusstatus wird jetzt von afterFirstDeploy und afterRedeploy bestimmt, wobei die Statusverfolgung nicht verwendet wird.
Firebase Extensions kann die Einrichtung ausführen, wenn ein Nutzer eine Erweiterung installiert, aktualisiert oder neu konfiguriert. Deklarieren Sie im npm-Paket entsprechende Lebenszyklusaktionen im Code.
Einmalige Einrichtung:
import { afterFirstDeploy } from "firebase-functions/lifecycle";
import { onTaskDispatched } from "firebase-functions/tasks";
export const runInitialSetup = onTaskDispatched(async (request) => {
await initializeResources(request.data);
});
afterFirstDeploy({
task: {
function: "runInitialSetup",
body: {}
}
});
Für Konfigurations- oder Code-Updates:
import { afterRedeploy } from "firebase-functions/lifecycle";
afterRedeploy({
task: {
function: "runInitialSetup",
body: { reconcile: true }
}
});
Machen Sie Ihre Lebenszyklusaktionen idempotent. Wenn die Ausführung fehlschlägt, müssen Ihre Nutzer sie möglicherweise manuell noch einmal ausführen:
firebase functions:lifecycle:run afterFirstDeploy CODEBASE_NAME
firebase functions:lifecycle:run afterRedeploy CODEBASE_NAME
Beispiel:Firestore-Daten in BigQuery streamen
Vorher lifecycleEvents in extension.yaml, aufgrund der Extensions-Laufzeit:
lifecycleEvents:
onInstall:
function: initBigQuerySync
processingMessage: Configuring BigQuery Sync.
onUpdate:
function: setupBigQuerySync
processingMessage: Configuring BigQuery Sync
onConfigure:
function: setupBigQuerySync
processingMessage: Configuring BigQuery Sync
Nachher Im Code deklariert; die Aufgaben stellen bei der ersten Bereitstellung BigQuery bereit:
import { afterFirstDeploy, afterRedeploy } from "firebase-functions/lifecycle";
afterFirstDeploy({ task: { function: "initBigQuerySync" } });
afterRedeploy({ task: { function: "setupBigQuerySync" } });
Die Bereitstellung ist idempotent. Bei einer erneuten Ausführung werden Dataset, Tabelle und Ansichten abgeglichen. Nutzer können den Vorgang mit firebase functions:lifecycle:run afterFirstDeploy CODEBASE_NAME manuell wiederholen.
Dokumenteinrichtung für Ihre Nutzer
Schreiben Sie ein Paket
README, in dem mindestens Folgendes erklärt wird:Die
.env-Werte, die für das Paket erforderlich sind.Die Secrets, die für das Paket erforderlich sind, und wie vorhandene Secret-Werte migriert werden.
Die IAM-Rollen, die das Paket mit
requiresRole(...)deklariert.Die Google-APIs, die das Paket aktiviert oder erfordert.
Die vom Paket deklarierten Lebenszyklus-Hooks und wie sie manuell noch einmal ausgeführt werden.
Abrechnungshinweise.
Was hat sich im Vergleich zur ursprünglichen Erweiterung geändert?
Beispiel:Firestore-Daten in BigQuery streamen
Die Paket-README enthält eine konkrete Tabelle mit den Änderungen:
| Bedenken | Als Erweiterung | Als @firebase/firestore-bigquery-export |
|---|---|---|
| Konfiguration | Erweiterungsparameter | Funktionsparameter über .env |
| IAM | Durch Erweiterungen gewährt | requiresRole(...), angewendet bei der Bereitstellung |
| Wird bereitgestellt | Lebenszyklusaufgabe nach Erweiterungen | afterFirstDeploy-Aufgabe / afterRedeploy-Aufgabe |
| Funktionsnamen | ext-instanceId-fsexportbigquery | fsexportbigquery (optional mit Präfix) |
Funktion der 2. Generation testen
Sie sollten jetzt eine Funktion der 2. Generation haben, die sich bei der Bereitstellung identisch mit einer Neuinstallation Ihrer Erweiterung verhält. Im letzten Schritt werden alle Probleme behoben, die versehentlich eingeführt wurden.
Achten Sie darauf, dass Sie firebase-tools
>= 15.25.1 verwenden, und stellen Sie Ihre konvertierte Funktion der 2. Generation in einem Testprojekt mit den entsprechenden Ressourcen bereit, um ihr Verhalten zu testen. Wenn Sie bereits ein Testprojekt zum Testen Ihrer Erweiterung eingerichtet haben, verwenden Sie den folgenden Befehl:
firebase deploy --only functions
Füllen Sie nach der Eingabe dieses Befehls den resultierenden Assistenten aus, in dem Sie nach Parameterwerten gefragt werden. Gehen Sie dabei genauso vor wie beim Ausfüllen des Installationsformulars für die Erweiterung in der Firebase-Konsole.
Beispiel:Firestore-Daten in BigQuery streamen
Wir prüfen die Synchronisierung von Cloud Firestore zu BigQuery von Anfang bis Ende:
- Erstellen Sie in der Cloud Firestore-Konsole die Sammlung, die Sie als COLLECTION_PATH (users) festgelegt haben, falls sie noch nicht vorhanden ist.
- Erstellen Sie ein Dokument mit dem Namen „bigquery-mirror-test“, das beliebige Felder mit beliebigen Werten enthält.
- Fragen Sie in der BigQuery-Konsole die Rohdaten-Changelog-Tabelle ab. Sie sollte eine einzelne Zeile mit der Protokollierung der Dokumenterstellung enthalten:
SELECT * FROM `PROJECT_ID.analytics.users_raw_changelog`
- Fragen Sie die letzte Ansicht ab. Dadurch sollte das letzte Änderungsereignis für das einzige vorhandene Dokument zurückgegeben werden:
bigquery-mirror-test
SELECT * FROM `PROJECT_ID.analytics.users_raw_latest`
- Löschen Sie das Dokument
bigquery-mirror-testin Cloud Firestore. Sie verschwindet aus der neuesten Ansicht und der Rohdaten-Changelog-Tabelle wird einDELETE-Ereignis angehängt.
Mit dem folgenden Befehl können Sie den vollständigen Verlauf eines einzelnen Dokuments aufrufen:
SELECT *
FROM `PROJECT_ID.analytics.users_raw_changelog`
WHERE document_name = "bigquery-mirror-test"
ORDER BY timestamp ASC
Unterschiede zum Testen der Erweiterung:
- Der Trigger wird als
fsexportbigquery(optional mit dem Präfix des Code-Repositorys) und nicht alsext-<instanceId>-fsexportbigquerybereitgestellt. Suchen Sie im Dashboard Cloud Functions und in den Logs nach diesem Namen. - Ihr Code wird jetzt wie gewohnt in den Firebase Local Emulator Suite-Funktionen ausgeführt. Mit
.env.localkönnen Sie den Wert von Parametern festlegen, die im Emulator verwendet werden sollen. Sie können Ihren Code auch mit dem firebase-functions-test SDK testen, wie unter Unittests für Cloud Functions beschrieben. - Die Bereitstellung wird nicht mehr von der Extensions-Laufzeit gesteuert. Wenn die Changelog-Tabelle nach der Bereitstellung fehlt, führen Sie die Einrichtungsaufgabe manuell noch einmal aus:
firebase functions:lifecycle:run afterFirstDeploy CODEBASE_NAME. Der Task ist idempotent. Wenn Sie ihn also noch einmal ausführen, werden Dataset, Tabelle und Ansichten abgeglichen. - Parameterwerte stammen aus
.envund nicht aus dem Installationsformular. Daher sind Wiederholungen vonfirebase deploynicht interaktiv, sobald.envabgeschlossen ist.