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

หากต้องการสร้างตัวอย่างที่สมบูรณ์ ให้เพิ่มทรัพยากร Dependency สำหรับพารามิเตอร์ 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 ใน Callback

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