Rozpocznij tworzenie rozszerzenia

Na tej stronie dowiesz się, jak utworzyć prostą Firebase Rozszerzenie, które możesz zainstalować w swoich projektach lub udostępnić innym. Ten prostego przykładowego rozszerzenia Firebase będzie śledzić w Bazie danych czasu rzeczywistego i konwertuj je na wielkie litery.

1. Konfigurowanie środowiska i inicjowanie projektu

Zanim zaczniesz tworzyć rozszerzenie, musisz skonfigurować kompilację za pomocą wymaganych narzędzi.

  1. Zainstaluj Node.js w wersji 16 lub nowszej. Jednym ze sposobów zainstalowania węzła jest użycie NVM (lub nvm-windows).

  2. Zainstaluj lub zaktualizuj interfejs wiersza poleceń Firebase do najnowszej wersji. Do zainstaluj lub zaktualizuj za pomocą npm, uruchom to polecenie:

    npm install -g firebase-tools
    

Teraz zainicjuj nowy projekt rozszerzenia za pomocą interfejsu wiersza poleceń Firebase:

  1. Utwórz katalog dla rozszerzenia i w nim cd:

    mkdir rtdb-uppercase-messages && cd rtdb-uppercase-messages
    
  2. Uruchom polecenie ext:dev:init w interfejsie wiersza poleceń Firebase:

    firebase ext:dev:init
    

    Gdy pojawi się prośba, jako język funkcji wybierz JavaScript (ale zwróć uwagę że możesz też używać TypeScriptu podczas tworzenia własnego rozszerzenia), gdy pojawi się prośba o zainstalowanie zależności, odpowiedz „Tak”. (Zaakceptuj domyślne ustawienia dla inne opcje). To polecenie spowoduje skonfigurowanie szkieletowej bazy kodu dla interfejsu nowego rozszerzenia, z którego możesz zacząć tworzyć swoje rozszerzenie.

2. Wypróbuj przykładowe rozszerzenie za pomocą emulatora

Gdy interfejs wiersza poleceń Firebase zainicjował nowy katalog rozszerzeń, utworzył plik prostą przykładową funkcję i katalog integration-tests, który zawiera niezbędne do uruchomienia rozszerzenia za pomocą pakietu emulatora Firebase.

Spróbuj uruchomić przykładowe rozszerzenie w emulatorze:

  1. Przejdź do katalogu integration-tests:

    cd functions/integration-tests
    
  2. Uruchom emulator przy użyciu projektu demonstracyjnego:

    firebase emulators:start --project=demo-test
    

    Emulator wczytuje rozszerzenie do wstępnie zdefiniowanego „fikcyjnego”. projekt (demo-test). Rozszerzenie składa się z jednego wywołania HTTP funkcja, greetTheWorld, która zwraca „hello world” wiadomość, gdy dostęp.

  3. Gdy emulator będzie nadal uruchomiony, użyj polecenia greetTheWorld rozszerzenia otwierając adres URL wydrukowany w momencie uruchomienia.

    W przeglądarce wyświetli się komunikat „Witaj świecie z powitania”.

  4. Kod źródłowy tej funkcji znajduje się w sekcji functions rozszerzenia katalogu. Otwórz źródło w wybranym edytorze lub IDE:

    functions/index.js

    const functions = require("firebase-functions");
    
    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);
    });
    
  5. Gdy emulator jest uruchomiony, automatycznie wczytuje ponownie wszystkie zmiany w kodzie funkcji. Spróbuj wprowadzić niewielką zmianę w Funkcja greetTheWorld:

    functions/index.js

    const greeting = `${consumerProvidedGreeting} everyone, from ${instanceId}`;
    

    Zapisz zmiany. Emulator ponownie wczyta kod, a teraz, gdy już otwórz URL funkcji, zobaczysz zaktualizowane powitanie.

3. Dodaj podstawowe informacje do plikuextension.yaml

Po skonfigurowaniu środowiska programistycznego i uruchomieniu możesz utworzyć własne rozszerzenie.

Na początek zmodyfikuj wstępnie zdefiniowane metadane rozszerzenia, by odzwierciedlały które chcesz utworzyć zamiast greet-the-world. Te metadane są zapisane w pliku extension.yaml.

  1. Otwórz w edytorze extension.yaml i zastąp całą zawartość pliku z następującymi danymi:

    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
    

    Zwróć uwagę na konwencję nazewnictwa używaną w polu name: oficjalna usługa Firebase. rozszerzenia mają nazwy z prefiksem wskazującym główną usługę Firebase oraz jego opis, co robi. Stosuj tę samą konwencję we własnych rozszerzeniach.

  2. Zmieniła się nazwa rozszerzenia, więc musisz też zaktualizować konfigurację emulatora z nową nazwą:

    1. W functions/integration-tests/firebase.json zmień greet-the-world do: rtdb-uppercase-messages.
    2. Zmień nazwę functions/integration-tests/extensions/greet-the-world.env na functions/integration-tests/extensions/rtdb-uppercase-messages.env

Pozostało trochę rozszerzenia greet-the-world w z kodem rozszerzenia, ale na razie zostaw je. Zaktualizujesz je w ciągu kilku następnych sekcji.

4. Napisz funkcję w Cloud Functions i zadeklaruj ją jako zasób rozszerzenia

Teraz możesz zacząć pisać kod. W tym kroku napiszesz platformę Cloud Funkcja, która wykonuje podstawowe zadanie rozszerzenia. aby monitorować wiadomości w Bazie danych czasu rzeczywistego i konwertować je na wielkie litery.

  1. Otwórz źródło funkcji rozszerzenia (w pliku functions) w wybranym edytorze lub IDE. Zamień o następującej zawartości:

    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);
    });
    

    Stara funkcja, którą zastąpiono, była funkcją wyzwalaną przez HTTP, była uruchamiana po uzyskaniu dostępu do punktu końcowego HTTP. Nowa funkcja jest wywoływana przez zdarzeń bazy danych w czasie rzeczywistym: monitoruje nowe elementy na określonej ścieżce a po jego wykryciu zapisuje wartość w wersji pisanej wielkimi literami do bazy danych.

    Przy okazji – w nowym pliku jest używana składnia modułu ECMAScript (import i export) zamiast CommonJS (require). Aby używać modułów ES w Node.js, określ "type": "module" w functions/package.json:

    {
      "name": "rtdb-uppercase-messages",
      "main": "index.js",
      "type": "module",
      …
    }
    
  2. Każda funkcja rozszerzenia musi być zadeklarowana w extension.yaml . Przykładowe rozszerzenie zadeklarowało greetTheWorld jako jedyne rozszerzenie. funkcja w Cloud Functions; po zastąpieniu go elementem makeuppercase, musi zaktualizować swoją deklarację.

    Otwórz extension.yaml i dodaj pole resources:

    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"
    
  3. Jako aktywatora Twoje rozszerzenie używa teraz Bazy danych czasu rzeczywistego, więc musisz żeby zaktualizować konfigurację emulatora i uruchomić emulator RTDB Emulator Cloud Functions:

    1. Jeśli emulator nadal działa, zatrzymaj go, naciskając Ctrl+C.

    2. W katalogu functions/integration-tests uruchom następujące polecenie polecenie:

      firebase init emulators
      

      Gdy pojawi się prośba, pomiń konfigurowanie domyślnego projektu i wybierz Funkcje. oraz emulatory baz danych. Zaakceptuj porty domyślne i zezwól na konfigurację narzędzie do pobierania potrzebnych plików.

    3. Ponownie uruchom emulator:

      firebase emulators:start --project=demo-test
      
  4. Wypróbuj zaktualizowane rozszerzenie:

    1. Otwórz interfejs emulatora bazy danych, klikając podany przez niego link. od chwili jego rozpoczęcia.

    2. Edytuj węzeł główny bazy danych:

      • Pole: messages
      • Typ: json
      • Wartość: {"11": {"original": "recipe"}}

      Jeśli wszystko jest skonfigurowane prawidłowo, po zapisaniu zmian w bazie danych funkcja makeuppercase rozszerzenia powinna aktywować się i dodać element podrzędny rekord do wiadomości 11 z treścią "upper": "RECIPE". Sprawdź w dziennikach i na kartach bazy danych interfejsu emulatora, oczekiwanych wyników.

    3. Spróbuj dodać więcej elementów podrzędnych do węzła messages ({"original":"any text"}). Za każdym razem, gdy dodajesz nowy rekord, moduł rozszerzenie powinno dodać pole uppercase zawierające wielkie litery zawartość pola original.

Masz teraz pełne, choć proste rozszerzenie, które działa na bazie baz danych czasu rzeczywistego. instancji. W kolejnych sekcjach doprecyzujesz to rozszerzenie, dodając kilka funkcje dodatkowe. Następnie przygotujesz rozszerzenie do rozpowszechniania wśród: innych. Dowiedz się też, jak opublikować rozszerzenie w Centrum rozszerzeń.

5. Deklarowanie interfejsów API i ról

Firebase przyznaje każdemu wystąpieniu zainstalowanego rozszerzenia ograniczony dostęp do projektu i jego danych za pomocą konta usługi dla poszczególnych instancji. Każde konto ma minimalny zestaw uprawnień wymaganych do działania. Z tego powodu musisz jawnie zadeklaruj wszelkie role uprawnień wymagane przez rozszerzenie; gdy użytkownicy instalują aplikację rozszerzenie, Firebase utworzy konto usługi z tymi rolami korzysta z niego do uruchamiania rozszerzenia.

Nie musisz deklarować ról, aby aktywować zdarzenia usługi, ale to robisz musisz zadeklarować rolę, aby móc wejść z nią w interakcję. Ponieważ funkcja, dodanych w ostatnim kroku podczas zapisywania do Bazy danych czasu rzeczywistego, musisz dodać tę deklarację dla extension.yaml:

roles:
  - role: firebasedatabase.admin
    reason: Allows the extension to write to RTDB.

Podobnie interfejsy API Google, z których korzysta rozszerzenie, deklarujesz w apis. . Podczas instalowania rozszerzenia użytkownicy są pytani, czy chcą aby automatycznie włączyć te interfejsy API w swoim projekcie. Jest to zwykle tylko nie jest konieczne w przypadku interfejsów API Google spoza Firebase i nie jest wymagany w tym przewodniku.

6. Zdefiniuj parametry konfigurowane przez użytkownika

Funkcja utworzona w ostatnich 2 krokach obserwowała konkretną lokalizację bazy danych czasu rzeczywistego o wiadomościach przychodzących. Czasami obejrzenie konkretnej lokalizacji wybrane przez Ciebie, np. gdy rozszerzenie działa na strukturze bazy danych, używaj go wyłącznie w rozszerzeniu. Jednak najczęściej umożliwić konfigurowanie tych wartości użytkownikom, którzy zainstalują Twoje rozszerzenie w projektach AI. Dzięki temu użytkownicy będą mogli korzystać z Twojego rozszerzenia do pracy ze dotychczasowej konfiguracji bazy danych.

Zezwól użytkownikowi na konfigurowanie ścieżki obserwowanej przez rozszerzenie dla nowych wiadomości:

  1. W pliku extension.yaml dodaj sekcję params:

    - 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
    

    Definiuje nowy parametr w postaci ciągu znaków, o którego ustawienie użytkownicy będą proszeni instalują Twoje rozszerzenie.

  2. Będąc w pliku extension.yaml, wróć do makeuppercase i zmień pole resource na takie:

    resource: projects/_/instances/${DATABASE_INSTANCE}/refs/${param:MESSAGE_PATH}
    

    Token ${param:MESSAGE_PATH} jest odniesieniem do parametru, który właśnie zdefiniowano jego definicję. Po uruchomieniu rozszerzenia ten token zostanie zastąpiony przez dowolny ustawioną przez użytkownika dla tego parametru, co spowoduje, że Funkcja makeuppercase będzie nasłuchiwać ścieżki podanej przez użytkownika. Dostępne opcje użyj tej składni, aby odwołać się do dowolnego parametru zdefiniowanego przez użytkownika w dowolnym miejscu extension.yaml (oraz w aplikacji POSTINSTALL.md – więcej o tym później).

  3. Z kodu funkcji możesz też uzyskać dostęp do parametrów zdefiniowanych przez użytkownika.

    W funkcji zapisanej w ostatniej sekcji zakodowano na stałe ścieżkę do i monitorować zmiany. Zmień definicję aktywatora, aby odwołać się do wartość definiowaną przez użytkownika:

    functions/index.js

    export const makeuppercase = database.ref(process.env.MESSAGE_PATH).onCreate
    

    Pamiętaj, że w Rozszerzeniach w Firebase ta zmiana dotyczy tylko dokumentacja: gdy funkcja w Cloud Functions zostanie wdrożona jako część rozszerzenia, korzysta z definicji aktywatora z pliku extension.yaml i ignoruje wartość określoną w definicji funkcji. Mimo to warto aby udokumentować w kodzie, skąd pochodzi ta wartość.

  4. Wprowadzanie zmiany w kodzie, w przypadku braku środowiska wykonawczego, może być rozczarowujące. ale ważną lekcją jest to, że masz dostęp do wszystkich zdefiniowany przez użytkownika w kodzie funkcji i użyj go jako wartości zwykłej w logice funkcji. W ramach uznania za tę możliwość dodaj następujący log: aby udowodnić, że rzeczywiście korzystasz z wartości, którą definiowany przez użytkownika:

    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.
        ...
    
  5. Zwykle użytkownicy są proszeni o podanie wartości parametrów, gdy zainstalować rozszerzenie. Gdy używasz emulatora do testowania i programowania, Instalację można pominąć, więc zamiast tego podasz wartości dla parametrów zdefiniowanych przez użytkownika za pomocą pliku env.

    Otwórz aplikację functions/integration-tests/extensions/rtdb-uppercase-messages.env i zastąp definicję GREETING taką:

    MESSAGE_PATH=/msgs/{pushId}/original
    

    Zwróć uwagę, że powyższa ścieżka różni się od ścieżki domyślnej i zdefiniowaną wcześniej ścieżkę, to jest tylko dowód dla siebie, gdy spróbujesz zaktualizowane rozszerzenie informujące, że definicja zaczyna obowiązywać.

  6. Teraz uruchom emulator ponownie i jeszcze raz otwórz jego interfejs.

    Zmodyfikuj węzeł główny bazy danych, stosując ścieżkę określoną powyżej:

    • Pole: msgs
    • Typ: json
    • Wartość: {"11": {"original": "recipe"}}

    Po zapisaniu zmian w bazie danych makeuppercase rozszerzenia powinna się aktywować tak samo jak wcześniej, ale teraz powinna także wyświetlić zdefiniowany przez użytkownika.

7. Udostępnij punkty zaczepienia zdarzeń na potrzeby logiki zdefiniowanej przez użytkownika

Jako autor rozszerzenia wiesz już, jak wyzwalać działanie usługi Firebase logika udostępniona przez rozszerzenie: tworzenie nowych rekordów w Bazie danych czasu rzeczywistego wyzwala funkcję makeuppercase. Rozszerzenie może mieć analogiczny z użytkownikami, którzy zainstalowali Twoje rozszerzenie: rozszerzenie może logiki aktywującej zdefiniowanej przez użytkownika.

Rozszerzenie może udostępniać synchroniczne elementy zaczepienia, asynchroniczne lub oba te elementy. Synchroniczne punkty zaczepienia umożliwiają użytkownikom wykonywanie zadań, które blokują ukończenie jedną z funkcji rozszerzenia. Dzięki temu użytkownicy będą mogli na przykład To sposób na niestandardowe wstępne przetwarzanie, zanim rozszerzenie zacznie działać.

W tym przewodniku dodasz do rozszerzenia asynchroniczny hook, który umożliwiać użytkownikom definiowanie własnych etapów przetwarzania, które mają być uruchamiane po rozszerzeniu zapisuje komunikat wielkimi literami w bazie danych czasu rzeczywistego. Asynchroniczne elementy zaczepienia używają Eventarc do aktywowania funkcji zdefiniowanych przez użytkownika. deklarują typy zdarzeń, które generują; gdy użytkownicy instalują rozszerzenie, wybierają typy zdarzeń, co może Cię zainteresować. Jeśli wybiorą co najmniej jedno zdarzenie, Firebase udostępni Kanał Eventarc rozszerzenia w ramach procesu instalacji. Użytkownicy mogą wdrażać własne funkcje w Cloud Functions, które nasłuchują w tym kanale, uruchamiają się, gdy rozszerzenie opublikuje nowe zdarzenia.

Aby dodać asynchroniczny punkt zaczepienia, wykonaj te czynności:

  1. W pliku extension.yaml dodaj następującą sekcję, która deklaruje parametr jeden typ zdarzenia emitowanego przez rozszerzenie:

    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.
    

    Typy zdarzeń muszą być uniwersalnie unikalne. aby zapewnić unikalność, zawsze nazywaj użyj takiego formatu: <publisher-id>.<extension-id>.<version>.<description> (Nie masz identyfikatora wydawcy, więc na razie używaj tylko identyfikatora test-publisher).

  2. Na końcu funkcji makeuppercase dodaj kod, który publikuje o deklarowanym właśnie typie:

    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,
        },
      });
    

    Ten przykładowy kod wykorzystuje fakt, że EVENTARC_CHANNEL zmienna środowiskowa jest definiowana tylko wtedy, gdy użytkownik włączył co najmniej jeden typ zdarzenia. Jeśli EVENTARC_CHANNEL nie jest zdefiniowany, kod nie będzie próbować do publikacji wydarzeń.

    Do zdarzenia Eventarc możesz dołączyć dodatkowe informacje. W przykładzie powyżej zdarzenie ma pole subject, które zawiera odwołanie do funkcji nowo utworzoną wartość oraz ładunek data zawierający pierwotne wartości i wiadomości pisane wielkimi literami. Funkcje zdefiniowane przez użytkownika, które aktywują zdarzenie, mogą korzystania z tych informacji.

  3. Normalnie środowisko EVENTARC_CHANNEL i EXT_SELECTED_EVENTS zmienne są definiowane na podstawie opcji wybranych przez użytkownika instalacji. Aby przeprowadzić testy za pomocą emulatora, ręcznie zdefiniuj te zmienne w pliku rtdb-uppercase-messages.env:

    EVENTARC_CHANNEL=locations/us-central1/channels/firebase
    EXT_SELECTED_EVENTS=test-publisher.rtdb-uppercase-messages.v1.complete
    

Na tym etapie zostały wykonane czynności niezbędne, aby dodać zdarzenie asynchroniczne. zaczepienie rozszerzenia.

Aby wypróbować tę nową funkcję, którą właśnie wdrożyliśmy, przez kilka kolejnych W tym celu należy przyjąć rolę użytkownika, który instaluje rozszerzenie:

  1. Zainicjuj nową aplikację Firebase z katalogu functions/integration-tests projekt:

    firebase init functions
    

    Gdy pojawi się prośba, odrzuć prośbę o skonfigurowanie projektu domyślnego i wybierz JavaScript jako języka Cloud Functions i zainstaluj wymagane zależności. Ten projekt reprezentuje projekt użytkownika, w którym jest zainstalowane Twoje rozszerzenie.

  2. Edytuj integration-tests/functions/index.js i wklej ten kod:

    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}!!!`);
      }
    );
    

    To jest przykład funkcji przetwarzania końcowego, którą może utworzyć użytkownik. W tym przypadku, funkcja nasłuchuje, że rozszerzenie opublikuje zdarzenie complete, a po uruchomieniu dodaje trzy wykrzykniki do nowo pisanych .

  3. Ponownie uruchom emulator. Emulator wczyta funkcje rozszerzenia jako a następnie funkcję przetwarzania końcowego, zdefiniowano jego definicję.

  4. Otwórz interfejs emulatora bazy danych i zmodyfikuj węzeł główny bazy danych, używając ścieżkę zdefiniowaną powyżej:

    • Pole:msgs
    • Typ: json
    • Wartość: {"11": {"original": "recipe"}}

    Po zapisaniu zmian w bazie danych makeuppercase rozszerzenia i funkcja extraemphasis użytkownika powinna zostać wywołana po kolei, w wyniku czego pole upper otrzymało wartość RECIPE!!!.

8. Dodaj moduły obsługi zdarzeń cyklu życia

Napisane do tej pory rozszerzenie przetwarza wiadomości od razu po ich utworzeniu. Ale A co jeśli użytkownicy mają już bazę danych wiadomości podczas instalowania rozszerzenie? Rozszerzenia w Firebase mają funkcję o nazwie punkty zaczepienia zdarzeń cyklu życia, możesz używać do uruchamiania działań po zainstalowaniu, aktualizacji lub aktualizacji rozszerzenia ponowna konfiguracja. W tej sekcji użyjesz punktów zaczepienia zdarzeń cyklu życia, aby uzupełnić w ramach projektu baza danych wiadomości pisanych wielkimi literami, gdy użytkownik instaluje rozszerzenie.

Rozszerzenia w Firebase używają Cloud Tasks do uruchamiania modułów obsługi zdarzeń cyklu życia. Ty definiować moduły obsługi zdarzeń za pomocą Cloud Functions; za każdym razem, gdy wystąpienie dochodzi do jednego z obsługiwanych zdarzeń cyklu życia, jeśli zdefiniujesz spowoduje dodanie go do kolejki Cloud Tasks. Cloud Tasks . Gdy działa moduł obsługi zdarzeń cyklu życia, konsola Firebase poinformuje użytkownika, że instancja rozszerzenia ma Przetwarzanie w toku. To funkcja Twojego modułu obsługi służy do zgłaszania bieżących stan reklamy i ukończenie zadania.

Aby dodać moduł obsługi zdarzeń cyklu życia, który uzupełnia istniejące wiadomości, wykonaj :

  1. Zdefiniuj nową funkcję w Cloud Functions, która będzie aktywowana przez zdarzenia w kolejce zadań:

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

    Zwróć uwagę, że funkcja przetwarza tylko kilka rekordów przed dodaniem swojej samej wartości do kolejki zadań. To strategia często wykorzystywana zadania przetwarzania, których nie można wykonać po upływie limitu czasu oczekiwania w Google Cloud funkcji. Ponieważ nie można przewidzieć, ile wiadomości może już przesłać użytkownik użytkowników w swojej bazie danych po zainstalowaniu rozszerzenia, ta strategia i były dopasowane.

  2. W pliku extension.yaml zadeklaruj funkcję uzupełniania jako rozszerzenie. zasób z właściwością taskQueueTrigger:

    resources:
      - name: makeuppercase
        ...
      - name: backfilldata
        type: firebaseextensions.v1beta.function
        description: >-
          Backfill existing messages with uppercase versions
        properties:
          runtime: "nodejs18"
          taskQueueTrigger: {}
    

    Następnie zadeklaruj funkcję jako moduł obsługi cyklu życia onInstall zdarzenie:

    lifecycleEvents:
      onInstall:
        function: backfilldata
        processingMessage: Uppercasing existing messages
    
  3. Chociaż warto mieć możliwość uzupełniania istniejących wiadomości, będą bez niego działać. W takich sytuacjach biegaj moduł obsługi zdarzeń cyklu życia jest opcjonalny.

    Aby to zrobić, dodaj do extension.yaml nowy parametr:

    - 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
    

    Następnie na początku funkcji uzupełniania sprawdź wartość parametru DO_BACKFILL i wyjść wcześniej, jeśli nie jest ustawiony:

    functions/index.js

    if (!process.env.DO_BACKFILL) {
      return getExtensions()
        .runtime()
        .setProcessingState("PROCESSING_COMPLETE", "Backfill skipped.");
    }
    

Po wprowadzeniu powyższych zmian rozszerzenie będzie teraz konwertować istniejące wiadomości na na wielkie litery.

Do opracowania rozszerzenia służyło Ci do tej pory emulator rozszerzenia testować bieżące zmiany. Emulator rozszerzenia pomija instalację. więc aby przetestować moduł obsługi zdarzeń onInstall, musisz zainstalować w prawdziwym projekcie. To dobrze, bo oprócz dodania tej funkcji automatycznego uzupełniania, rozszerzenie samouczka to już cały kod.

9. Wdróż w prawdziwym projekcie Firebase

Chociaż emulator rozszerzeń to świetne narzędzie do szybkiej iteracji w trakcie programowania, warto czasem wypróbować je w praktyce. w projektach AI.

Aby to zrobić, najpierw skonfiguruj nowy projekt z włączonymi usługami:

  1. W konsoli Firebase dodaj nową w projektach AI.
  2. Przenoszenie projektu na wyższy na abonament Blaze. Cloud Functions dla Firebase wymaga projekt ma konto rozliczeniowe, więc potrzebujesz go także do: zainstalować rozszerzenie.
  3. W nowym projekcie włącz Bazę danych czasu rzeczywistego.
  4. Chcesz sprawdzić możliwość uzupełniania danych przez rozszerzenie w zaimportuj kilka przykładowych danych do instancji bazy danych w czasie rzeczywistym:
    1. Pobierz wyjściowe dane RTDB.
    2. Na stronie Baza danych czasu rzeczywistego w konsoli Firebase kliknij (więcej) > Importuj z pliku JSON i wybierz pobrany przed chwilą plik.
  5. Aby włączyć funkcję uzupełniania korzystającą z metody orderByChild, skonfiguruj bazy danych do indeksowania wiadomości na podstawie wartości upper:

    {
      "rules": {
        ".read": false,
        ".write": false,
        "messages": {
          ".indexOn": "upper"
        }
      }
    }
    

Teraz zainstaluj rozszerzenie ze źródła lokalnego w nowym projekcie:

  1. Utwórz nowy katalog dla projektu Firebase:

    mkdir ~/extensions-live-test && cd ~/extensions-live-test
    
  2. Zainicjuj projekt Firebase w katalogu roboczym:

    firebase init database
    

    Gdy pojawi się odpowiedni komunikat, wybierz utworzony przed chwilą projekt.

  3. Zainstaluj rozszerzenie w lokalnym projekcie Firebase:

    firebase ext:install /path/to/rtdb-uppercase-messages
    

    Tutaj widać, jak użytkownicy korzystają z za pomocą narzędzia wiersza poleceń Firebase. Wybierz „tak” gdy narzędzie konfiguracji pyta, czy chcesz uzupełnić istniejącą bazę danych.

    Gdy wybierzesz opcje konfiguracji, interfejs wiersza poleceń Firebase zapisze konfigurację w katalogu extensions i zanotuj źródło rozszerzenia lokalizację w pliku firebase.json. Te dwa rekordy są łącznie za pomocą pliku manifestu rozszerzeń. W pliku manifestu użytkownicy mogą zapisać swoje konfigurację rozszerzeń i wdrażać je w różnych projektach.

  4. Wdróż konfigurację rozszerzenia w projekcie wersji opublikowanej:

    firebase deploy --only extensions
    

Jeśli wszystko pójdzie dobrze, interfejs wiersza poleceń Firebase powinien przesłać rozszerzenie do projektu. i ją zainstaluj. Po zakończeniu instalacji zostanie uruchomione zadanie uzupełniania, a za za kilka minut, Twoja baza danych zostanie zaktualizowana o wiadomości pisane wielkimi literami. Dodaj więcej do bazy danych wiadomości i upewnij się, że rozszerzenie też działa. na nowe wiadomości.

10. Tworzenie dokumentacji

Zanim udostępnisz użytkownikom swoje rozszerzenie, upewnij się, dokumentacji, które umożliwią ich skuteczne zaliczenie.

Po zainicjowaniu projektu rozszerzenia interfejs wiersza poleceń Firebase utworzył wycinek wersji minimalnej wymaganej dokumentacji. Zaktualizuj te pliki, aby były dokładne które odzwierciedlają utworzone rozszerzenie.

file.yaml

Aktualizujesz już ten plik w miarę tworzenia tego rozszerzenia, więc nie musisz teraz wprowadzać żadnych zmian.

Nie zapominaj jednak o tym, jak ważna jest dokumentacja . Oprócz najważniejszych informacji identyfikujących rozszerzenie, takich jak nazwa, opis, autor, lokalizacja oficjalnego repozytorium – extension.yaml zawiera dokumentację dla użytkownika dla każdego zasobu, który można skonfigurować przez użytkownika . Użytkownicy zobaczą te informacje w konsoli Firebase, Centrum rozszerzeń i interfejs wiersza poleceń Firebase.

PREINSTALL.md

W tym pliku podaj informacje, których użytkownik potrzebuje przed zainstalowaniem rozszerzenia: krótko opisz, do czego służy rozszerzenie, wyjaśnij wszelkie wymagania wstępne, i poinformować użytkowników o wpływie instalacji . Jeśli masz witrynę z dodatkowymi informacjami, jest to również do linków.

Tekst tego pliku jest wyświetlany użytkownikowi w Centrum rozszerzeń oraz przez firebase ext:info.

Oto przykład pliku PREINSTALL:

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

Ten plik zawiera informacje przydatne dla użytkowników, którzy zainstalowane rozszerzenie: np. dalsze kroki konfiguracji, przykładowy i tak dalej.

Zawartość pliku POSTINSTALL.md jest wyświetlana w konsoli Firebase po jest skonfigurowane i zainstalowane. Parametry użytkownika możesz odwoływać się w tym miejscu . Zostaną one zastąpione skonfigurowanymi wartościami.

Oto przykładowy plik używany po zainstalowaniu rozszerzenia samouczka:

### 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

Musisz też udokumentować zmiany, które wprowadzasz między wersjami rozszerzenia. w pliku CHANGELOG.md.

To rozszerzenie nie zostało wcześniej opublikowane, więc historia zmian tylko jeden wpis:

## Version 0.0.1

Initial release of the _Convert messages to upper case_ extension.

README.md

Większość rozszerzeń udostępnia też plik Readme przeznaczony dla użytkowników do repozytorium rozszerzenia. możesz napisać ten plik ręcznie lub wygenerować za pomocą polecenia.

Na potrzeby tego przewodnika pomiń pisanie pliku Readme.

Dodatkowa dokumentacja

Dokumentacja omówiona powyżej to minimalny zestaw dokumentów, jaki należy dla użytkowników. Wiele rozszerzeń wymaga od użytkowników bardziej szczegółowej dokumentacji z nich korzystać. W takim przypadku wpisz dodatkowe dokumentację i przechowywanie w miejscu, do którego możesz ją skierować.

W tym przewodniku pomiń pisanie bardziej szczegółowej dokumentacji.

11. Opublikuj w Centrum rozszerzeń

Teraz, gdy kod rozszerzenia jest kompletny i udokumentowany, możesz je udostępnić ze światem w Centrum rozszerzeń. To tylko samouczek, więc nie mogą to robić. Zacznij tworzyć własne rozszerzenie na podstawie tego, oraz w pozostałej dokumentacji dla wydawców Rozszerzeń w Firebase. oraz sprawdzając źródło oficjalnych rozszerzeń napisanych przez Firebase.

Aby opublikować swoje dzieło w Centrum rozszerzeń, wykonaj te czynności: :

  1. Jeśli publikujesz pierwsze rozszerzenie, zarejestruj się jako wydawca rozszerzeń. Kiedy rejestrujesz się jako wydawca rozszerzeń, tworzysz identyfikator wydawcy, użytkownicy szybko rozpoznają Cię jako autora rozszerzeń.
  2. Przechowuj kod źródłowy rozszerzenia w miejscu, które można publicznie zweryfikować. Kiedy że kod pochodzi z weryfikowanego źródła, Firebase może opublikować bezpośrednio z tej lokalizacji. Dzięki temu będziesz mieć pewność, że opublikowanie obecnie opublikowanej wersji Twojego rozszerzenia i ułatwi użytkownikom umożliwiając im sprawdzenie kodu instalowanego w swoich projektach.

    Obecnie oznacza to udostępnienie rozszerzenia w publicznym serwisie GitHub. z repozytorium.

  3. Prześlij rozszerzenie do Centrum rozszerzeń za pomocą: firebase ext:dev:upload .

  4. Otwórz panel wydawcy w konsoli Firebase i znajdź rozszerzenie. właśnie przesłać i kliknąć „Opublikuj w Centrum rozszerzeń”. Spowoduje to przesłanie prośby o ale może to potrwać kilka dni. Po zatwierdzeniu rozszerzenie zostanie opublikowane w Centrum rozszerzeń. Jeśli ją odrzucimy, komunikat z wyjaśnieniem przyczyny; możesz rozwiązać zgłaszane problemy ponownie do sprawdzenia.