Catch up on highlights from Firebase at Google I/O 2023. Learn more

Xử lý các sự kiện vòng đời của tiện ích mở rộng của bạn

Tiện ích mở rộng của bạn có thể bao gồm các chức năng Nhiệm vụ trên đám mây kích hoạt khi phiên bản tiện ích mở rộng trải qua bất kỳ sự kiện vòng đời nào sau đây:

  • Một phiên bản của tiện ích mở rộng đã được cài đặt
  • Phiên bản của tiện ích mở rộng được cập nhật lên phiên bản mới
  • Cấu hình của phiên bản tiện ích mở rộng bị thay đổi

Một trong những trường hợp sử dụng quan trọng nhất của tính năng này là chèn lấp dữ liệu . Ví dụ: giả sử bạn đang tạo tiện ích mở rộng tạo bản xem trước hình thu nhỏ của hình ảnh được tải lên bộ chứa Lưu trữ đám mây. Công việc chính của tiện ích mở rộng của bạn sẽ được thực hiện trong một chức năng được kích hoạt bởi sự kiện onFinalize Cloud Storage. Tuy nhiên, chỉ những hình ảnh được tải lên sau khi cài đặt tiện ích mở rộng mới được xử lý. Bằng cách đưa vào tiện ích mở rộng của bạn một chức năng được kích hoạt bởi sự kiện vòng đời onInstall , bạn cũng có thể tạo bản xem trước hình thu nhỏ của bất kỳ hình ảnh hiện có nào khi tiện ích mở rộng được cài đặt.

Một số trường hợp sử dụng khác của trình kích hoạt sự kiện vòng đời bao gồm:

  • Tự động thiết lập sau cài đặt (tạo bản ghi cơ sở dữ liệu, lập chỉ mục, v.v.)
  • Nếu bạn phải xuất bản các thay đổi không tương thích ngược, hãy tự động di chuyển dữ liệu khi cập nhật

Trình xử lý sự kiện vòng đời chạy ngắn

Nếu tác vụ của bạn có thể chạy hoàn toàn trong thời lượng tối đa của Chức năng đám mây (9 phút sử dụng API thế hệ thứ nhất), thì bạn có thể viết trình xử lý sự kiện vòng đời của mình dưới dạng một hàm duy nhất kích hoạt sự kiện onDispatch trên hàng đợi tác vụ:

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

Sau đó, trong tệp extension.yaml của tiện ích mở rộng của bạn, hãy làm như sau:

  1. Đăng ký chức năng của bạn dưới dạng tài nguyên mở rộng với bộ thuộc tính taskQueueTrigger . Nếu bạn đặt taskQueueTrigger thành bản đồ trống ( {} ), tiện ích mở rộng của bạn sẽ cung cấp hàng đợi Tác vụ trên đám mây bằng cách sử dụng cài đặt mặc định; bạn có thể tùy chọn điều chỉnh các cài đặt này .

    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. Đăng ký chức năng của bạn với tư cách là trình xử lý cho một hoặc nhiều sự kiện vòng đời:

    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
    
    

    Bạn có thể đăng ký chức năng cho bất kỳ sự kiện nào sau đây: onInstall , onUpdateonConfigure . Tất cả những sự kiện này là tùy chọn.

  3. Khuyến nghị : Nếu tác vụ xử lý không bắt buộc để tiện ích mở rộng của bạn hoạt động, hãy thêm tham số do người dùng định cấu hình để cho phép người dùng chọn có bật hay không.

    Ví dụ: thêm một tham số như sau:

    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
    

    Và trong hàm của bạn, nếu tham số được đặt thành false , hãy thoát sớm:

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

Thực hiện các nhiệm vụ chạy dài

Nếu nhiệm vụ của bạn không thể hoàn thành trong khoảng thời gian tối đa của Cloud Function, hãy chia nhiệm vụ thành các nhiệm vụ con và thực hiện từng nhiệm vụ con theo thứ tự bằng cách xếp các công việc vào hàng đợi bằng phương thức TaskQueue.enqueue() của SDK quản trị.

Ví dụ: giả sử bạn muốn chèn lấp dữ liệu Cloud Firestore. Bạn có thể chia bộ sưu tập tài liệu thành nhiều phần bằng cách sử dụng con trỏ truy vấn . Sau khi xử lý một đoạn, hãy tăng phần bù bắt đầu và đưa vào hàng đợi một lệnh gọi hàm khác như được hiển thị bên dưới:

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

Thêm chức năng vào extension.yaml của bạn như được mô tả trong phần trước .

tình trạng báo cáo

Khi tất cả các chức năng xử lý của bạn kết thúc, dù thành công hay có lỗi, hãy báo cáo trạng thái của tác vụ bằng cách sử dụng các phương pháp thời gian chạy tiện ích mở rộng của SDK dành cho quản trị viên. Người dùng có thể thấy trạng thái này trên trang chi tiết tiện ích mở rộng trong bảng điều khiển Firebase.

Hoàn thành thành công và lỗi không nghiêm trọng

Để báo cáo quá trình hoàn tất thành công và các lỗi không nghiêm trọng (các lỗi không đưa tiện ích vào trạng thái không hoạt động), hãy sử dụng phương thức thời gian chạy tiện ích setProcessingState() của SDK quản trị:

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

// ...

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

Bạn có thể đặt các trạng thái sau:

trạng thái không gây tử vong
PROCESSING_COMPLETE

Sử dụng để báo cáo hoàn thành nhiệm vụ thành công. Ví dụ:

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

Sử dụng để báo cáo thành công một phần. Ví dụ:

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

Sử dụng để báo cáo lỗi khiến tác vụ không thể hoàn thành, nhưng không để tiện ích mở rộng không sử dụng được. Ví dụ:

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

Để báo cáo các lỗi khiến tiện ích mở rộng không sử dụng được, hãy gọi setFatalError() .

NONE

Sử dụng để xóa trạng thái của nhiệm vụ. Bạn có thể tùy ý sử dụng điều này để xóa thông báo trạng thái khỏi bảng điều khiển (ví dụ: sau một khoảng thời gian đã trôi qua kể từ khi đặt PROCESSING_COMPLETE ). Ví dụ:

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

lỗi nghiêm trọng

Nếu xảy ra lỗi khiến tiện ích mở rộng không hoạt động—ví dụ: tác vụ thiết lập bắt buộc không thành công—hãy báo cáo lỗi nghiêm trọng với setFatalError() :

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

// ...

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

Điều chỉnh hàng đợi nhiệm vụ

Nếu bạn đặt thuộc tính taskQueueTrigger thành {} , tiện ích mở rộng của bạn sẽ cung cấp hàng đợi Tác vụ trên đám mây với cài đặt mặc định khi phiên bản tiện ích mở rộng được cài đặt. Ngoài ra, bạn có thể điều chỉnh các giới hạn đồng thời của hàng đợi tác vụ và thử lại hành vi bằng cách cung cấp các giá trị cụ thể:

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

Xem Định cấu hình hàng đợi Tác vụ trên đám mây trong tài liệu Google Cloud để biết chi tiết về các tham số này.

ví dụ

Các tiện ích mở rộng chính thức storage-resize-images , firestore-bigquery-exportfirestore-translate-text đều sử dụng trình xử lý sự kiện vòng đời để chèn lấp dữ liệu.