Kích hoạt lưu trữ đám mây


Bạn có thể kích hoạt một chức năng để phản hồi việc tải lên, cập nhật hoặc xóa các tệp và thư mục trong Cloud Storage.

Các ví dụ trong trang này dựa trên hàm mẫu kích hoạt khi tệp hình ảnh được tải lên Cloud Storage. Hàm mẫu này trình bày cách truy cập các thuộc tính sự kiện, cách tải tệp xuống phiên bản Chức năng đám mây và các nguyên tắc cơ bản khác về xử lý các sự kiện Lưu trữ đám mây.

Nhập các mô-đun cần thiết

Để bắt đầu, hãy nhập mô-đun cần thiết để xử lý các sự kiện Cloud Storage:

Node.js

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

Python

 from firebase_functions import storage_fn

Để xây dựng mẫu đầy đủ, hãy thêm các phần phụ thuộc cho SDK quản trị Firebase và các công cụ xử lý hình ảnh:

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

Phạm vi chức năng Lưu trữ đám mây

Sử dụng mẫu sau để xác định phạm vi chức năng của bạn cho một nhóm Lưu trữ đám mây cụ thể và đặt bất kỳ tùy chọn mong muốn nào:

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]):
    # ...

Ngược lại, hàm tạo hình thu nhỏ mẫu được đặt trong nhóm mặc định cho dự án:

Node.js

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

Python

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

Đặt vị trí chức năng

Sự không khớp giữa các vị trí có thể dẫn đến thất bại trong việc triển khai. Ngoài ra, khoảng cách giữa vị trí của bộ chứa Cloud Storage và vị trí của chức năng có thể tạo ra độ trễ mạng đáng kể. Để tránh những tình huống này, hãy chỉ định vị trí hàm sao cho khớp với vị trí nhóm/trình kích hoạt theo một trong các cách sau:

  • Vị trí chức năng giống với vị trí kích hoạt
  • Vị trí chức năng nằm bên trong vị trí kích hoạt (khi vùng kích hoạt là vùng kép/đa vùng)
  • Chức năng có thể ở bất kỳ vị trí nào nếu vùng kích hoạt được đặt thành us-central1

Xử lý các sự kiện Lưu trữ đám mây

Các trình xử lý này để phản hồi các sự kiện Cloud Storage có sẵn:

Node.js

  • onObjectArchived Chỉ được gửi khi một nhóm đã bật tính năng lập phiên bản đối tượng . Sự kiện này cho biết rằng phiên bản trực tiếp của một đối tượng đã trở thành phiên bản được lưu trữ, do nó đã được lưu trữ hoặc do nó bị ghi đè khi tải lên một đối tượng cùng tên.
  • onObjectDeleted Được gửi khi một đối tượng đã bị xóa vĩnh viễn. Điều này bao gồm các đối tượng bị ghi đè hoặc bị xóa trong cấu hình vòng đời của nhóm . Đối với các nhóm đã bật phiên bản đối tượng , thông tin này không được gửi khi đối tượng được lưu trữ (xem onArchive ), ngay cả khi quá trình lưu trữ diễn ra thông qua phương thức storage.objects.delete .
  • onObjectFinalized Được gửi khi một đối tượng mới (hoặc thế hệ mới của đối tượng hiện có) được tạo thành công trong nhóm. Điều này bao gồm việc sao chép hoặc viết lại một đối tượng hiện có. Tải lên không thành công không kích hoạt sự kiện này.
  • onMetadataUpdated gửi khi siêu dữ liệu của đối tượng hiện có thay đổi.

Python

  • on_object_archived Chỉ được gửi khi một nhóm đã bật tính năng lập phiên bản đối tượng . Sự kiện này cho biết rằng phiên bản trực tiếp của một đối tượng đã trở thành phiên bản được lưu trữ, do nó đã được lưu trữ hoặc do nó bị ghi đè khi tải lên một đối tượng cùng tên.
  • on_object_deleted Được gửi khi một đối tượng đã bị xóa vĩnh viễn. Điều này bao gồm các đối tượng bị ghi đè hoặc bị xóa trong cấu hình vòng đời của nhóm . Đối với các nhóm đã bật phiên bản đối tượng , thông tin này không được gửi khi đối tượng được lưu trữ (xem onArchive ), ngay cả khi quá trình lưu trữ diễn ra thông qua phương thức storage.objects.delete .
  • on_object_finalized Được gửi khi một đối tượng mới (hoặc thế hệ mới của đối tượng hiện có) được tạo thành công trong nhóm. Điều này bao gồm việc sao chép hoặc viết lại một đối tượng hiện có. Tải lên không thành công không kích hoạt sự kiện này.
  • on_metadata_updated Được gửi khi siêu dữ liệu của đối tượng hiện có thay đổi.

Truy cập các thuộc tính đối tượng Cloud Storage

Cloud Functions hiển thị một số thuộc tính của đối tượng Cloud Storage chẳng hạn như kích thước của đối tượng và loại nội dung đối với tệp được cập nhật. Thuộc tính metageneration được tăng lên bất cứ khi nào có thay đổi đối với siêu dữ liệu của đối tượng. Đối với các đối tượng mới, giá trị metageneration1 .

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

Mẫu tạo hình thu nhỏ sử dụng một số thuộc tính sau để phát hiện các trường hợp thoát mà hàm trả về:

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

Tải xuống, chuyển đổi và tải lên một tập tin

Trong một số trường hợp, có thể không cần thiết phải tải xuống tệp từ Cloud Storage. Tuy nhiên, để thực hiện các tác vụ chuyên sâu như tạo hình ảnh thu nhỏ từ tệp được lưu trữ trong Cloud Storage, bạn cần tải tệp xuống phiên bản hàm—tức là máy ảo chạy mã của bạn.

Sử dụng Cloud Functions cùng với các chương trình xử lý hình ảnh như sharp cho Node.js và Pillow cho Python, bạn có thể thực hiện các thao tác trên các tệp hình ảnh đồ họa. Sau đây là ví dụ về cách tạo hình thu nhỏ cho tệp hình ảnh đã tải lên:

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!");
});

Tải tệp xuống thư mục tạm thời trên phiên bản Cloud Functions của bạn. Ở vị trí này, bạn có thể xử lý tệp khi cần rồi tải lên Cloud Storage. Khi thực hiện các tác vụ không đồng bộ, hãy đảm bảo bạn trả lại lời hứa JavaScript trong lệnh gọi lại của mình.

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")

Mã này tạo hình thu nhỏ 200x200 cho hình ảnh được lưu trong thư mục tạm thời, sau đó tải nó trở lại Cloud Storage.