คุณสามารถทริกเกอร์ฟังก์ชันเพื่อตอบสนองต่อการอัปโหลด อัปเดต หรือลบไฟล์และโฟลเดอร์ใน Cloud Storage
ตัวอย่างในหน้านี้อิงตามฟังก์ชันตัวอย่างที่ทริกเกอร์เมื่อมีการอัปโหลดไฟล์รูปภาพไปยัง Cloud Storage ฟังก์ชันตัวอย่างนี้สาธิตวิธีเข้าถึงแอตทริบิวต์ของเหตุการณ์ วิธีดาวน์โหลดไฟล์ไปยังอินสแตนซ์ Cloud Functions และพื้นฐานอื่นๆ ในการจัดการเหตุการณ์ Cloud Storage
นำเข้าโมดูลที่จำเป็น
ในการเริ่มต้น ให้นำเข้าโมดูลที่จำเป็นสำหรับการจัดการเหตุการณ์ Cloud Storage:
โหนด js
const {onObjectFinalized} = require("firebase-functions/v2/storage");
หลาม
from firebase_functions import storage_fn
หากต้องการสร้างตัวอย่างแบบเต็ม ให้เพิ่มการขึ้นต่อกันสำหรับ Firebase Admin SDK และเครื่องมือประมวลผลรูปภาพ:
โหนด 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();
หลาม
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 ที่ต้องการ และตั้งค่าตัวเลือกที่ต้องการ:
โหนด js
// scope handler to a specific bucket, using storage options parameter
export 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]):
# ...
ในทางตรงกันข้าม ฟังก์ชันตัวสร้างภาพขนาดย่อตัวอย่างถูกกำหนดขอบเขตไว้ที่บัคเก็ตเริ่มต้นสำหรับโปรเจ็กต์:
โหนด 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:
โหนด 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
โหนด 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
ตัวอย่างการสร้างภาพขนาดย่อใช้คุณลักษณะบางอย่างเหล่านี้เพื่อตรวจจับกรณีทางออกที่ฟังก์ชันส่งคืน:
โหนด 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 คุณสามารถดำเนินการปรับแต่งไฟล์ภาพกราฟิกได้ ต่อไปนี้เป็นตัวอย่างวิธีการสร้างภาพขนาดย่อสำหรับไฟล์ภาพที่อัพโหลด:
โหนด 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 ในการติดต่อกลับของคุณ
หลาม
@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