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

Uzantınızın yaşam döngüsü olaylarını yönetin

Uzantınız, bir uzantı örneği aşağıdaki yaşam döngüsü olaylarından herhangi birini geçtiğinde tetiklenen Cloud Tasks işlevlerini içerebilir:

  • Uzantının bir örneği yüklendi
  • Uzantının bir örneği yeni bir sürüme güncellendi
  • Bir uzantı örneğinin yapılandırması değiştirildi

Bu özelliğin en önemli kullanım durumlarından biri , verilerin doldurulmasıdır . Örneğin, bir Bulut Depolama grubuna yüklenen görüntülerin küçük resim önizlemelerini oluşturan bir uzantı oluşturduğunuzu varsayalım. Uzantınızın ana işi, onFinalize Cloud Storage olayı tarafından tetiklenen bir işlevde yapılır. Ancak, yalnızca uzantı yüklendikten sonra yüklenen resimler işlenir. Uzantınıza onInstall yaşam döngüsü olayı tarafından tetiklenen bir işlevi dahil ederek, uzantı yüklendiğinde mevcut tüm görüntülerin küçük resim önizlemelerini de oluşturabilirsiniz.

Yaşam döngüsü olay tetikleyicilerinin diğer bazı kullanım durumları şunları içerir:

  • Kurulum sonrası kurulumu otomatikleştirin (veritabanı kayıtları oluşturma, indeksleme vb.)
  • Geriye dönük uyumsuz değişiklikleri yayınlamanız gerekiyorsa, güncelleme sırasında verileri otomatik olarak taşıyın

Kısa süreli yaşam döngüsü olay işleyicileri

Göreviniz maksimum Cloud Functions süresi içinde (birinci nesil API kullanılarak 9 dakika) tamamen çalışabiliyorsa, yaşam döngüsü olay işleyicinizi, görev kuyruğu onDispatch olayında tetiklenen tek bir işlev olarak yazabilirsiniz:

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

Ardından, uzantınızın extension.yaml dosyasında aşağıdakileri yapın:

  1. İşlevinizi, taskQueueTrigger özellik kümesiyle bir uzantı kaynağı olarak kaydedin. taskQueueTrigger boş haritaya ( {} ) ayarlarsanız, uzantınız varsayılan ayarları kullanarak bir Cloud Tasks kuyruğu sağlar; isteğe bağlı olarak bu ayarları yapabilirsiniz.

    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. İşlevinizi bir veya daha fazla yaşam döngüsü olayı için işleyici olarak kaydedin:

    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
    
    

    Aşağıdaki olaylardan herhangi biri için işlevleri kaydedebilirsiniz: onInstall , onUpdate ve onConfigure . Bu olayların tümü isteğe bağlıdır.

  3. Önerilen : Uzantınızın çalışması için işleme görevi gerekli değilse, kullanıcıların etkinleştirip etkinleştirmemeyi seçmesine olanak tanıyan , kullanıcı tarafından yapılandırılan bir parametre ekleyin.

    Örneğin, aşağıdaki gibi bir parametre ekleyin:

    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
    

    İşlevinizde, parametre false olarak ayarlanmışsa erken çıkın:

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

Uzun süren görevleri gerçekleştirme

Göreviniz maksimum Cloud Functions süresi içinde tamamlanamazsa, görevi alt görevlere ayırın ve işleri Admin SDK'nın TaskQueue.enqueue() yöntemiyle kuyruğa alarak her bir alt görevi sırayla gerçekleştirin.

Örneğin, Cloud Firestore verilerini doldurmak istediğinizi varsayalım. Sorgu imleçlerini kullanarak belge koleksiyonunu parçalara ayırabilirsiniz. Bir öbeği işledikten sonra, başlangıç ​​ofsetini ilerletin ve aşağıda gösterildiği gibi başka bir işlev çağrısını kuyruğa alın:

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

Önceki bölümde açıklandığı gibi extension.yaml dosyanıza işlevi ekleyin.

Raporlama durumu

Tüm işleme işlevleriniz başarıyla veya bir hatayla tamamlandığında, Admin SDK'nın uzantı çalışma zamanı yöntemlerini kullanarak görevin durumunu bildirin. Kullanıcılar bu durumu Firebase konsolundaki uzantı ayrıntıları sayfasında görebilir.

Başarılı tamamlama ve ölümcül olmayan hatalar

Başarılı tamamlama ve önemli olmayan hataları (uzantıyı işlevsiz bir duruma getirmeyen hatalar) bildirmek için Admin SDK'nın setProcessingState() extension runtime yöntemini kullanın:

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

// ...

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

Aşağıdaki durumları ayarlayabilirsiniz:

Ölümcül olmayan durumlar
PROCESSING_COMPLETE

Görevin başarıyla tamamlandığını bildirmek için kullanın. Örnek:

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

Kısmi başarıyı bildirmek için kullanın. Örnek:

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

Görevin tamamlanmasını engelleyen ancak uzantıyı kullanılmaz hale getirmeyen hataları bildirmek için kullanın. Örnek:

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

Uzantıyı kullanılamaz hale getiren hataları bildirmek için setFatalError() öğesini çağırın.

NONE

Görevin durumunu temizlemek için kullanın. Durum mesajını konsoldan silmek için isteğe bağlı olarak bunu kullanabilirsiniz (örneğin, PROCESSING_COMPLETE ayarlandıktan sonra bir süre geçtikten sonra). Örnek:

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

Önemli hatalar

Uzantının çalışmasını engelleyen bir hata oluşursa (örneğin, gerekli bir kurulum görevinin başarısız olması) ölümcül hatayı setFatalError() ile bildirin:

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

// ...

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

Görev kuyruğunu ayarlama

taskQueueTrigger özelliğini {} olarak ayarlarsanız, uzantınız, bir uzantı örneği yüklendiğinde varsayılan ayarlarla bir Cloud Tasks kuyruğu sağlar. Alternatif olarak, belirli değerler sağlayarak görev kuyruğunun eşzamanlılık sınırlarını ayarlayabilir ve davranışı yeniden deneyebilirsiniz:

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

Bu parametrelerle ilgili ayrıntılar için Google Cloud belgelerinde Bulut Görevleri sıralarını yapılandırma konusuna bakın.

örnekler

Resmi storage-resize-images , firestore-bigquery-export ve firestore-translate-text uzantılarının tümü, verileri doldurmak için yaşam döngüsü olay işleyicilerini kullanır.