Cloud Storage 觸發條件


您可以依據上傳、更新或 刪除 Cloud Storage 中的檔案和資料夾。

本頁中的範例是以圖片圖片時觸發的範例函式為依據 將檔案上傳至 Cloud Storage這個範例函式可示範 如何存取事件屬性、如何將檔案下載到 Cloud Functions 以及其他處理 Cloud Storage 事件的基礎知識。

匯入必要模組

如要開始使用,請匯入處理 Cloud Storage 所需的模組 事件:

Node.js

 const {onObjectFinalized} = require("firebase-functions/v2/storage");

Python

 from firebase_functions import storage_fn

如要建構完整範例,請同時新增 Firebase Admin SDK 和影像處理工具:

Node.js

 const {initializeApp} = require("firebase-admin/app");
const {getStorage} = require("firebase-admin/storage");
const logger = require("firebase-functions/logger");
const path = require("path");

// library for image resizing
const sharp = require("sharp");

initializeApp();

Python

 import io
import pathlib

from PIL import Image

from firebase_admin import initialize_app

initialize_app()
from firebase_admin import storage

設定 Cloud Storage 函式的範圍

請使用下列模式指定 函式,然後設定任何需要的選項:

Node.js

// scope handler to a specific bucket, using storage options parameter
export archivedopts = onObjectArchived({ bucket: "myBucket" }, (event) => {
  //…
});

Python

# Scope handler to a specific bucket using storage options parameter
@storage_fn.on_object_archived(bucket="myBucket")
def archived_bucket(event: storage_fn.CloudEvent[storage_fn.StorageObjectData]):
    # ...

相反地,範例縮圖產生器函式的範圍僅限於 專案:

Node.js

exports.generateThumbnail = onObjectFinalized({cpu: 2}, async (event) => {
// ...
});

Python

@storage_fn.on_object_archived()
def generatethumbnail(event: storage_fn.CloudEvent[storage_fn.StorageObjectData]):
    # ...

設定函式位置

位置 位置可能會導致部署失敗此外,位置之間的距離 觸發函式的位置和函式位置 網路延遲。如要避免上述情況,請 函式位置, 會以下列其中一種方式比對值區/觸發條件位置:

  • 函式位置與觸發位置相同
  • 函式位置位於觸發條件位置 (當觸發條件區域為 雙區域)
  • 如果觸發條件區域設為「us-central1」,函式可能會在任何位置執行

處理 Cloud Storage 事件

您可以利用下列處理常式來回應 Cloud Storage 事件:

Node.js

  • onObjectArchived 只在值區已啟用時傳送 物件版本管理功能。 這個事件表示物件的使用中版本已成為 封存版本,因為已封存或之前版本 覆寫覆寫值。
  • onObjectDeleted在永久刪除物件時傳送。這個 包含值區內遭覆寫或刪除的物件 生命週期設定。 如為含有 物件版本管理 啟用後,物件在封存時不會傳送 (請參閱 onArchive), 透過 storage.objects.delete 方法封存封存檔。
  • onObjectFinalized:發生以下情況時傳送:新物件 (或新一代的 物件),包括複製內容 或重寫現有物件上傳失敗不會觸發這個事件。
  • onMetadataUpdated 在現有物件的中繼資料變更時傳送。

Python

  • on_object_archived 只在值區已啟用時傳送 物件版本管理功能。 這個事件表示物件的使用中版本已成為 封存版本,因為已封存或之前版本 覆寫覆寫值。
  • on_object_deleted在永久刪除物件時傳送。這個 包含值區內遭覆寫或刪除的物件 生命週期設定。 如為含有 物件版本管理 啟用後,物件在封存時不會傳送 (請參閱 onArchive), 透過 storage.objects.delete 方法封存封存檔。
  • on_object_finalized:發生以下情況時傳送:新物件 (或新一代的 物件),包括複製內容 或重寫現有物件上傳失敗不會觸發這個事件。
  • on_metadata_updated 在現有物件的中繼資料變更時傳送。

存取 Cloud Storage 物件屬性

Cloud Functions 會顯示許多 Cloud Storage 物件屬性 ,例如更新檔案的物件大小和內容類型metageneration 屬性發生變更時, 物件中繼資料如果是新物件,metageneration 的值則為 1

Node.js

const fileBucket = event.data.bucket; // Storage bucket containing the file.
const filePath = event.data.name; // File path in the bucket.
const contentType = event.data.contentType; // File content type.

Python

bucket_name = event.data.bucket
file_path = pathlib.PurePath(event.data.name)
content_type = event.data.content_type

縮圖產生範例會使用部分屬性來偵測離開事件 出現以下情況時:

Node.js

// Exit if this is triggered on a file that is not an image.
if (!contentType.startsWith("image/")) {
  return logger.log("This is not an image.");
}
// Exit if the image is already a thumbnail.
const fileName = path.basename(filePath);
if (fileName.startsWith("thumb_")) {
  return logger.log("Already a Thumbnail.");
}

Python

# Exit if this is triggered on a file that is not an image.
if not content_type or not content_type.startswith("image/"):
    print(f"This is not an image. ({content_type})")
    return

# Exit if the image is already a thumbnail.
if file_path.name.startswith("thumb_"):
    print("Already a thumbnail.")
    return

下載、轉換及上傳檔案

在某些情況下,您可能不需要從 一起來探索這個決策樹 協助您找到合適的 Cloud Storage 儲存空間級別不過,如要執行大量工作,例如產生 如果圖片來源為 Cloud Storage 檔案,您必須先下載 傳送至函式執行個體,也就是執行 程式碼。

搭配使用 Cloud Functions 和圖片處理程式,例如 sharp 適用於 Node.js 和 Python 適用的 Pillow 即可 圖像檔案的相關操作以下範例說明如何 為上傳的圖片檔案建立縮圖圖片:

Node.js

/**
 * When an image is uploaded in the Storage bucket,
 * generate a thumbnail automatically using sharp.
 */
exports.generateThumbnail = onObjectFinalized({cpu: 2}, async (event) => {

  const fileBucket = event.data.bucket; // Storage bucket containing the file.
  const filePath = event.data.name; // File path in the bucket.
  const contentType = event.data.contentType; // File content type.

  // Exit if this is triggered on a file that is not an image.
  if (!contentType.startsWith("image/")) {
    return logger.log("This is not an image.");
  }
  // Exit if the image is already a thumbnail.
  const fileName = path.basename(filePath);
  if (fileName.startsWith("thumb_")) {
    return logger.log("Already a Thumbnail.");
  }

  // Download file into memory from bucket.
  const bucket = getStorage().bucket(fileBucket);
  const downloadResponse = await bucket.file(filePath).download();
  const imageBuffer = downloadResponse[0];
  logger.log("Image downloaded!");

  // Generate a thumbnail using sharp.
  const thumbnailBuffer = await sharp(imageBuffer).resize({
    width: 200,
    height: 200,
    withoutEnlargement: true,
  }).toBuffer();
  logger.log("Thumbnail created");

  // Prefix 'thumb_' to file name.
  const thumbFileName = `thumb_${fileName}`;
  const thumbFilePath = path.join(path.dirname(filePath), thumbFileName);

  // Upload the thumbnail.
  const metadata = {contentType: contentType};
  await bucket.file(thumbFilePath).save(thumbnailBuffer, {
    metadata: metadata,
  });
  return logger.log("Thumbnail uploaded!");
});

將檔案下載為暫存檔 複製到 Cloud Functions 執行個體的目錄在這個位置,您可以 視需要處理檔案,然後上傳至 Cloud Storage。時間 執行非同步工作時,請務必在 回呼。

Python

@storage_fn.on_object_finalized()
def generatethumbnail(event: storage_fn.CloudEvent[storage_fn.StorageObjectData]):
    """When an image is uploaded in the Storage bucket, generate a thumbnail
    automatically using Pillow."""

    bucket_name = event.data.bucket
    file_path = pathlib.PurePath(event.data.name)
    content_type = event.data.content_type

    # Exit if this is triggered on a file that is not an image.
    if not content_type or not content_type.startswith("image/"):
        print(f"This is not an image. ({content_type})")
        return

    # Exit if the image is already a thumbnail.
    if file_path.name.startswith("thumb_"):
        print("Already a thumbnail.")
        return

    bucket = storage.bucket(bucket_name)

    image_blob = bucket.blob(str(file_path))
    image_bytes = image_blob.download_as_bytes()
    image = Image.open(io.BytesIO(image_bytes))

    image.thumbnail((200, 200))
    thumbnail_io = io.BytesIO()
    image.save(thumbnail_io, format="png")
    thumbnail_path = file_path.parent / pathlib.PurePath(f"thumb_{file_path.stem}.png")
    thumbnail_blob = bucket.blob(str(thumbnail_path))
    thumbnail_blob.upload_from_string(thumbnail_io.getvalue(), content_type="image/png")

這段程式碼會建立 儲存在暫存目錄中的圖片縮圖 200x200,然後上傳 返回 Cloud Storage