Auf dieser Seite werden die Schritte zum Erstellen einer einfachen Firebase-Erweiterung beschrieben, die Sie in Ihren Projekten installieren oder für andere freigeben können. Dieses Beispiel für eine Firebase-Erweiterung, die Ihre Realtime Database auf und wandeln sie in Großbuchstaben um.
1. Umgebung einrichten und Projekt initialisieren
Bevor Sie mit der Erstellung einer Erweiterung beginnen können, müssen Sie einen Build einrichten. mit den erforderlichen Tools.
Installieren Sie Node.js 16 oder höher. Eine Möglichkeit, Node zu installieren, ist die nvm (oder nvm-windows).
Installieren Sie die Firebase CLI oder aktualisieren Sie sie auf die neueste Version. Bis Führen Sie den folgenden Befehl aus, um die App mit
npm
zu installieren oder zu aktualisieren:npm install -g firebase-tools
Verwenden Sie jetzt die Firebase CLI, um ein neues Erweiterungsprojekt zu initialisieren:
Erstellen Sie ein Verzeichnis für die Erweiterung und fügen Sie
cd
hinzu:mkdir rtdb-uppercase-messages && cd rtdb-uppercase-messages
Führen Sie den Befehl
ext:dev:init
der Firebase CLI aus:firebase ext:dev:init
Wählen Sie bei entsprechender Aufforderung JavaScript als Sprache für die Funktionen aus (Hinweis: Sie können auch TypeScript verwenden, wenn Sie Ihre eigene Erweiterung entwickeln. Antworten Sie mit „Ja“, wenn Sie aufgefordert werden, Abhängigkeiten zu installieren. (Übernehmen Sie die Standardwerte für alle anderen Optionen.) Mit diesem Befehl wird die Basis für eine neue Erweiterung, über die Sie mit der Entwicklung Ihrer Erweiterung beginnen können.
2. Beispielerweiterung mit dem Emulator testen
Als die Firebase CLI das neue Erweiterungsverzeichnis initialisiert hat, wurde ein
einfache Beispielfunktion und ein integration-tests
-Verzeichnis, das die
Dateien, die zum Ausführen einer Erweiterung mit der Firebase-Emulator-Suite erforderlich sind.
Führen Sie die Beispielerweiterung im Emulator aus:
Wechseln Sie in das Verzeichnis
integration-tests
:cd functions/integration-tests
Starten Sie den Emulator mit einem Demoprojekt:
firebase emulators:start --project=demo-test
Der Emulator lädt die Erweiterung in eine vordefinierte Dummy-Datei. Projekt (
demo-test
). Die Erweiterung besteht bisher aus einem einzelnen, durch HTTP ausgelöstengreetTheWorld
, die "Hello World" zurückgibt Nachricht senden, wenn Zugriff haben.Wenn der Emulator noch ausgeführt wird, versuche es mit dem
greetTheWorld
der Erweiterung über die URL, die beim Start ausgegeben wurde.In Ihrem Browser wird die Nachricht „Hello World from greet-the-world“ angezeigt.
Der Quellcode für diese Funktion befindet sich im
functions
der Erweiterung -Verzeichnis. Öffnen Sie die Quelle im Editor oder in der IDE Ihrer Wahl:functions/index.js
const functions = require("firebase-functions/v1"); exports.greetTheWorld = functions.https.onRequest((req, res) => { // Here we reference a user-provided parameter // (its value is provided by the user during installation) const consumerProvidedGreeting = process.env.GREETING; // And here we reference an auto-populated parameter // (its value is provided by Firebase after installation) const instanceId = process.env.EXT_INSTANCE_ID; const greeting = `${consumerProvidedGreeting} World from ${instanceId}`; res.send(greeting); });
Während der Emulator ausgeführt wird, werden alle Änderungen, die Sie im Functions-Code vornehmen. Nehmen Sie eine kleine Änderung am
greetTheWorld
-Funktion:functions/index.js
const greeting = `${consumerProvidedGreeting} everyone, from ${instanceId}`;
Speichern Sie die Änderungen. Der Emulator lädt Ihren Code neu. Wenn Sie die Funktions-URL aufrufen, sehen Sie die aktualisierte Begrüßung.
3. Grundlegende Informationen zu „extension.yaml“ hinzufügen
Nachdem Sie eine Entwicklungsumgebung eingerichtet und den Erweiterungsemulator gestartet haben, können Sie mit dem Erstellen Ihrer eigenen Erweiterung beginnen.
Als ersten Schritt kannst du die vordefinierten Metadaten der Erweiterung entsprechend bearbeiten.
die Sie anstelle von greet-the-world
schreiben möchten. Diese Metadaten sind
die in der Datei extension.yaml
gespeichert sind.
Öffnen Sie
extension.yaml
in Ihrem Editor und ersetzen Sie den gesamten Inhalt der Datei durch Folgendes:name: rtdb-uppercase-messages version: 0.0.1 specVersion: v1beta # Firebase Extensions specification version; don't change # Friendly display name for your extension (~3-5 words) displayName: Convert messages to upper case # Brief description of the task your extension performs (~1 sentence) description: >- Converts messages in RTDB to upper case author: authorName: Your Name url: https://your-site.example.com license: Apache-2.0 # Required license # Public URL for the source code of your extension sourceUrl: https://github.com/your-name/your-repo
Beachten Sie die im Feld
name
verwendete Namenskonvention: offizielle Firebase Erweiterungen werden mit einem Präfix benannt, das das primäre Firebase-Produkt angibt. auf der die Erweiterung ausgeführt wird, gefolgt von einer Beschreibung macht. Sie sollten dieselbe Konvention in Ihren eigenen Erweiterungen verwenden.Da Sie den Namen Ihrer Erweiterung geändert haben, sollten Sie auch die Emulator-Konfiguration mit dem neuen Namen:
- Ändern Sie in
functions/integration-tests/firebase.json
den Wertgreet-the-world
inrtdb-uppercase-messages
. functions/integration-tests/extensions/greet-the-world.env
umbenennen infunctions/integration-tests/extensions/rtdb-uppercase-messages.env
.
- Ändern Sie in
Im Erweiterungscode sind noch einige Überreste der greet-the-world
-Erweiterung vorhanden. Lassen Sie sie vorerst. Sie aktualisieren diese in den nächsten Abschnitten.
4. Cloud Functions-Funktion schreiben und als Erweiterungsressource deklarieren
Jetzt können Sie anfangen, Code zu schreiben. In diesem Schritt schreiben Sie eine Cloud Funktion, die die Hauptaufgabe Ihrer Erweiterung ausführt: um Ihre Realtime Database auf Nachrichten zu prüfen und sie in Großbuchstaben umzuwandeln.
Öffnen Sie die Quelle für die Funktionen der Erweiterung (in der
functions
) im Editor oder in der IDE Ihrer Wahl. Ersetzen Sie den Inhalt durch Folgendes:functions/index.js
import { database, logger } from "firebase-functions/v1"; const app = initializeApp(); // Listens for new messages added to /messages/{pushId}/original and creates an // uppercase version of the message to /messages/{pushId}/uppercase // for all databases in 'us-central1' export const makeuppercase = database .ref("/messages/{pushId}/uppercase") .onCreate(async (snapshot, context) => { // Grab the current value of what was written to the Realtime Database. const original = snapshot.val(); // Convert it to upper case. logger.log("Uppercasing", context.params.pushId, original); const uppercase = original.toUpperCase(); // Setting an "uppercase" sibling in the Realtime Database. const upperRef = snapshot.ref.parent.child("upper"); await upperRef.set(uppercase); });
Die alte Funktion, die Sie ersetzt haben, war eine durch HTTP ausgelöste Funktion, ausgeführt, als auf einen HTTP-Endpunkt zugegriffen wurde. Die neue Funktion wird durch Echtzeit-Datenbankereignisse ausgelöst: Sie prüft, ob neue Elemente an einem bestimmten Pfad vorhanden sind, und schreibt bei einem positiven Ergebnis die Großbuchstabenversion des Werts zurück in die Datenbank.
Diese neue Datei verwendet übrigens die ECMAScript-Modulsyntax (
import
undexport
) anstelle von CommonJS (require
). Um ES-Module in Node zu verwenden,"type": "module"
infunctions/package.json
angeben:{ "name": "rtdb-uppercase-messages", "main": "index.js", "type": "module", … }
Jede Funktion in Ihrer Erweiterung muss in der Datei
extension.yaml
deklariert werden. In der Beispielerweiterung wurdegreetTheWorld
als einzige Cloud-Funktion der Erweiterung deklariert. Da Sie sie jetzt durchmakeuppercase
ersetzt haben, müssen Sie auch die Deklaration aktualisieren.Öffnen Sie
extension.yaml
und fügen Sie einresources
-Feld hinzu:resources: - name: makeuppercase type: firebaseextensions.v1beta.function properties: eventTrigger: eventType: providers/google.firebase.database/eventTypes/ref.create # DATABASE_INSTANCE (project's default instance) is an auto-populated # parameter value. You can also specify an instance. resource: projects/_/instances/${DATABASE_INSTANCE}/refs/messages/{pushId}/original runtime: "nodejs18"
Da Ihre Erweiterung jetzt Realtime Database als Trigger verwendet, benötigen Sie um die Konfiguration des Emulators zu aktualisieren, sodass der RTDB-Emulator parallel zum Cloud Functions-Emulator:
Wenn der Emulator noch ausgeführt wird, beenden Sie ihn durch Drücken von Strg+C.
Führen Sie im Verzeichnis
functions/integration-tests
folgenden Befehl aus: Befehl:firebase init emulators
Überspringen Sie bei Aufforderung die Einrichtung eines Standardprojekts und wählen Sie die Funktionen und Datenbankemulatoren. Akzeptieren Sie die Standardports und erlauben Sie dem Einrichtungstool, alle erforderlichen Dateien herunterzuladen.
Starten Sie den Emulator neu:
firebase emulators:start --project=demo-test
Testen Sie die aktualisierte Erweiterung:
Öffnen Sie die Benutzeroberfläche des Datenbankemulators über den vom Emulator ausgegebenen Link als Sie ihn begonnen haben.
Bearbeiten Sie den Stammknoten der Datenbank:
- Feld:
messages
- Typ:
json
- Wert:
{"11": {"original": "recipe"}}
Wenn alles korrekt eingerichtet ist, Die Funktion
makeuppercase
der Erweiterung sollte auslösen und ein untergeordnetes Element hinzufügen Datensatz in Nachricht 11 mit dem Inhalt"upper": "RECIPE"
aufnehmen. Sehen Sie sich die Protokolle und die Datenbank-Tabs der Emulator-Benutzeroberfläche an, um die erwarteten Ergebnisse zu bestätigen.- Feld:
Fügen Sie dem Knoten
messages
weitere untergeordnete Elemente hinzu ({"original":"any text"}
). Jedes Mal, wenn Sie einen neuen Eintrag hinzufügen, muss das Felduppercase
mit dem Großbuchstaben des Feldsoriginal
enthält.
Sie haben jetzt eine vollständige, aber einfache Erweiterung, die auf einem RTDB basiert. Instanz. In den folgenden Abschnitten verfeinern Sie diese Erweiterung, zusätzliche Funktionen. Anschließend bereiten Sie die Erweiterung vor, und erfahren, wie Sie Ihre Erweiterung im Erweiterungs-Hub veröffentlichen.
5. APIs und Rollen deklarieren
Firebase gewährt jeder Instanz einer installierten Erweiterung eingeschränkten Zugriff auf die Projekt und seine Daten mit einem instanzspezifischen Dienstkonto. Jedes Konto hat die Berechtigungen, die für den Betrieb erforderlich sind. Aus diesem Grund müssen Sie Sie müssen explizit alle IAM-Rollen deklarieren, die Ihre Erweiterung erfordert. wenn Nutzer*innen die App installieren Erweiterung hinzufügen, erstellt Firebase ein Dienstkonto mit diesen Rollen, um die Erweiterung auszuführen.
Sie müssen keine Rollen zum Auslösen von Produktereignissen deklarieren,
eine Rolle erklären müssen, um anderweitig mit ihr interagieren zu können. Da die Funktion, die Sie
die im letzten Schritt in Realtime Database geschrieben werden, müssen Sie die Methode
folgende Erklärung an extension.yaml
:
roles:
- role: firebasedatabase.admin
reason: Allows the extension to write to RTDB.
Ebenso deklarieren Sie die Google APIs, die von einer Erweiterung verwendet werden, im Feld apis
. Wenn Nutzer Ihre Erweiterung installieren, werden sie gefragt, ob sie
um diese APIs automatisch für ihr Projekt zu aktivieren. Dies ist normalerweise nur
erforderlich für Nicht-Firebase-Google-APIs und wird für diesen Leitfaden nicht benötigt.
6. Benutzerdefinierte Parameter definieren
Die Funktion, die Sie in den letzten beiden Schritten erstellt haben, hat an einem bestimmten RTDB-Speicherort nach eingehenden Nachrichten gesucht. Manchmal ist es wichtig, einen bestimmten Ort zu beobachten, z. B. wenn Ihre Erweiterung auf einer Datenbankstruktur läuft, die Sie ausschließlich für Ihre Erweiterung verwenden. Meistens werden Sie jedoch können Sie diese Werte für Nutzer konfigurieren, die Ihre Erweiterung in ihrem Projekten. So können Nutzer die Erweiterung für ihre vorhandenen Datenbank-Setup haben.
Der Pfad, den die Erweiterung auf neue Nachrichten überwacht, sollte vom Nutzer konfiguriert werden:
Fügen Sie in der Datei
extension.yaml
einen Abschnittparams
hinzu:- param: MESSAGE_PATH label: Message path description: >- What is the path at which the original text of a message can be found? type: string default: /messages/{pushId}/original required: true immutable: false
Definiert einen neuen String-Parameter, den Nutzer festlegen müssen, wenn sie installieren Ihre Erweiterung.
Gehen Sie in der Datei
extension.yaml
zurück zurmakeuppercase
-Erklärung und ändern Sie das Feldresource
in Folgendes:resource: projects/_/instances/${DATABASE_INSTANCE}/refs/${param:MESSAGE_PATH}
Das
${param:MESSAGE_PATH}
-Token ist ein Verweis auf den gerade definierten Parameter. Wenn Ihre Erweiterung ausgeführt wird, wird dieses Token durch ein beliebiges Wert, den der Nutzer für diesen Parameter konfiguriert hat, mit dem Ergebnis, dass der Die Funktionmakeuppercase
überwacht den vom Nutzer angegebenen Pfad. Sie können können Sie diese Syntax verwenden, um auf beliebige benutzerdefinierte Parameter an beliebiger Stelle inextension.yaml
(und inPOSTINSTALL.md
– dazu später mehr).Sie können auch über den Funktionscode auf benutzerdefinierte Parameter zugreifen.
In der Funktion, die Sie im letzten Abschnitt geschrieben haben, haben Sie den Pfad zu und achten Sie auf Veränderungen. Ändern Sie die Triggerdefinition so, dass sie auf die benutzerdefinierten Wert:
functions/index.js
export const makeuppercase = database.ref(process.env.MESSAGE_PATH).onCreate
In Firebase Extensions ist diese Änderung einzig Dokumentation: Wenn eine Cloud Functions-Funktion als Teil einer Erweiterung bereitgestellt wird, verwendet die Triggerdefinition aus der Datei
extension.yaml
und ignoriert den Parameter Wert, der in der Funktionsdefinition angegeben wurde. Dennoch ist es eine gute Idee, um in Ihrem Code zu dokumentieren, woher dieser Wert stammt.Es kann enttäuschend sein, eine Codeänderung ohne Laufzeit vorzunehmen. aber die wichtigste Lektion ist, dass Sie auf alle benutzerdefinierten Parameter in Ihrem Funktionscode und verwenden Sie ihn als gewöhnlichen Wert in der Logik der Funktion. Fügen Sie zur Veranschaulichung das folgende Log hinzu: um zu zeigen, dass Sie tatsächlich auf den Wert zugreifen, Benutzerdefiniert:
functions/index.js
export const makeuppercase = database.ref(process.env.MESSAGE_PATH).onCreate( async (snapshot, context) => { logger.log("Found new message at ", snapshot.ref); // Grab the current value of what was written to the Realtime Database. ...
Normalerweise werden Nutzer aufgefordert, Werte für Parameter anzugeben, wenn sie eine Erweiterung installieren. Wenn Sie den Emulator zu Test- und Entwicklungszwecken verwenden, Sie überspringen jedoch den Installationsprozess und geben stattdessen Werte an. für benutzerdefinierte Parameter mithilfe einer
env
-Datei.functions/integration-tests/extensions/rtdb-uppercase-messages.env
öffnen und ersetzen Sie dieGREETING
-Definition durch Folgendes:MESSAGE_PATH=/msgs/{pushId}/original
Beachten Sie, dass sich der obige Pfad vom Standardpfad und vom Pfad, den Sie zuvor definiert haben; dass Sie sich selbst beweisen, wenn Sie dass Ihre Definition wirksam wird.
Starten Sie nun den Emulator neu und rufen Sie noch einmal die Benutzeroberfläche des Datenbankemulators auf.
Bearbeiten Sie den Stammknoten der Datenbank unter Verwendung des oben definierten Pfads:
- Feld:
msgs
- Typ:
json
- Wert:
{"11": {"original": "recipe"}}
Wenn du die Datenbankänderungen speicherst, wird der
makeuppercase
der Erweiterung sollte wie zuvor ausgelöst werden, jetzt sollte sie aber auch benutzerdefinierten Parameter an das Konsolenprotokoll übergeben.- Feld:
7. Ereignis-Hooks für benutzerdefinierte Logik bereitstellen
Sie haben als Autor von Erweiterungen bereits gesehen, wie ein Firebase-Produkt
Von der Erweiterung bereitgestellte Logik: Erstellung neuer Datensätze in Realtime Database
Löst die Funktion makeuppercase
aus. Ihre Erweiterung kann ein analoges
zu den Nutzern, die die Erweiterung installiert haben: Ihre Erweiterung kann
Triggerlogik, die der user definiert.
Eine Erweiterung kann synchrone Hooks, asynchrone Hooks oder beides bereitstellen. Mit synchronen Hooks können Nutzende Aufgaben ausführen, die den Abschluss einer der Funktionen der Erweiterung. Dies kann beispielsweise nützlich sein, um Nutzenden eine Möglichkeit, eine benutzerdefinierte Vorverarbeitung durchzuführen, bevor eine Erweiterung ihre Arbeit übernimmt.
In diesem Leitfaden fügen Sie Ihrer Erweiterung einen asynchronen Hook hinzu, der Nutzer können eigene Verarbeitungsschritte definieren, die nach der Erweiterung ausgeführt werden sollen schreibt die Nachricht in Großbuchstaben in Realtime Database. Bei asynchronen Hooks werden benutzerdefinierte Funktionen über Eventarc ausgelöst. Erweiterungen deklarieren die Arten von Ereignissen, die sie ausgeben, und Wenn Nutzer die Erweiterung installieren, wählen sie die Ereignistypen aus, an denen Sie interessiert sind. Wenn er mindestens ein Ereignis auswählt, wird von Firebase ein Eventarc-Kanal für die Erweiterung im Rahmen der Installation. Nutzer können dann eigene Cloud-Funktionen bereitstellen, die auf diesem Kanal lauschen und ausgelöst werden, wenn die Erweiterung neue Ereignisse veröffentlicht.
Führen Sie die folgenden Schritte aus, um einen asynchronen Hook hinzuzufügen:
Fügen Sie der Datei
extension.yaml
den folgenden Abschnitt hinzu, in dem die einen Ereignistyp, den die Erweiterung ausgibt:events: - type: test-publisher.rtdb-uppercase-messages.v1.complete description: >- Occurs when message uppercasing completes. The event subject will contain the RTDB URL of the uppercase message.
Ereignistypen müssen universell eindeutig sein. um die Eindeutigkeit zu gewährleisten, im folgenden Format erstellen:
<publisher-id>.<extension-id>.<version>.<description>
Da du noch keine Publisher-ID hast, verwende vorersttest-publisher
.Fügen Sie am Ende der Funktion
makeuppercase
Code hinzu, der einen -Ereignis des soeben deklarierten Typs ein:functions/index.js
// Import the Eventarc library: import { initializeApp } from "firebase-admin/app"; import { getEventarc } from "firebase-admin/eventarc"; const app = initializeApp(); // In makeuppercase, after upperRef.set(uppercase), add: // Set eventChannel to a newly-initialized channel, or `undefined` if events // aren't enabled. const eventChannel = process.env.EVENTARC_CHANNEL && getEventarc().channel(process.env.EVENTARC_CHANNEL, { allowedEventTypes: process.env.EXT_SELECTED_EVENTS, }); // If events are enabled, publish a `complete` event to the configured // channel. eventChannel && eventChannel.publish({ type: "test-publisher.rtdb-uppercase-messages.v1.complete", subject: upperRef.toString(), data: { "original": original, "uppercase": uppercase, }, });
Bei diesem Beispielcode wird die Tatsache ausgenutzt, dass das
EVENTARC_CHANNEL
Umgebungsvariable wird nur definiert, wenn der Nutzer mindestens eine Variable aktiviert hat Ereignistyp. IstEVENTARC_CHANNEL
nicht definiert, versucht der Code nicht, um Ereignisse zu veröffentlichen.Sie können einem Eventarc-Ereignis zusätzliche Informationen anhängen. Im obigen Beispiel Das Ereignis hat ein
subject
-Feld mit einem Verweis auf den neu erstellten Wert und einedata
-Nutzlast, die das ursprüngliche und Nachrichten in Großbuchstaben. Benutzerdefinierte Funktionen, die das Ereignis auslösen, können diese Informationen zu nutzen.Normalerweise werden die Umgebungsvariablen
EVENTARC_CHANNEL
undEXT_SELECTED_EVENTS
anhand der Optionen definiert, die der Nutzer bei der Installation ausgewählt hat. Definieren Sie diese Variablen für Tests mit dem Emulator manuell in der Dateirtdb-uppercase-messages.env
:EVENTARC_CHANNEL=locations/us-central1/channels/firebase EXT_SELECTED_EVENTS=test-publisher.rtdb-uppercase-messages.v1.complete
Sie haben jetzt alle Schritte ausgeführt, die zum Hinzufügen eines asynchronen Ereignis-Hooks zu Ihrer Erweiterung erforderlich sind.
Um diese neue Funktion auszuprobieren, die Sie gerade implementiert haben, übernehmen Sie in den nächsten Schritten die Rolle eines Nutzers, der die Erweiterung installiert:
Initialisieren Sie im Verzeichnis
functions/integration-tests
ein neues Firebase Projekt:firebase init functions
Lehnen Sie die Einrichtung eines Standardprojekts ab, wählen Sie JavaScript als Cloud Functions-Sprache aus und installieren Sie die erforderlichen Abhängigkeiten. Dieses Projekt stellt das Projekt eines Nutzers dar, in dem Ihre Erweiterung installiert ist.
Bearbeiten Sie
integration-tests/functions/index.js
und fügen Sie den folgenden Code ein:import { logger } from "firebase-functions/v1"; import { onCustomEventPublished } from "firebase-functions/v2/eventarc"; import { initializeApp } from "firebase-admin/app"; import { getDatabase } from "firebase-admin/database"; const app = initializeApp(); export const extraemphasis = onCustomEventPublished( "test-publisher.rtdb-uppercase-messages.v1.complete", async (event) => { logger.info("Received makeuppercase completed event", event); const refUrl = event.subject; const ref = getDatabase().refFromURL(refUrl); const upper = (await ref.get()).val(); return ref.set(`${upper}!!!`); } );
Dies ist ein Beispiel für eine Funktion zur Nachbearbeitung, die ein Nutzer schreiben könnte. In dieser wartet die Funktion auf die Erweiterung, um ein
complete
-Ereignis zu veröffentlichen. Beim Auslösen werden dem neuen Großbuchstaben drei Ausrufezeichen hinzugefügt. .Starte den Emulator neu. Der Emulator lädt die Funktionen der Erweiterung als sowie die Nachbearbeitungsfunktion „Nutzer“ definiert.
Rufen Sie die Benutzeroberfläche des Datenbankemulators auf und bearbeiten Sie den Stammknoten der Datenbank mit Pfad, den Sie oben definiert haben:
- Feld:
msgs
- Typ:
json
- Wert:
{"11": {"original": "recipe"}}
Wenn du die Datenbankänderungen speicherst, wird der
makeuppercase
der Erweiterung und die Funktionextraemphasis
des Nutzers der Reihe nach ausgelöst werden, Dadurch wird im Feldupper
der WertRECIPE!!!
abgerufen.- Feld:
8. Lifecycle-Event-Handler hinzufügen
Die von Ihnen erstellte Erweiterung verarbeitet Nachrichten, während sie erstellt werden. Was ist aber, wenn Ihre Nutzer bereits eine Datenbank mit Nachrichten haben, wenn sie die Erweiterung installieren? Firebase Extensions hat eine Funktion namens Lebenszyklus-Ereignis-Hooks, die Aktionen auslösen, wenn Ihre Erweiterung installiert, aktualisiert oder neu konfiguriert. In diesem Abschnitt verwenden Sie Lebenszyklus-Ereignis-Hooks, um einen Backfill für einen Nachrichtendatenbank des Projekts mit Nachrichten in Großbuchstaben, wenn ein Nutzer installiert Ihre Erweiterung.
Firebase Extensions verwendet Cloud Tasks, um Ihre Lebenszyklus-Event-Handler auszuführen. Ich Event-Handler mithilfe von Cloud Functions definieren wenn eine Instanz Ihres Erweiterung eines der unterstützten Lebenszyklus-Ereignisse erreicht, wenn Sie ein -Handler erstellt haben, wird der Handler einer Cloud Tasks-Warteschlange hinzugefügt. wird Cloud Tasks dann den Handler asynchron auszuführen. Während ein Lebenszyklus-Event-Handler ausgeführt wird, meldet die Firebase Console dem Nutzer, dass die Erweiterungsinstanz in Bearbeitung ist. Es liegt an der Handler-Funktion, fortlaufende Status und Abschluss der Aufgabe an die Nutzenden senden.
So fügen Sie einen Lebenszyklus-Event-Handler hinzu, der vorhandene Nachrichten auffüllt: Folgendes:
Definieren Sie eine neue Cloud Functions-Funktion, die durch Ereignisse in der Aufgabenwarteschlange ausgelöst wird:
functions/index.js
import { tasks } from "firebase-functions/v1"; import { getDatabase } from "firebase-admin/database"; import { getExtensions } from "firebase-admin/extensions"; import { getFunctions } from "firebase-admin/functions"; export const backfilldata = tasks.taskQueue().onDispatch(async () => { const batch = await getDatabase() .ref(process.env.MESSAGE_PATH) .parent.parent.orderByChild("upper") .limitToFirst(20) .get(); const promises = []; for (const key in batch.val()) { const msg = batch.child(key); if (msg.hasChild("original") && !msg.hasChild("upper")) { const upper = msg.child("original").val().toUpperCase(); promises.push(msg.child("upper").ref.set(upper)); } } await Promise.all(promises); if (promises.length > 0) { const queue = getFunctions().taskQueue( "backfilldata", process.env.EXT_INSTANCE_ID ); return queue.enqueue({}); } else { return getExtensions() .runtime() .setProcessingState("PROCESSING_COMPLETE", "Backfill complete."); } });
Beachten Sie, dass die Funktion nur einige Datensätze verarbeitet, bevor sie sich selbst hinzufügt zurück in die Aufgabenwarteschlange. Dies ist eine gängige Strategie, um mit Verarbeitungsaufgaben umzugehen, die nicht innerhalb des Zeitlimits einer Cloud-Funktion abgeschlossen werden können. Da Sie nicht vorhersagen können, wie viele Nachrichten ein Nutzer in der Datenbank gespeichert sind, wenn sie Ihre Erweiterung installieren, die gut passen.
Deklarieren Sie in der Datei
extension.yaml
die Backfill-Funktion als Erweiterung Ressource mit dem AttributtaskQueueTrigger
:resources: - name: makeuppercase ... - name: backfilldata type: firebaseextensions.v1beta.function description: >- Backfill existing messages with uppercase versions properties: runtime: "nodejs18" taskQueueTrigger: {}
Deklarieren Sie dann die Funktion als Handler für den
onInstall
-Lebenszyklus Ereignis:lifecycleEvents: onInstall: function: backfilldata processingMessage: Uppercasing existing messages
Das Backfilling vorhandener Nachrichten ist zwar praktisch, die Erweiterung funktioniert aber auch ohne. In solchen Fällen sollten Sie sind die Lifecycle-Event-Handler optional.
Fügen Sie dazu einen neuen Parameter zu
extension.yaml
hinzu:- param: DO_BACKFILL label: Backfill existing messages description: >- Generate uppercase versions of existing messages? type: select required: true options: - label: Yes value: true - label: No value: false
Überprüfen Sie dann am Anfang der Backfill-Funktion den Wert des
DO_BACKFILL
-Parameter und vorzeitig beenden, wenn er nicht festgelegt ist:functions/index.js
if (!process.env.DO_BACKFILL) { return getExtensions() .runtime() .setProcessingState("PROCESSING_COMPLETE", "Backfill skipped."); }
Durch die oben genannten Änderungen werden vorhandene Nachrichten nach der Installation der Erweiterung in Großbuchstaben umgewandelt.
Bisher haben Sie den Erweiterungsemulator verwendet, um Ihre Erweiterung zu entwickeln und
laufende Änderungen testen. Der Erweiterungsemulator überspringt die Installation jedoch.
Zum Testen des onInstall
-Event-Handlers musst du den
in einem echten Projekt nutzen. Das ist aber genauso gut, da die Erweiterung
dieser automatischen Auffüllfunktion ist die Erweiterung der Anleitung jetzt vollständig mit dem Code ausgestattet.
9. In echtem Firebase-Projekt bereitstellen
Der Erweiterungsemulator ist ein hervorragendes Tool, um während der Entwicklung schnell Änderungen an einer Erweiterung vorzunehmen. Irgendwann sollten Sie sie jedoch in einem echten Projekt ausprobieren.
Richten Sie dazu zuerst ein neues Projekt mit einigen aktivierten Diensten ein:
- Fügen Sie in der Firebase Console eine neue Projekt arbeiten.
- Upgrade für Projekt durchführen zum „Pay as you go“-Tarif. Cloud Functions for Firebase benötigt Ihr Projekt benötigen Sie ein Rechnungskonto. eine Erweiterung installieren.
- Aktivieren Sie in Ihrem neuen Projekt die Realtime Database.
- Da Sie testen möchten, ob Ihre Erweiterung
Installieren Sie einige Beispieldaten in Ihre Echtzeit-Datenbankinstanz:
- Laden Sie einige Seed-RTDB-Daten herunter.
- Klicken Sie auf der Seite „Echtzeitdatenbank“ der Firebase Console auf (mehr) > JSON importieren und wählen Sie die Datei aus, die Sie gerade heruntergeladen haben.
Damit die Backfill-Funktion die Methode
orderByChild
verwenden kann, müssen Sie die Datenbank, um Nachrichten für den Wert vonupper
zu indexieren:{ "rules": { ".read": false, ".write": false, "messages": { ".indexOn": "upper" } } }
Installieren Sie jetzt die Erweiterung aus der lokalen Quelle im neuen Projekt:
Erstellen Sie ein neues Verzeichnis für Ihr Firebase-Projekt:
mkdir ~/extensions-live-test && cd ~/extensions-live-test
Initialisieren Sie im Arbeitsverzeichnis ein Firebase-Projekt:
firebase init database
Wählen Sie das gerade erstellte Projekt aus, wenn Sie dazu aufgefordert werden.
Installieren Sie die Erweiterung in Ihrem lokalen Firebase-Projekt:
firebase ext:install /path/to/rtdb-uppercase-messages
Hier sehen Sie, wie die Installation eines mit dem Firebase CLI-Tool. Achten Sie darauf, „Ja“ auszuwählen. wenn das Ereignis Konfigurationstool fragt, ob Sie ein Backfill für Ihre vorhandene Datenbank ausführen möchten.
Nachdem Sie die Konfigurationsoptionen ausgewählt haben, speichert die Firebase CLI Ihre Konfiguration im Verzeichnis
extensions
und notieren Sie sich die Erweiterungsquelle Speicherort in der Dateifirebase.json
. Zusammen sind diese beiden Datensätze das Erweiterungsmanifest. Nutzer können das Manifest verwenden, um ihre Konfiguration von Erweiterungen und stellen sie in verschiedenen Projekten bereit.Stellen Sie die Erweiterungskonfiguration für Ihr Live-Projekt bereit:
firebase deploy --only extensions
Wenn alles richtig funktioniert, sollte die Firebase CLI Ihre Erweiterung in Ihr Projekt hochladen und installieren. Nach Abschluss der Installation wird die Backfill-Aufgabe ausgeführt. wird Ihre Datenbank mit Nachrichten in Großbuchstaben aktualisiert. Füge welche hinzu neue Knoten zur Nachrichtendatenbank hinzu und stellen Sie sicher, dass die Erweiterung für neue Nachrichten.
10. Dokumentation schreiben
Stellen Sie vor der Freigabe Ihrer Erweiterung sicher, dass Sie damit sie erfolgreich sind.
Bei der Initialisierung des Erweiterungsprojekts hat die Firebase CLI einen Stub erstellt Versionen der erforderlichen Mindestdokumentation. Aktualisieren Sie diese Dateien, damit sie die von Ihnen erstellte Erweiterung korrekt widerspiegeln.
Erweiterung.yaml
Sie haben diese Datei mit dieser Erweiterung bereits aktualisiert. Sie müssen momentan keine weiteren Aktualisierungen vornehmen.
Sie dürfen jedoch nicht übersehen, wie wichtig die in diesem Dokument
-Datei. Neben den wichtigen Identifizierungsinformationen einer Erweiterung, wie Name,
Beschreibung, Autor, offizieller Repository-Speicherort (extension.yaml
)
Datei enthält eine an den Nutzer gerichtete Dokumentation für jede Ressource und kann vom Nutzer konfiguriert werden.
. Diese Informationen werden Nutzern
in der Firebase Console angezeigt,
Extensions Hub und Firebase CLI.
PREINSTALL.md:
Geben Sie in dieser Datei Informationen an, die der Nutzer benötigt, bevor er Ihre App installiert. Erweiterung: Beschreiben Sie kurz die Funktion der Erweiterung, erklären Sie alle Voraussetzungen, und Nutzer darüber zu informieren, welche Auswirkungen die Installation der . Wenn du eine Website mit zusätzlichen Informationen hast, ist dies auch ein um es zu verknüpfen.
Der Text dieser Datei wird dem Nutzer im Extensions Hub und über den Befehl firebase ext:info
angezeigt.
Hier ist ein Beispiel für eine PREINSTALL-Datei:
Use this extension to automatically convert strings to upper case when added to
a specified Realtime Database path.
This extension expects a database layout like the following example:
"messages": {
MESSAGE_ID: {
"original": MESSAGE_TEXT
},
MESSAGE_ID: {
"original": MESSAGE_TEXT
},
}
When you create new string records, this extension creates a new sibling record
with upper-cased text:
MESSAGE_ID: {
"original": MESSAGE_TEXT,
"upper": UPPERCASE_MESSAGE_TEXT,
}
#### Additional setup
Before installing this extension, make sure that you've
[set up Realtime Database](https://firebase.google.com/docs/database/quickstart)
in your Firebase project.
#### Billing
To install an extension, your project must be on the
[Blaze (pay as you go) plan](https://firebase.google.com/pricing).
- This extension uses other Firebase and Google Cloud Platform services, which
have associated charges if you exceed the service's no-cost tier:
- Realtime Database
- Cloud Functions (Node.js 10+ runtime)
[See FAQs](https://firebase.google.com/support/faq#extensions-pricing)
- If you enable events,
[Eventarc fees apply](https://cloud.google.com/eventarc/pricing).
POSTINSTALL.md
Diese Datei enthält Informationen, die für Nutzer nützlich sind, nachdem sie Ihre Erweiterung installiert haben. Dazu gehören beispielsweise weitere Einrichtungsschritte und ein Beispiel für die Verwendung der Erweiterung.
Der Inhalt von POSTINSTALL.md wird in der Firebase Console angezeigt, nachdem eine Erweiterung konfiguriert und installiert wurde. Sie können in diesem und werden durch die konfigurierten Werte ersetzt.
Hier ist eine Beispieldatei für die Erweiterung nach der Installation:
### See it in action
You can test out this extension right away!
1. Go to your
[Realtime Database dashboard](https://console.firebase.google.com/project/${param:PROJECT_ID}/database/${param:PROJECT_ID}/data) in the Firebase console.
1. Add a message string to a path that matches the pattern `${param:MESSAGE_PATH}`.
1. In a few seconds, you'll see a sibling node named `upper` that contains the
message in upper case.
### Using the extension
We recommend adding data by pushing -- for example,
`firebase.database().ref().push()` -- because pushing assigns an automatically
generated ID to the node in the database. During retrieval, these nodes are
guaranteed to be ordered by the time they were added. Learn more about reading
and writing data for your platform (iOS, Android, or Web) in the
[Realtime Database documentation](https://firebase.google.com/docs/database/).
### Monitoring
As a best practice, you can
[monitor the activity](https://firebase.google.com/docs/extensions/manage-installed-extensions#monitor)
of your installed extension, including checks on its health, usage, and logs.
CHANGELOG.md
Sie sollten auch die Änderungen dokumentieren, die Sie zwischen den Releases einer Erweiterung vornehmen.
in der Datei CHANGELOG.md
.
Da die Beispielerweiterung noch nie veröffentlicht wurde, wurde das Änderungsprotokoll nur einen Eintrag:
## Version 0.0.1
Initial release of the _Convert messages to upper case_ extension.
README.md
Die meisten Erweiterungen bieten auch eine Readme-Datei zum Vorteil der Besucher der Website des Repositorys der Erweiterung. können Sie diese Datei von Hand schreiben mit dem -Befehl.
Für die Zwecke dieses Leitfadens überspringen Sie das Schreiben einer Readme-Datei.
Zusätzliche Dokumentation
Die oben erläuterte Dokumentation ist die Mindestmenge an Dokumentation, die Sie den Nutzenden bieten. Viele Erweiterungen erfordern eine detailliertere Dokumentation, erfolgreich einsetzen können. In diesem Fall sollten Sie zusätzliche und an einem Ort hosten, an den Sie die Nutzenden verweisen können.
Für die Zwecke dieses Leitfadens überspringen Sie das Schreiben einer ausführlicheren Dokumentation.
11. Im Erweiterungs-Hub veröffentlichen
Der Code Ihrer Erweiterung ist vollständig und dokumentiert. Jetzt können Sie sie teilen. im Erweiterungs-Hub mit der Welt teilen. Da es sich aber nur um eine Demo handelt, sollten Sie das nicht tun. Beginnen Sie damit, Ihre eigene Erweiterung mit dem, was Sie und der anderen Publisher-Dokumentation zu Firebase Extensions. und die Quelle der offiziellen, von Firebase geschriebenen Erweiterungen.
Wenn Sie bereit sind, Ihre Arbeit im Erweiterungs-Hub zu veröffentlichen, gehen Sie so vor: es:
- Wenn Sie Ihre erste Erweiterung veröffentlichen, als Erweiterungs-Publisher registrieren. Wenn Sie sich als Publisher von Erweiterungen registrieren, erstellen Sie eine Publisher-ID, anhand derer Nutzer Sie schnell als Autor Ihrer Erweiterungen identifizieren können.
Hosten Sie den Quellcode Ihrer Erweiterung an einem öffentlich überprüfbaren Ort. Wann? aus einer überprüfbaren Quelle stammt, kann Firebase Ihre Erweiterung direkt von diesem Standort aus. So können Sie sicherstellen, Wenn Sie die aktuell veröffentlichte Version Ihrer Erweiterung veröffentlichen, helfen Sie Nutzern, indem sie den Code untersuchen können, den sie in ihren Projekten installieren.
Derzeit bedeutet das, dass Sie Ihre Erweiterung in einem öffentlichen GitHub-Repository verfügbar machen müssen.
Lade deine Erweiterung über die
firebase ext:dev:upload
in den Erweiterungs-Hub hoch .Rufen Sie in der Firebase Console Ihr Publisher-Dashboard auf, suchen Sie die gerade hochgeladene Erweiterung und klicken Sie auf „Im Erweiterungs-Hub veröffentlichen“. Hier wird ein Überprüfung durch unsere Mitarbeiter. Dies kann einige Tage dauern. Wenn die Erweiterung genehmigt wird, wird sie im Erweiterungs-Hub veröffentlicht. Wenn der Antrag abgelehnt wird, erhalten Sie eine Nachricht mit einer Begründung. Sie können dann die gemeldeten Probleme beheben und den Antrag noch einmal zur Überprüfung einreichen.