راه‌اندازهای Cloud Storage

می‌توانید در پاسخ به بارگذاری، به‌روزرسانی، یا حذف فایل‌ها و پوشه‌ها در Cloud Storage، تابعی را راه‌اندازی کنید.

مثال‌های این صفحه براساس تابع نمونه‌ای است که وقتی فایل‌های تصویری در Cloud Storage بارگذاری می‌شوند راه‌اندازی می‌شود. این تابع نمونه نشان می‌دهد چگونه به مشخصه‌های رویداد دسترسی پیدا کنید، چگونه فایلی را در نمونه Cloud Functions بارگیری کنید، و دیگر اصول مدیریت رویدادهای Cloud Storage.

وارد کردن واحدهای لازم

برای شروع، واحد لازم برای مدیریت رویدادهای Cloud Storage را وارد کنید:

Node.js

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

پایتون

 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 = /** @type {typeof import("sharp")} */ (require("sharp"));

initializeApp();

پایتون

 import io
import pathlib

from PIL import Image

from firebase_admin import initialize_app

initialize_app()
from firebase_admin import storage

حوزه تابع Cloud Storage

از الگوی زیر برای محدود کردن دامنه تابع به یک دسته Cloud Storage خاص و تنظیم گزینه‌های دلخواه استفاده کنید:

Node.js

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

پایتون

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

پایتون

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

تنظیم مکان عملکرد

عدم تطابق بین مکان‌ها می‌تواند منجر به شکست در استقرار شود. همچنین، فاصله بین مکان یک دسته Cloud Storage و مکان تابع می‌تواند تأخیر شبکه قابل‌توجهی ایجاد کند. برای جلوگیری از این شرایط، مکان تابع را مشخص کنید تا با مکان راه‌انداز/سبد به یکی از این روش‌ها مطابقت داشته باشد:

  • مکان تابع با مکان راه‌انداز یکسان است
  • مکان تابع درون مکان راه‌انداز باشد (وقتی منطقه راه‌انداز دوگانه/چندگانه باشد)
  • اگر منطقه راه‌انداز روی us-central1 تنظیم شده باشد، تابع می‌تواند در هر مکانی باشد

رسیدگی به رویدادهای Cloud Storage

این گرداننده‌ها برای پاسخ دادن به رویدادهای Cloud Storage دردسترس هستند:

Node.js

  • onObjectArchived فقط زمانی ارسال می‌شود که یک دسته نسخه‌بندی شیء را فعال کرده باشد. این رویداد نشان می‌دهد که نسخه زنده یک شیء به نسخه بایگانی‌شده تبدیل شده است، یا به این دلیل که بایگانی شده است یا به این دلیل که با بارگذاری شیء دیگری با همان نام بازنویسی شده است.
  • onObjectDeleted وقتی ارسال می‌شود که شیء برای همیشه حذف شده باشد. این شامل اشیایی است که رونویسی شده‌اند یا به‌عنوان بخشی از پیکربندی چرخه حیات سطل حذف شده‌اند. برای دسته‌هایی که نسخه‌بندی شیء در آن‌ها فعال است، وقتی شیء بایگانی می‌شود (onArchive را ببینید)، این مورد ارسال نمی‌شود، حتی اگر بایگانی ازطریق روش storage.objects.delete انجام شود.
  • onObjectFinalized وقتی شیء جدیدی (یا نسل جدیدی از شیء موجود) باموفقیت در دسته ایجاد شود، ارسال می‌شود. این شامل کپی کردن یا بازنویسی شیء موجود می‌شود. بارگذاری ناموفق این رویداد را راه‌اندازی نمی‌کند.
  • onMetadataUpdated وقتی فراداده شیء موجودی تغییر می‌کند ارسال می‌شود.

پایتون

  • 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.

پایتون

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

پایتون

# 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 و Pillow برای Python، می‌توانید فایل‌های تصویری گرافیکی را دستکاری کنید. در زیر نمونه‌ای از نحوه ایجاد تصویر کوچک برای فایل تصویری بارگذاری‌شده آورده شده است:

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 بارگذاری کنید. هنگام انجام کارهای ناهمگام، مطمئن شوید که یک JavaScript promise در فراخوانی برگشتی‌تان برمی‌گردانید.

پایتون

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

این کد یک ریزعکس ۲۰۰×۲۰۰ برای تصویر ذخیره‌شده در دایرکتوری موقت ایجاد می‌کند، سپس آن را دوباره در Cloud Storage بارگذاری می‌کند.