Cloud Storage में फ़ाइलें और फ़ोल्डर अपलोड, अपडेट या मिटाने पर, किसी फ़ंक्शन को Cloud Storage में ट्रिगर किया जा सकता है.
इस पेज पर दिए गए उदाहरण, एक सैंपल फ़ंक्शन पर आधारित हैं. यह फ़ंक्शन, इमेज फ़ाइलें Cloud Storage पर अपलोड होने पर ट्रिगर होता है. इस सैंपल फ़ंक्शन से पता चलता है कि इवेंट एट्रिब्यूट को कैसे ऐक्सेस किया जाए, Cloud Functions के इंस्टेंस पर कोई फ़ाइल कैसे डाउनलोड की जाए, और Cloud Storage इवेंट को मैनेज करने की अन्य बुनियादी बातें.
ज़रूरी मॉड्यूल इंपोर्ट करना
शुरू करने के लिए, Cloud Storage इवेंट को मैनेज करने के लिए ज़रूरी मॉड्यूल इंपोर्ट करें:
Node.js
const {onObjectFinalized} = require("firebase-functions/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 के किसी खास Cloud Storage बकेट के लिए स्कोप करने और अपनी पसंद के विकल्प सेट करने के लिए, इस पैटर्न का इस्तेमाल करें:
Node.js
// scope handler to a specific bucket, using storage options parameter
exports.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यह सूचना तब भेजी जाती है, जब किसी ऑब्जेक्ट को हमेशा के लिए मिटा दिया जाता है. इसमें वे ऑब्जेक्ट शामिल हैं जो ओवरराइट किए गए हैं या बकेट के लाइफ़साइकल कॉन्फ़िगरेशनके तहत मिटाए गए हैं. जिन बकेट में ऑब्जेक्ट वर्शनिंग की सुविधा चालू है उनके लिए, किसी ऑब्जेक्ट को आर्काइव करने पर यह सूचना नहीं भेजी जाती. भले ही, आर्काइव करने की प्रोसेसstorage.objects.deleteतरीके से की गई हो. ज़्यादा जानकारी के लिए,onArchiveदेखें.onObjectFinalizedयह सूचना तब भेजी जाती है, जब बकेट में कोई नया ऑब्जेक्ट (या किसी मौजूदा ऑब्जेक्ट का नया जनरेशन) बन जाता है. इसमें किसी मौजूदा ऑब्जेक्ट को कॉपी करना या फिर से लिखना शामिल है. अपलोड करने में गड़बड़ी होने पर, यह इवेंट ट्रिगर नहीं होता.onMetadataUpdatedयह सूचना तब भेजी जाती है, जब किसी मौजूदा ऑब्जेक्ट का मेटाडेटा बदलता है.
Python
on_object_archivedयह सूचना सिर्फ़ तब भेजी जाती है, जब किसी बकेट में ऑब्जेक्ट वर्शनिंग की सुविधा चालू हो. इस इवेंट से पता चलता है कि किसी ऑब्जेक्ट का लाइव वर्शन, आर्काइव किया गया वर्शन बन गया है. ऐसा इसलिए हुआ, क्योंकि उसे आर्काइव किया गया था या उसी नाम के किसी ऑब्जेक्ट को अपलोड करने की वजह से, वह ओवरराइट हो गया था.on_object_deletedयह सूचना तब भेजी जाती है, जब किसी ऑब्जेक्ट को हमेशा के लिए मिटा दिया जाता है. इसमें वे ऑब्जेक्ट शामिल हैं जो ओवरराइट किए गए हैं या बकेट के लाइफ़साइकल कॉन्फ़िगरेशनके तहत मिटाए गए हैं. जिन बकेट में ऑब्जेक्ट वर्शनिंग की सुविधा चालू है उनके लिए, किसी ऑब्जेक्ट को आर्काइव करने पर यह सूचना नहीं भेजी जाती. भले ही, आर्काइव करने की प्रोसेसstorage.objects.deleteतरीके से की गई हो. ज़्यादा जानकारी के लिए,onArchiveदेखें.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 का इस्तेमाल, Node.js के लिए
sharp और Python के लिए
Pillow जैसे इमेज-प्रोसेसिंग प्रोग्राम के साथ किया जा सकता है.
इससे, ग्राफ़िकल इमेज फ़ाइलों में
बदलाव किए जा सकते हैं. अपलोड की गई इमेज फ़ाइल के लिए थंबनेल इमेज बनाने का तरीका यहां दिया गया है:
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 पर अपलोड कर दिया जाता है.