ทริกเกอร์ 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

ใช้รูปแบบต่อไปนี้เพื่อกำหนดขอบเขตฟังก์ชันไปยัง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]):
    # ...

ตั้งค่าตำแหน่งฟังก์ชัน

ความไม่ตรงกันระหว่าง สถานที่ตั้งอาจทำให้การติดตั้งใช้งานล้มเหลว นอกจากนี้ ระยะทางระหว่างตำแหน่งของที่เก็บข้อมูล Cloud Storage กับตำแหน่งของฟังก์ชันอาจทำให้เกิดเวลาในการตอบสนองของเครือข่ายที่สูงมาก หากต้องการหลีกเลี่ยงสถานการณ์เหล่านี้ ให้ระบุตำแหน่งฟังก์ชันเพื่อให้ตรงกับตำแหน่งของที่เก็บข้อมูล/ทริกเกอร์ด้วยวิธีใดวิธีหนึ่งต่อไปนี้

  • ตำแหน่งฟังก์ชันเหมือนกับตำแหน่งทริกเกอร์
  • ตำแหน่งฟังก์ชันอยู่ภายในตำแหน่งทริกเกอร์ (เมื่อภูมิภาคทริกเกอร์เป็นแบบ คู่/หลายภูมิภาค)
  • ฟังก์ชันอาจอยู่ในตำแหน่งใดก็ได้หากตั้งค่าภูมิภาคทริกเกอร์เป็น 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 และ 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 ใน การเรียกกลับ

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