Cloud Functions की मदद से, Firebase Realtime Database में इवेंट मैनेज किए जा सकते हैं. इसके लिए, क्लाइंट कोड को अपडेट करने की ज़रूरत नहीं होती. Cloud Functions की मदद से, Realtime Database के सभी ऑपरेशन एडमिन के सभी ऐक्सेस के साथ चलाए जा सकते हैं. साथ ही, यह पक्का किया जा सकता है कि Realtime Database में किए गए हर बदलाव को अलग से प्रोसेस किया जाए. डेटा स्नैपशॉट या Admin SDK की मदद से, Firebase Realtime Database में बदलाव किए जा सकते हैं.
आम तौर पर, लाइफ़साइकल में Firebase Realtime Database फ़ंक्शन ये काम करता है:
- किसी खास Realtime Database पाथ में बदलाव होने का इंतज़ार करता है.
- कोई इवेंट होने पर ट्रिगर होता है और अपने टास्क पूरा करता है.
- इसमें एक डेटा ऑब्जेक्ट मिलता है, जिसमें उस पाथ पर सेव किए गए डेटा का स्नैपशॉट होता है.
Firebase Realtime Database में डेटाबेस नोड लिखने, बनाने, अपडेट करने या मिटाने के जवाब में, कोई फ़ंक्शन ट्रिगर किया जा सकता है. फ़ंक्शन कब ट्रिगर होगा, यह कंट्रोल करने के लिए, कोई एक इवेंट हैंडलर तय करें. साथ ही, वह Realtime Database पाथ भी तय करें जहां वह इवेंट के लिए सुनेगा.
फ़ंक्शन की जगह सेट करना
Realtime Database इंस्टेंस की जगह और फ़ंक्शन की जगह के बीच की दूरी की वजह से, नेटवर्क में देरी हो सकती है. इसके अलावा, क्षेत्रों के बीच मेल न खाने की वजह से, डिप्लॉयमेंट पूरा नहीं हो सकता. इन स्थितियों से बचने के लिए, फ़ंक्शन की जगह की जानकारी दें, ताकि वह डेटाबेस इंस्टेंस की जगह से मेल खा सके.
Realtime Database इवेंट मैनेज करना
फ़ंक्शन की मदद से, Realtime Database इवेंट को दो लेवल पर मैनेज किया जा सकता है. पहला, सिर्फ़ लिखने, बनाने, अपडेट करने या मिटाने वाले इवेंट के लिए सुनना. दूसरा, किसी रेफ़रंस में हुए किसी भी तरह के बदलाव के लिए सुनना.
Realtime Database इवेंट के जवाब देने के लिए, ये हैंडलर उपलब्ध हैं:
onValueWritten()
Realtime Database में डेटा बनाने, अपडेट करने या मिटाने पर ट्रिगर होता है.onValueCreated()
सिर्फ़ तब ट्रिगर होता है, जब Realtime Database में डेटा बनाया जाता है.onValueUpdated()
सिर्फ़ तब ट्रिगर होता है, जब Realtime Database में डेटा अपडेट किया जाता है.onValueDeleted()
सिर्फ़ तब ट्रिगर होता है, जब Realtime Database में डेटा मिटाया जाता है.
on_value_written()
Realtime Database में डेटा बनाने, अपडेट करने या मिटाने पर ट्रिगर होता है.on_value_created()
सिर्फ़ तब ट्रिगर होता है, जब Realtime Database में डेटा बनाया जाता है.on_value_updated()
सिर्फ़ तब ट्रिगर होता है, जब Realtime Database में डेटा अपडेट किया जाता है.on_value_deleted()
सिर्फ़ तब ट्रिगर होता है, जब Realtime Database में डेटा मिटाया जाता है.
ज़रूरी मॉड्यूल इंपोर्ट करना
आपको अपने फ़ंक्शन सोर्स में, उन SDK टूल के मॉड्यूल इंपोर्ट करने होंगे जिनका इस्तेमाल करना है. इस सैंपल के लिए, Realtime Database में लिखने के लिए, Firebase Admin SDK मॉड्यूल के साथ-साथ एचटीटीपी और Realtime Database मॉड्यूल इंपोर्ट करना ज़रूरी है.
// The Cloud Functions for Firebase SDK to setup triggers and logging.
const {onRequest} = require("firebase-functions/v2/https");
const {onValueCreated} = require("firebase-functions/v2/database");
const {logger} = require("firebase-functions");
// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require("firebase-admin");
admin.initializeApp();
# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import db_fn, https_fn
# The Firebase Admin SDK to access the Firebase Realtime Database.
from firebase_admin import initialize_app, db
app = initialize_app()
इंस्टेंस और पाथ की जानकारी देना
यह कंट्रोल करने के लिए कि आपका फ़ंक्शन कब और कहां ट्रिगर होना चाहिए, अपने फ़ंक्शन को किसी पाथ और Realtime Database इंस्टेंस के साथ कॉन्फ़िगर करें. अगर आपने कोई इंस्टेंस नहीं बताया है, तो फ़ंक्शन, फ़ंक्शन क्षेत्र में मौजूद सभी Realtime Database इंस्टेंस को सुनता है. एक ही क्षेत्र के इंस्टेंस के चुनिंदा सबसेट में डिप्लॉय करने के लिए, Realtime Database इंस्टेंस पैटर्न भी तय किया जा सकता है.
उदाहरण के लिए:
// All Realtime Database instances in default function region us-central1 at path "/user/{uid}" // There must be at least one Realtime Database present in us-central1. const onWrittenFunctionDefault = onValueWritten("/user/{uid}", (event) => { // … }); // Instance named "my-app-db-2", at path "/user/{uid}". // The "my-app-db-2" instance must exist in this region. const OnWrittenFunctionInstance = onValueWritten( { ref: "/user/{uid}", instance: "my-app-db-2" // This example assumes us-central1, but to set location: // region: "europe-west1" }, (event) => { // … } ); // Instance with "my-app-db-" prefix, at path "/user/{uid}", where uid ends with @gmail.com. // There must be at least one Realtime Database with "my-app-db-*" prefix in this region. const onWrittenFunctionInstance = onValueWritten( { ref: "/user/{uid=*@gmail.com}", instance: "my-app-db-*" // This example assumes us-central1, but to set location: // region: "europe-west1" }, (event) => { // … } );
# All Realtime Database instances in default function region us-central1 at path "/user/{uid}"
# There must be at least one Realtime Database present in us-central1.
@db_fn.on_value_written(r"/user/{uid}")
def onwrittenfunctiondefault(event: db_fn.Event[db_fn.Change]):
# ...
pass
# Instance named "my-app-db-2", at path "/user/{uid}".
# The "my-app-db-2" instance must exist in this region.
@db_fn.on_value_written(
reference=r"/user/{uid}",
instance="my-app-db-2",
# This example assumes us-central1, but to set location:
# region="europe-west1",
)
def on_written_function_instance(event: db_fn.Event[db_fn.Change]):
# ...
pass
# Instance with "my-app-db-" prefix, at path "/user/{uid}", where uid ends with @gmail.com.
# There must be at least one Realtime Database with "my-app-db-*" prefix in this region.
@db_fn.on_value_written(
reference=r"/user/{uid=*@gmail.com}",
instance="my-app-db-*",
# This example assumes us-central1, but to set location:
# region="europe-west1",
)
def on_written_function_instance(event: db_fn.Event[db_fn.Change]):
# ...
pass
ये पैरामीटर आपके फ़ंक्शन को Realtime Database इंस्टेंस में किसी खास पाथ पर लिखने की सुविधा देते हैं.
पाथ की जानकारी, किसी पाथ से जुड़ी सभी लिखी गई चीज़ों से मेल खाती है. इनमें, उस पाथ के नीचे कहीं भी लिखी गई चीज़ें भी शामिल हैं. अगर आपने अपने फ़ंक्शन के लिए पाथ को /foo/bar
के तौर पर सेट किया है, तो यह इन दोनों जगहों पर मौजूद इवेंट से मैच करता है:
/foo/bar
/foo/bar/baz/really/deep/path
दोनों ही मामलों में, Firebase यह समझता है कि इवेंट /foo/bar
पर होता है और इवेंट डेटा में /foo/bar
पर मौजूद पुराना और नया डेटा शामिल होता है. अगर इवेंट का डेटा बड़ा हो सकता है, तो अपने डेटाबेस के रूट के पास एक फ़ंक्शन के बजाय, गहरे पाथ पर कई फ़ंक्शन इस्तेमाल करें. सबसे अच्छी परफ़ॉर्मेंस के लिए, सिर्फ़ ज़्यादा से ज़्यादा जानकारी का अनुरोध करें.
वाइल्डकार्ड और कैप्चर
स्क्रीनशॉट लेने के लिए, {key}
, {key=*}
, {key=prefix*}
, {key=*suffix}
का इस्तेमाल किया जा सकता है. सिंगल-सेगमेंट वाइल्डकार्ड के लिए *
, prefix*
, *suffix
.
ध्यान दें: **
, एक से ज़्यादा सेगमेंट वाले वाइल्डकार्ड का इस्तेमाल करता है. यह सुविधा Realtime Database में उपलब्ध नहीं है.
पाथ पैटर्न को समझना लेख पढ़ें.
पाथ वाइल्डकार्डिंग. पाथ के किसी कॉम्पोनेंट को वाइल्डकार्ड के तौर पर सेट किया जा सकता है:
- तारे के निशान,
*
का इस्तेमाल करके. उदाहरण के लिए,foo/*
,foo/
के नीचे मौजूद नोड के लेआउट के एक लेवल के सभी चाइल्ड से मैच करता है. - ऐसे सेगमेंट का इस्तेमाल करना जिसमें ऐस्टरिस्क,
*
शामिल हो. उदाहरण के लिए,foo/app*-us
foo/
के नीचे मौजूद किसी भी चाइल्ड सेगमेंट से मेल खाता है. इसमेंapp
प्रीफ़िक्स और-us
सफ़िक्स शामिल हैं.
वाइल्डकार्ड वाले पाथ, एक ही लिखने की कार्रवाई से होने वाले कई इवेंट से मैच कर सकते हैं.
{
"foo": {
"hello": "world",
"firebase": "functions"
}
}
पाथ "/foo/*"
से दो बार मैच करता है: एक बार "hello": "world"
और फिर "firebase": "functions"
के साथ.
पाथ कैप्चर करना. पाथ मैच को नाम वाले वैरिएबल में कैप्चर किया जा सकता है, ताकि उनका इस्तेमाल आपके फ़ंक्शन कोड (उदाहरण के लिए, /user/{uid}
, /user/{uid=*-us}
) में किया जा सके.
कैप्चर वैरिएबल की वैल्यू, आपके फ़ंक्शन के database.DatabaseEvent.params ऑब्जेक्ट में उपलब्ध होती हैं.
इंस्टेंस वाइल्डकार्डिंग. वाइल्डकार्ड का इस्तेमाल करके भी इंस्टेंस कॉम्पोनेंट तय किया जा सकता है. किसी इंस्टेंस वाइल्डकार्ड में प्रीफ़िक्स, सफ़िक्स या दोनों हो सकते हैं (उदाहरण के लिए, my-app-*-prod
).
वाइल्डकार्ड और कैप्चर रेफ़रंस
Cloud Functions (2nd gen) और Realtime Database के साथ, ref
और instance
की जानकारी देते समय पैटर्न का इस्तेमाल किया जा सकता है. हर ट्रिगर इंटरफ़ेस में, फ़ंक्शन के स्कोप के लिए ये विकल्प होंगे:
ref की जानकारी देना |
instance की जानकारी देना |
व्यवहार |
---|---|---|
सिंगल (/foo/bar ) |
जानकारी नहीं दी गई | फ़ंक्शन क्षेत्र के सभी इंस्टेंस के लिए हैंडलर को स्कोप करता है. |
सिंगल (/foo/bar ) |
सिंगल (‘my-new-db' ) |
फ़ंक्शन क्षेत्र में किसी खास इंस्टेंस के लिए हैंडलर को स्कोप करता है. |
सिंगल (/foo/bar ) |
पैटर्न (‘inst-prefix*' ) |
फ़ंक्शन क्षेत्र में पैटर्न से मैच करने वाले सभी इंस्टेंस पर हैंडल को स्कोप करता है. |
पैटर्न (/foo/{bar} ) |
जानकारी नहीं दी गई | फ़ंक्शन क्षेत्र के सभी इंस्टेंस के लिए हैंडलर को स्कोप करता है. |
पैटर्न (/foo/{bar} ) |
सिंगल (‘my-new-db' ) |
फ़ंक्शन क्षेत्र में किसी खास इंस्टेंस के लिए हैंडलर को स्कोप करता है. |
पैटर्न (/foo/{bar} ) |
पैटर्न (‘inst-prefix*' ) |
फ़ंक्शन क्षेत्र में पैटर्न से मैच करने वाले सभी इंस्टेंस पर हैंडल को स्कोप करता है. |
इवेंट डेटा मैनेज करना
जब कोई Realtime Database इवेंट ट्रिगर होता है, तो वह आपके हैंडलर फ़ंक्शन को Event
ऑब्जेक्ट पास करता है.
इस ऑब्जेक्ट में एक data
प्रॉपर्टी होती है. इसमें डेटा बनाने और मिटाने के इवेंट के लिए, बनाए गए या मिटाए गए डेटा का स्नैपशॉट होता है.
इस उदाहरण में, फ़ंक्शन रेफ़रंस किए गए पाथ का डेटा वापस लाता है. साथ ही, उस जगह की स्ट्रिंग को अपरकेस में बदलता है और बदली गई स्ट्रिंग को डेटाबेस में लिखता है:
// Listens for new messages added to /messages/:pushId/original and creates an
// uppercase version of the message to /messages/:pushId/uppercase
// for all databases in 'us-central1'
exports.makeuppercase = onValueCreated(
"/messages/{pushId}/original",
(event) => {
// Grab the current value of what was written to the Realtime Database.
const original = event.data.val();
logger.log("Uppercasing", event.params.pushId, original);
const uppercase = original.toUpperCase();
// You must return a Promise when performing
// asynchronous tasks inside a function, such as
// writing to the Firebase Realtime Database.
// Setting an "uppercase" sibling in the
// Realtime Database returns a Promise.
return event.data.ref.parent.child("uppercase").set(uppercase);
},
);
@db_fn.on_value_created(reference="/messages/{pushId}/original")
def makeuppercase(event: db_fn.Event[Any]) -> None:
"""Listens for new messages added to /messages/{pushId}/original and
creates an uppercase version of the message to /messages/{pushId}/uppercase
"""
# Grab the value that was written to the Realtime Database.
original = event.data
if not isinstance(original, str):
print(f"Not a string: {event.reference}")
return
# Use the Admin SDK to set an "uppercase" sibling.
print(f"Uppercasing {event.params['pushId']}: {original}")
upper = original.upper()
parent = db.reference(event.reference).parent
if parent is None:
print("Message can't be root node.")
return
parent.child("uppercase").set(upper)
पिछली वैल्यू पढ़ना
write
या update
इवेंट के लिए, data
प्रॉपर्टी एक Change
ऑब्जेक्ट है. इसमें दो स्नैपशॉट होते हैं, जो इवेंट ट्रिगर होने से पहले और बाद की डेटा स्थिति दिखाते हैं.
Change
ऑब्जेक्ट में एक before
प्रॉपर्टी होती है. इससे यह पता लगाया जा सकता है कि इवेंट के पहले Realtime Database में क्या सेव किया गया था. साथ ही, after
प्रॉपर्टी से यह पता चलता है कि इवेंट के बाद डेटा की स्थिति क्या है.
उदाहरण के लिए, before
प्रॉपर्टी का इस्तेमाल करके यह पक्का किया जा सकता है कि फ़ंक्शन, पहली बार बनाने पर ही टेक्स्ट को अपरकेस में बदले:
exports makeUppercase = onValueWritten("/messages/{pushId}/original", (event) => { // Only edit data when it is first created. if (event.data.before.exists()) { return null; } // Exit when the data is deleted. if (!event.data.after.exists()) { return null; } // Grab the current value of what was written to the Realtime Database. const original = event.data.after.val(); console.log('Uppercasing', event.params.pushId, original); const uppercase = original.toUpperCase(); // You must return a Promise when performing asynchronous tasks inside a Functions such as // writing to the Firebase Realtime Database. // Setting an "uppercase" sibling in the Realtime Database returns a Promise. return event.data.after.ref.parent.child('uppercase').set(uppercase); });
@db_fn.on_value_written(reference="/messages/{pushId}/original")
def makeuppercase2(event: db_fn.Event[db_fn.Change]) -> None:
"""Listens for new messages added to /messages/{pushId}/original and
creates an uppercase version of the message to /messages/{pushId}/uppercase
"""
# Only edit data when it is first created.
if event.data.before is not None:
return
# Exit when the data is deleted.
if event.data.after is None:
return
# Grab the value that was written to the Realtime Database.
original = event.data.after
if not hasattr(original, "upper"):
print(f"Not a string: {event.reference}")
return
# Use the Admin SDK to set an "uppercase" sibling.
print(f"Uppercasing {event.params['pushId']}: {original}")
upper = original.upper()
parent = db.reference(event.reference).parent
if parent is None:
print("Message can't be root node.")
return
parent.child("uppercase").set(upper)