Menambahkan hook pengguna ke ekstensi

Anda dapat memberi pengguna yang menginstal ekstensi Anda kemampuan untuk memasukkan logika kustom mereka sendiri ke dalam eksekusi ekstensi Anda. Ada dua cara untuk melakukannya:

  • Peristiwa Eventarc: untuk memberi pengguna cara bereaksi secara asinkron terhadap peristiwa, Anda dapat memublikasikan ke Eventarc. Pengguna dapat men-deploy fungsi pengendali peristiwa yang, misalnya, mengirim notifikasi setelah tugas yang berjalan lama selesai, atau mereka dapat menentukan fungsi pascapemrosesannya sendiri.

  • Hook sinkron: untuk memberi pengguna cara menambahkan logika pemblokiran ke ekstensi, Anda dapat menambahkan hook sinkron pada titik-titik yang telah ditentukan dalam pengoperasian ekstensi. Pada tahap ini, Anda akan menjalankan fungsi penyedia pengguna dan melanjutkan hanya setelah selesai. Tugas pra-pemrosesan sering kali termasuk dalam kategori ini.

Ekstensi dapat menggunakan salah satu atau kedua metode tersebut.

Peristiwa Eventarc

Untuk memublikasikan peristiwa dari ekstensi:

  1. Deklarasikan jenis peristiwa yang akan Anda publikasikan dalam file extension.yaml:

    events:
      - type: publisher-id.extension-name.version.event-name
        description: event-description
      - type: publisher-id.extension-name.version.another-event-name
        description: another-event-description
    

    ID type terdiri dari beberapa kolom yang dipisahkan titik. Kolom ID penayang, nama ekstensi, dan nama peristiwa diperlukan. Sebaiknya gunakan kolom versi. Pilih nama peristiwa yang unik dan deskriptif untuk setiap jenis peristiwa yang Anda publikasikan.

    Misalnya, ekstensi storage-resize-images mendeklarasikan jenis peristiwa tunggal:

    events:
      - type: firebase.extensions.storage-resize-images.v1.complete
        description: |
          Occurs when image resizing completes. The event will contain further
          details about specific formats and sizes.
    

    Pengguna akan dapat memilih untuk berlangganan peristiwa yang mana saat menginstal ekstensi tersebut.

  2. Dalam fungsi ekstensi Anda, impor Eventarc API dari Admin SDK dan lakukan inisialisasi saluran peristiwa menggunakan setelan penginstalan pengguna. Setelan ini diekspos menggunakan variabel lingkungan berikut:

    • EVENTARC_CHANNEL: nama saluran Eventarc yang sepenuhnya memenuhi syarat tempat pengguna memilih untuk memublikasikan peristiwa.
    • EXT_SELECTED_EVENTS: daftar yang dipisahkan koma dari jenis-jenis peristiwa yang dipilih pengguna untuk dipublikasikan. Saat Anda menginisialisasi saluran dengan nilai ini, Admin SDK otomatis memfilter peristiwa yang tidak dipilih pengguna.
    • EVENTARC_CLOUD_EVENT_SOURCE: ID sumber Peristiwa Cloud. Admin SDK otomatis meneruskan nilai ini di kolom source peristiwa-peristiwa yang dipublikasikan. Biasanya, Anda tidak perlu menggunakan variabel ini secara eksplisit.

    Jika peristiwa tidak diaktifkan saat penginstalan, variabel ini tidak akan ditentukan. Anda dapat menggunakan fakta ini untuk menginisialisasi saluran peristiwa hanya saat peristiwa diaktifkan:

    import * as admin from "firebase-admin";
    import {getEventarc} from 'firebase-admin/eventarc';
    
    admin.initializeApp();
    
    // 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,
      });
    
  3. Publikasikan peristiwa ke saluran pada titik-titik dalam ekstensi yang ingin Anda ekspos kepada pengguna. Contoh:

    // If events are enabled, publish a `complete` event to the configured
    // channel.
    eventChannel && eventChannel.publish({
        type: 'firebase.extensions.storage-resize-images.v1.complete',
        subject: filename,  // the name of the original file
        data: {
          // ...
        }
    });
    
  4. Dokumentasikan peristiwa yang Anda publikasikan, dalam file PREINSTALL atau POSTINSTALL.

    Untuk setiap peristiwa, dokumentasikan hal berikut:

    • Tujuan yang dimaksudkan
    • Titik di logika ekstensi yang dijalankan
    • Data output yang dicakup
    • Kondisi untuk eksekusinya

    Selain itu, peringatkan pengguna untuk tidak melakukan tindakan apa pun dalam pengendali peristiwa yang mungkin memicu ekstensi yang sama, yang akan menghasilkan loop tak terbatas.

Saat Anda memublikasikan peristiwa dari ekstensi, pengguna dapat men-deploy pengendali peristiwa untuk merespons dengan logika kustom.

Misalnya, contoh berikut menghapus gambar asli setelah ukurannya diubah. Perlu diperhatikan bahwa pengendali contoh ini menggunakan properti subject peristiwa, yang dalam hal ini adalah nama file asli dari gambar.

exports.onimageresized = onCustomEventPublished(
    "firebase.extensions.storage-resize-images.v1.complete",
    (event) => {
      logger.info("Received image resize completed event", event);
      // For example, delete the original.
      return admin.storage()
          .bucket("my-project.appspot.com")
          .file(event.subject)
          .delete();
    });

Lihat Pemicu peristiwa kustom untuk mengetahui informasi selengkapnya.

Contoh

Ekstensi Resize Images resmi menyediakan hook asinkron dengan memublikasikan ke Eventarc setelah mengubah ukuran gambar.

Hook sinkron

Jika Anda ingin memberi hook kepada pengguna yang harus berhasil diselesaikan agar salah satu fungsi ekstensi Anda dapat beroperasi, gunakan hook sinkron.

Hook sinkron memanggil Cloud Function callable HTTPS yang ditentukan pengguna dan menunggu penyelesaian (mungkin dengan nilai yang ditampilkan) sebelum melanjutkan. Error dalam fungsi yang diberikan pengguna menghasilkan error dalam fungsi ekstensi.

Untuk mengekspos hook sinkron:

  1. Tambahkan parameter ke ekstensi Anda yang memungkinkan pengguna dapat mengonfigurasi ekstensi dengan URL ke Cloud Function kustom mereka. Contoh:

    - param: PREPROCESSING_FUNCTION
      label: Pre-processing function URL
      description: >
        An HTTPS callable function that will be called to transform the input data
        before it is processed by this function.
      type: string
      example: https://us-west1-my-project-id.cloudfunctions.net/preprocessData
      required: false
    
  2. Pada titik di ekstensi tempat Anda ingin mengekspos hook, panggil fungsi menggunakan URL-nya. Contoh:

    const functions = require('firebase-functions');
    const fetch = require('node-fetch');
    
    const preprocessFunctionURL = process.env.PREPROCESSING_FUNCTION;
    
    exports.yourFunctionName = functions.firestore.document("collection/{doc_id}")
        .onWrite((change, context) => {
          // PREPROCESSING_FUNCTION hook begins here.
          // If a preprocessing function is defined, call it before continuing.
          if (preprocessFunctionURL) {
            try {
              await fetch(preprocessFunctionURL); // Could also be a POST request if you want to send data.
            } catch (e) {
              // Preprocessing failure causes the function to fail.
              functions.logger.error("Preprocessor error:", e);
              return;
            }
          }
          // End of PREPROCESSING_FUNCTION hook.
    
          // Main function logic follows.
          // ...
        });
    
  3. Dokumentasikan hook yang Anda sediakan dalam file PREINSTALL atau POSTINSTALL.

    Untuk setiap hook, dokumentasikan hal berikut:

    • Tujuan yang dimaksudkan
    • Titik di logika ekstensi yang dijalankan
    • Input dan output yang diharapkan
    • Kondisi (atau opsi) untuk eksekusinya

    Selain itu, peringatkan pengguna untuk tidak melakukan tindakan apa pun dalam fungsi hook yang mungkin memicu ekstensi yang sama, yang akan menghasilkan loop tak terbatas.

Contoh

Ekstensi Algolia Search menyediakan hook sinkron untuk memanggil fungsi transformasi yang disediakan pengguna sebelum menulis ke Algolia.