Bạn có thể kích hoạt một hàm để phản hồi việc tải lên, cập nhật hoặc xoá tệp và thư mục trong Cloud Storage.
Các ví dụ trong trang này dựa trên một hàm mẫu sẽ kích hoạt khi tệp hình ảnh được tải lên Cloud Storage. Hàm mẫu này minh hoạ cách truy cập vào các thuộc tính của sự kiện, cách tải một tệp xuống một thực thể Cloud Functions và các kiến thức cơ bản khác về việc xử lý các sự kiện Cloud Storage.
Nhập các mô-đun bắt buộc
Để 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
Để tạo mẫu đầy đủ, hãy thêm các phần phụ thuộc cho Firebase Admin SDK 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 của hàm Cloud Storage
Sử dụng mẫu sau để giới hạn phạm vi hàm của bạn trong một nhóm Cloud Storage cụ thể và đặt mọi lựa chọn mong muốn:
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 trình tạo hình thu nhỏ mẫu được giới hạn trong vùng chứa mặc định của 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í của hàm
Sự khác biệt giữa các vị trí có thể dẫn đến việc triển khai không thành công. Ngoài ra, khoảng cách giữa vị trí của một vùng chứa Cloud Storage và vị trí của hàm có thể tạo ra độ trễ đáng kể cho mạng. Để tránh những trường hợp này, hãy chỉ định vị trí hàm sao cho vị trí này khớp với vị trí của nhóm/trình kích hoạt theo một trong những cách sau:
- Vị trí của hàm giống với vị trí của điều kiện kích hoạt
- Vị trí của hàm nằm trong vị trí của điều kiện kích hoạt (khi vùng điều kiện kích hoạt là vùng kép/nhiều vùng)
- Hàm 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ý sự kiện Cloud Storage
Sau đây là các trình xử lý để phản hồi các sự kiện Cloud Storage:
Node.js
onObjectArchived
Chỉ được gửi khi một nhóm đã bật tính năng quản lý phiên bản đối tượng. Sự kiện này cho biết phiên bản trực tiếp của một đối tượng đã trở thành phiên bản lưu trữ, có thể là do đối tượng đó đã được lưu trữ hoặc do đối tượng đó đã bị ghi đè bằng việc tải lên một đối tượng có cùng tên.onObjectDeleted
Được gửi khi một đối tượng đã bị xoá vĩnh viễn. Điều này bao gồm các đối tượng bị ghi đè hoặc bị xoá trong cấu hình vòng đời của nhóm. Đối với các vùng chứa đã bật phiên bản đối tượng, thông tin này sẽ không được gửi khi một đối tượng được lưu trữ (xemonArchive
), ngay cả khi quá trình lưu trữ diễn ra thông qua phương thứcstorage.objects.delete
.onObjectFinalized
Gửi khi một đối tượng mới (hoặc một 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ó. Sự kiện này không kích hoạt khi tải lên không thành công.onMetadataUpdated
Gửi khi siêu dữ liệu của một đố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 quản lý phiên bản đối tượng. Sự kiện này cho biết phiên bản trực tiếp của một đối tượng đã trở thành phiên bản lưu trữ, có thể là do đối tượng đó đã được lưu trữ hoặc do đối tượng đó đã bị ghi đè bằng việc tải lên một đối tượng có cùng tên.on_object_deleted
Được gửi khi một đối tượng đã bị xoá vĩnh viễn. Điều này bao gồm các đối tượng bị ghi đè hoặc bị xoá trong cấu hình vòng đời của nhóm. Đối với các vùng chứa đã bật phiên bản đối tượng, thông tin này sẽ không được gửi khi một đối tượng được lưu trữ (xemonArchive
), ngay cả khi quá trình lưu trữ diễn ra thông qua phương thứcstorage.objects.delete
.on_object_finalized
Gửi khi một đối tượng mới (hoặc một 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ó. Sự kiện này không kích hoạt khi tải lên không thành công.on_metadata_updated
Gửi khi siêu dữ liệu của một đối tượng hiện có thay đổi.
Truy cập vào các thuộc tính của đối tượng Cloud Storage
Cloud Functions hiển thị một số thuộc tính đối tượng Cloud Storage, chẳng hạn như kích thước và loại nội dung của đối tượng cho tệp đã cập nhật. Thuộc tính metageneration
sẽ tăng lên mỗi khi 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ị metageneration
là 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
Mẫu tạo hình thu nhỏ sử dụng một số thuộc tính này để 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 tệp lên
Trong một số trường hợp, bạn có thể không cần tải tệp xuống từ Cloud Storage. Tuy nhiên, để thực hiện các tác vụ chuyên sâu như tạo hình thu nhỏ từ mộ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.
Khi 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 tệp hình ảnh đồ hoạ. Sau đây là ví dụ về cách tạo hình thu nhỏ cho một tệp hình ảnh được 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 một thư mục tạm thời trên phiên bản Cloud Functions. Ở vị trí này, bạn có thể xử lý tệp nếu 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 nhớ trả về một lời hứa JavaScript trong lệnh gọi lại của bạn.
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 một hình thu nhỏ 200x200 cho hình ảnh được lưu trong một thư mục tạm thời, sau đó tải hình thu nhỏ đó trở lại Cloud Storage.