אתה יכול להפעיל פונקציה בתגובה להעלאה, עדכון או מחיקה של קבצים ותיקיות ב-Cloud Storage.
דוגמאות בדף זה מבוססות על פונקציה לדוגמה המופעלת כאשר קבצי תמונה מועלים ל-Cloud Storage. פונקציה לדוגמה זו מדגימה כיצד לגשת לתכונות אירוע, כיצד להוריד קובץ למופע של Cloud Functions, ועקרונות יסוד אחרים של טיפול באירועי Cloud Storage.
ייבא את המודולים הדרושים
כדי להתחיל, ייבא את המודול הנדרש לטיפול באירועי Cloud Storage:
Node.js
const {onObjectFinalized} = require("firebase-functions/v2/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 = 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 ולהגדיר את כל האפשרויות הרצויות:
Node.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]):
# ...
לעומת זאת, פונקציית מחולל התמונות הממוזערות לדוגמה מתמקדת בקטגוריית ברירת המחדל של הפרויקט:
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, עליך להוריד קבצים למופע הפונקציות - כלומר, המחשב הוירטואלי שמריץ את הקוד שלך.
באמצעות פונקציות ענן יחד עם תוכנות עיבוד תמונה כמו 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 בהתקשרות חזרה.
פִּיתוֹן
@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.