Ikuti sorotan dari Firebase di Google I/O 2023. Pelajari lebih lanjut

Tangani peristiwa siklus proses ekstensi Anda

Ekstensi Anda dapat menyertakan fungsi Cloud Tasks yang terpicu saat instance ekstensi melewati salah satu peristiwa siklus proses berikut:

  • Instance dari ekstensi diinstal
  • Contoh ekstensi diperbarui ke versi baru
  • Konfigurasi instance ekstensi diubah

Salah satu kasus penggunaan terpenting dari fitur ini adalah mengisi ulang data . Misalnya, Anda membuat ekstensi yang menghasilkan pratinjau thumbnail dari gambar yang diunggah ke keranjang Cloud Storage. Pekerjaan utama ekstensi Anda akan dilakukan dalam fungsi yang dipicu oleh peristiwa onFinalize Cloud Storage. Namun, hanya gambar yang diunggah setelah ekstensi dipasang yang akan diproses. Dengan menyertakan fungsi yang dipicu oleh peristiwa siklus hidup onInstall dalam ekstensi Anda, Anda juga dapat membuat pratinjau thumbnail dari gambar apa pun yang ada saat ekstensi dipasang.

Beberapa kasus penggunaan lain dari pemicu peristiwa siklus proses meliputi:

  • Mengotomatiskan penyiapan pasca pemasangan (membuat catatan basis data, pengindeksan, dll.)
  • Jika Anda harus memublikasikan perubahan yang tidak kompatibel dengan versi sebelumnya, migrasikan data secara otomatis saat pembaruan

Penangan peristiwa siklus hidup yang berjalan singkat

Jika tugas Anda dapat berjalan sepenuhnya dalam durasi maksimum Cloud Functions (9 menit menggunakan API generasi pertama), Anda dapat menulis pengendali peristiwa daur hidup sebagai satu fungsi yang memicu peristiwa onDispatch antrean tugas:

export const myTaskFunction = functions.tasks.taskQueue()
  .onDispatch(async () => {
    // Complete your lifecycle event handling task.
    // ...

    // When processing is complete, report status to the user (see below).
  });

Kemudian, di file extension.yaml ekstensi Anda, lakukan hal berikut:

  1. Daftarkan fungsi Anda sebagai sumber ekstensi dengan set properti taskQueueTrigger . Jika Anda menyetel taskQueueTrigger ke peta kosong ( {} ), ekstensi Anda akan menyediakan antrean Cloud Tasks menggunakan setelan default; Anda dapat menyetel pengaturan ini secara opsional.

    resources:
      - name: myTaskFunction
        type: firebaseextensions.v1beta.function
        description: >-
          Describe the task performed when the function is triggered by a lifecycle
          event
        properties:
          location: ${LOCATION}
          taskQueueTrigger: {}
    
  2. Daftarkan fungsi Anda sebagai penangan untuk satu atau beberapa peristiwa siklus hidup:

    resources:
      - ...
    lifecycleEvents:
      onInstall:
        function: myTaskFunction
        processingMessage: Resizing your existing images
      onUpdate:
        function: myOtherTaskFunction
        processingMessage: Setting up your extension
      onConfigure:
        function: myOtherTaskFunction
        processingMessage: Setting up your extension
    
    

    Anda dapat mendaftarkan fungsi untuk salah satu peristiwa berikut: onInstall , onUpdate , dan onConfigure . Semua acara ini bersifat opsional.

  3. Direkomendasikan : Jika tugas pemrosesan tidak diperlukan agar ekstensi Anda berfungsi, tambahkan parameter yang dikonfigurasi pengguna yang memungkinkan pengguna memilih apakah akan mengaktifkannya.

    Misalnya, tambahkan parameter seperti berikut:

    params:
      - param: DO_BACKFILL
        label: Backfill existing images
        description: >
          Should existing, unresized images in the Storage bucket be resized as well?
        type: select
        options:
          - label: Yes
            value: true
          - label: No
            value: false
    

    Dan dalam fungsi Anda, jika parameter disetel ke false , keluar lebih awal:

    export const myTaskFunction = functions.tasks.taskQueue()
      .onDispatch(async () => {
        if (!process.env.DO_BACKFILL) {
          await runtime.setProcessingState(
            "PROCESSING_COMPLETE",
            "Existing images were not resized."
          );
          return;
        }
        // Complete your lifecycle event handling task.
        // ...
      });
    

Melakukan tugas jangka panjang

Jika tugas Anda tidak dapat diselesaikan dalam durasi maksimum Cloud Functions, bagi tugas menjadi subtugas dan lakukan setiap subtugas secara berurutan dengan mengantrekan tugas menggunakan metode TaskQueue.enqueue() Admin SDK.

Misalnya, Anda ingin mengisi ulang data Cloud Firestore. Anda dapat membagi koleksi dokumen menjadi potongan-potongan menggunakan kursor kueri . Setelah memproses potongan, lanjutkan offset awal dan enqueue pemanggilan fungsi lain seperti yang ditunjukkan di bawah ini:

import { getFirestore } from "firebase-admin/firestore";
import { getFunctions } from "firebase-admin/functions";

exports.backfilldata = functions.tasks.taskQueue().onDispatch(async (data) => {
  // When a lifecycle event triggers this function, it doesn't pass any data,
  // so an undefined offset indicates we're on our first invocation and should
  // start at offset 0. On subsequent invocations, we'll pass an explicit
  // offset.
  const offset = data["offset"] ?? 0;

  // Get a batch of documents, beginning at the offset.
  const snapshot = await getFirestore()
    .collection(process.env.COLLECTION_PATH)
    .startAt(offset)
    .limit(DOCS_PER_BACKFILL)
    .get();
  // Process each document in the batch.
  const processed = await Promise.allSettled(
    snapshot.docs.map(async (documentSnapshot) => {
      // Perform the processing.
    })
  );

  // If we processed a full batch, there are probably more documents to
  // process, so enqueue another invocation of this function, specifying
  // the offset to start with.
  //
  // If we processed less than a full batch, we're done.
  if (processed.length == DOCS_PER_BACKFILL) {
    const queue = getFunctions().taskQueue(
      "backfilldata",
      process.env.EXT_INSTANCE_ID
    );
    await queue.enqueue({
      offset: offset + DOCS_PER_BACKFILL,
    });
  } else {
      // Processing is complete. Report status to the user (see below).
  }
});

Tambahkan fungsi ke extension.yaml Anda seperti yang dijelaskan di bagian sebelumnya .

Status pelaporan

Saat semua fungsi pemrosesan Anda selesai, baik berhasil atau dengan kesalahan, laporkan status tugas menggunakan metode runtime ekstensi Admin SDK. Pengguna dapat melihat status ini di halaman detail ekstensi di Firebase console.

Penyelesaian yang berhasil dan kesalahan non-fatal

Untuk melaporkan penyelesaian yang berhasil dan error non-fatal (error yang tidak menyebabkan ekstensi tidak berfungsi), gunakan metode runtime ekstensi setProcessingState() dari Admin SDK:

import { getExtensions } from "firebase-admin/extensions";

// ...

getExtensions().runtime().setProcessingState(processingState, message);

Anda dapat mengatur status berikut:

Kondisi tidak fatal
PROCESSING_COMPLETE

Gunakan untuk melaporkan penyelesaian tugas yang berhasil. Contoh:

getExtensions().runtime().setProcessingState(
  "PROCESSING_COMPLETE",
  `Backfill complete. Successfully processed ${numSuccess} documents.`
);
PROCESSING_WARNING

Gunakan untuk melaporkan keberhasilan sebagian. Contoh:

getExtensions().runtime().setProcessingState(
  "PROCESSING_WARNING",
  `Backfill complete. ${numSuccess} documents processed successfully.`
    + ` ${numFailed} documents failed to process. ${listOfErrors}.`
    + ` ${instructionsToFixTheProblem}`
);
PROCESSING_FAILED

Gunakan untuk melaporkan kesalahan yang mencegah penyelesaian tugas, tetapi jangan biarkan ekstensi tidak dapat digunakan. Contoh:

getExtensions().runtime().setProcessingState(
  "PROCESSING_FAILED",
  `Backfill failed. ${errorMsg} ${optionalInstructionsToFixTheProblem}.`
);

Untuk melaporkan error yang membuat ekstensi tidak dapat digunakan, panggil setFatalError() .

NONE

Gunakan untuk menghapus status tugas. Anda dapat menggunakan ini secara opsional untuk menghapus pesan status dari konsol (misalnya, setelah beberapa waktu berlalu sejak pengaturan PROCESSING_COMPLETE ). Contoh:

getExtensions().runtime().setProcessingState("NONE");

Kesalahan fatal

Jika terjadi kesalahan yang mencegah ekstensi berfungsi—misalnya, tugas penyiapan yang diperlukan gagal—laporkan kesalahan fatal dengan setFatalError() :

import { getExtensions } from "firebase-admin/extensions";

// ...

getExtensions().runtime().setFatalError(`Post-installation setup failed. ${errorMessage}`);

Menyetel antrian tugas

Jika Anda menyetel properti taskQueueTrigger ke {} , ekstensi Anda akan menyediakan antrean Cloud Tasks dengan setelan default saat instance ekstensi diinstal. Alternatifnya, Anda dapat menyetel batas konkurensi antrean tugas dan mencoba lagi perilaku dengan memberikan nilai tertentu:

resources:
  - name: myTaskFunction
    type: firebaseextensions.v1beta.function
    description: >-
      Perform a task when triggered by a lifecycle event
    properties:
      location: ${LOCATION}
      taskQueueTrigger:
        rateLimits:
          maxConcurrentDispatches: 1000
          maxDispatchesPerSecond: 500
        retryConfig:
          maxAttempts: 100  # Warning: setting this too low can prevent the function from running
          minBackoffSeconds: 0.1
          maxBackoffSeconds: 3600
          maxDoublings: 16
lifecycleEvents:
  onInstall: 
    function: myTaskFunction
    processingMessage: Resizing your existing images
  onUpdate:
    function: myTaskFunction
    processingMessage: Setting up your extension
  onConfigure:
    function: myOtherTaskFunction
    processingMessage: Setting up your extension

Lihat Mengonfigurasi antrean Tugas Cloud di dokumen Google Cloud untuk mengetahui detail tentang parameter ini.

Contoh

Ekstensi resmi storage-resize-images , firestore-bigquery-export , dan firestore-translate-text semuanya menggunakan lifecycle event handler untuk mengisi ulang data.