Catch up on highlights from Firebase at Google I/O 2023. Learn more

रीयलटाइम डेटाबेस ट्रिगर


क्लाउड फ़ंक्शंस के साथ, आप क्लाइंट कोड को अपडेट करने की आवश्यकता के बिना Firebase रीयलटाइम डेटाबेस में ईवेंट प्रबंधित कर सकते हैं। क्लाउड फ़ंक्शंस आपको पूर्ण व्यवस्थापकीय विशेषाधिकारों के साथ रीयलटाइम डेटाबेस संचालन चलाने देता है, और यह सुनिश्चित करता है कि रीयलटाइम डेटाबेस में प्रत्येक परिवर्तन व्यक्तिगत रूप से संसाधित किया जाता है। आप DataSnapshot के माध्यम से या व्यवस्थापक SDK के माध्यम से Firebase रीयलटाइम डेटाबेस परिवर्तन कर सकते हैं।

एक सामान्य जीवनचक्र में, Firebase रीयलटाइम डेटाबेस फ़ंक्शन निम्न कार्य करता है:

  1. किसी विशेष रीयलटाइम डेटाबेस स्थान में परिवर्तन की प्रतीक्षा करता है।
  2. ट्रिगर तब होता है जब कोई घटना होती है और अपने कार्यों को निष्पादित करती है (उपयोग के मामलों के उदाहरणों के लिए मैं क्लाउड फ़ंक्शंस के साथ क्या कर सकता हूं? देखें)।
  3. एक डेटा ऑब्जेक्ट प्राप्त करता है जिसमें निर्दिष्ट दस्तावेज़ में संग्रहीत डेटा का एक स्नैपशॉट होता है।

रीयलटाइम डेटाबेस फ़ंक्शन ट्रिगर करें

functions.database के साथ रीयलटाइम डेटाबेस इवेंट के लिए नए फ़ंक्शन बनाएं। यह नियंत्रित करने के लिए कि फ़ंक्शन कब ट्रिगर होता है, एक ईवेंट हैंडलर निर्दिष्ट करें, और रीयलटाइम डेटाबेस पथ निर्दिष्ट करें जहां यह ईवेंट सुनेगा.

ईवेंट हैंडलर सेट करें

फ़ंक्शंस आपको विशिष्टता के दो स्तरों पर रीयलटाइम डेटाबेस ईवेंट प्रबंधित करने देते हैं; आप विशेष रूप से केवल निर्माण, अद्यतन या हटाने की घटनाओं के लिए सुन सकते हैं, या आप किसी पथ के किसी भी प्रकार के परिवर्तन के लिए सुन सकते हैं। क्लाउड फ़ंक्शंस रीयलटाइम डेटाबेस के लिए इन ईवेंट हैंडलर्स का समर्थन करता है:

  • onWrite() , जो रीयलटाइम डेटाबेस में डेटा के बनने, अपडेट होने या डिलीट होने पर ट्रिगर होता है।
  • onCreate() , जो रीयलटाइम डेटाबेस में नया डेटा बनने पर ट्रिगर होता है।
  • onUpdate() , जो रीयलटाइम डेटाबेस में डेटा अपडेट होने पर ट्रिगर होता है।
  • onDelete() , जो रीयलटाइम डेटाबेस से डेटा हटाए जाने पर ट्रिगर होता है।

उदाहरण और पथ निर्दिष्ट करें

यह नियंत्रित करने के लिए कि आपका फ़ंक्शन कब और कहाँ ट्रिगर होना चाहिए, पथ निर्दिष्ट करने के लिए ref(path) पर कॉल करें, और वैकल्पिक रूप से instance('INSTANCE_NAME') के साथ रीयलटाइम डेटाबेस उदाहरण निर्दिष्ट करें। यदि आप कोई आवृत्ति निर्दिष्ट नहीं करते हैं, तो फ़ंक्शन Firebase प्रोजेक्ट के लिए डिफ़ॉल्ट रीयलटाइम डेटाबेस आवृत्ति पर लागू होता है, उदाहरण के लिए:

  • डिफ़ॉल्ट रीयलटाइम डेटाबेस उदाहरण: functions.database.ref('/foo/bar')
  • उदाहरण का नाम "my-app-db-2": functions.database.instance('my-app-db-2').ref('/foo/bar')

ये विधियाँ आपके फ़ंक्शन को रीयलटाइम डेटाबेस उदाहरण के भीतर एक निश्चित पथ पर लिखने के लिए निर्देशित करती हैं। पथ विनिर्देश उन सभी लेखनों से मेल खाते हैं जो किसी पथ को छूते हैं, इसमें वे लेखन भी शामिल हैं जो इसके नीचे कहीं भी होते हैं। यदि आप अपने फ़ंक्शन के लिए /foo/bar के रूप में पथ सेट करते हैं, तो यह इन दोनों स्थानों पर ईवेंट से मेल खाता है:

 /foo/bar
 /foo/bar/baz/really/deep/path

किसी भी मामले में, फायरबेस व्याख्या करता है कि घटना /foo/bar पर होती है, और घटना डेटा में /foo/bar पर पुराना और नया डेटा शामिल होता है। यदि ईवेंट डेटा बड़ा हो सकता है, तो अपने डेटाबेस के रूट के पास एकल फ़ंक्शन के बजाय गहरे पथ पर एकाधिक फ़ंक्शन का उपयोग करने पर विचार करें। सर्वोत्तम प्रदर्शन के लिए, केवल सबसे गहरे स्तर पर डेटा का अनुरोध करें।

आप किसी पथ घटक को घुमावदार कोष्ठकों से घेरकर उसे वाइल्डकार्ड के रूप में निर्दिष्ट कर सकते हैं; ref('foo/{bar}') /foo के किसी भी बच्चे से मेल खाता है। इन वाइल्डकार्ड पथ घटकों के मान आपके फ़ंक्शन के EventContext.params ऑब्जेक्ट में उपलब्ध हैं। इस उदाहरण में, मान context.params.bar के रूप में उपलब्ध है।

वाइल्डकार्ड वाले पथ एक ही लेखन से कई घटनाओं का मिलान कर सकते हैं। का एक आवेषण

{
  "foo": {
    "hello": "world",
    "firebase": "functions"
  }
}

पथ "/foo/{bar}" दो बार मेल खाता है: एक बार "hello": "world" के साथ और फिर "firebase": "functions" के साथ।

ईवेंट डेटा को संभालें

रीयलटाइम डेटाबेस ईवेंट को हैंडल करते समय, लौटाया गया डेटा ऑब्जेक्ट DataSnapshot है। onWrite या onUpdate ईवेंट के लिए, पहला पैरामीटर एक Change ऑब्जेक्ट है जिसमें दो स्नैपशॉट होते हैं जो ट्रिगरिंग इवेंट से पहले और बाद में डेटा स्थिति का प्रतिनिधित्व करते हैं। onCreate और onDelete ईवेंट के लिए, लौटाया गया डेटा ऑब्जेक्ट निर्मित या हटाए गए डेटा का एक स्नैपशॉट है।

इस उदाहरण में, फ़ंक्शन निर्दिष्ट पथ के लिए स्नैपशॉट को पुनर्प्राप्त करता है, उस स्थान पर स्ट्रिंग को अपरकेस में कनवर्ट करता है, और उस संशोधित स्ट्रिंग को डेटाबेस में लिखता है:

// Listens for new messages added to /messages/:pushId/original and creates an
// uppercase version of the message to /messages/:pushId/uppercase
exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
    .onCreate((snapshot, context) => {
      // Grab the current value of what was written to the Realtime Database.
      const original = snapshot.val();
      functions.logger.log('Uppercasing', context.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 snapshot.ref.parent.child('uppercase').set(uppercase);
    });

उपयोगकर्ता प्रमाणीकरण जानकारी तक पहुँचना

EventContext.auth और EventContext.authType से, आप किसी फ़ंक्शन को ट्रिगर करने वाले उपयोगकर्ता के लिए अनुमतियों सहित उपयोगकर्ता जानकारी तक पहुंच सकते हैं। यह सुरक्षा नियमों को लागू करने के लिए उपयोगी हो सकता है, जिससे आपके फ़ंक्शन को उपयोगकर्ता के स्तर की अनुमति के आधार पर विभिन्न कार्यों को पूरा करने की अनुमति मिलती है:

const functions = require('firebase-functions');
const admin = require('firebase-admin');

exports.simpleDbFunction = functions.database.ref('/path')
    .onCreate((snap, context) => {
      if (context.authType === 'ADMIN') {
        // do something
      } else if (context.authType === 'USER') {
        console.log(snap.val(), 'written by', context.auth.uid);
      }
    });

साथ ही, आप किसी उपयोगकर्ता को "प्रतिरूपण" करने के लिए उपयोगकर्ता प्रमाणीकरण जानकारी का लाभ उठा सकते हैं और उपयोगकर्ता की ओर से लेखन कार्य कर सकते हैं। समवर्ती मुद्दों को रोकने के लिए नीचे दिखाए गए ऐप इंस्टेंस को हटाना सुनिश्चित करें:

exports.impersonateMakeUpperCase = functions.database.ref('/messages/{pushId}/original')
    .onCreate((snap, context) => {
      const appOptions = JSON.parse(process.env.FIREBASE_CONFIG);
      appOptions.databaseAuthVariableOverride = context.auth;
      const app = admin.initializeApp(appOptions, 'app');
      const uppercase = snap.val().toUpperCase();
      const ref = snap.ref.parent.child('uppercase');

      const deleteApp = () => app.delete().catch(() => null);

      return app.database().ref(ref).set(uppercase).then(res => {
        // Deleting the app is necessary for preventing concurrency leaks
        return deleteApp().then(() => res);
      }).catch(err => {
        return deleteApp().then(() => Promise.reject(err));
      });
    });

पिछला मान पढ़ना

Change ऑब्जेक्ट में एक before प्रॉपर्टी है जो आपको यह जांचने देती है कि इवेंट से पहले रियलटाइम डेटाबेस में क्या सेव किया गया था। before संपत्ति एक DataSnapshot लौटाती है जहां सभी विधियां (उदाहरण के लिए, val() और exists() ) पिछले मान को संदर्भित करती हैं। आप मूल DataSnapshot उपयोग करके या after संपत्ति को पढ़कर नए मान को फिर से पढ़ सकते हैं। किसी भी Change पर यह गुण एक अन्य DataSnapshot है जो घटना घटित होने के बाद डेटा की स्थिति का प्रतिनिधित्व करता है।

उदाहरण के लिए, before संपत्ति का उपयोग यह सुनिश्चित करने के लिए किया जा सकता है कि जब यह पहली बार बनाया गया हो तो फ़ंक्शन केवल टेक्स्ट को अपरकेस करता है:

exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
    .onWrite((change, context) => {
      // Only edit data when it is first created.
      if (change.before.exists()) {
        return null;
      }
      // Exit when the data is deleted.
      if (!change.after.exists()) {
        return null;
      }
      // Grab the current value of what was written to the Realtime Database.
      const original = change.after.val();
      console.log('Uppercasing', context.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 change.after.ref.parent.child('uppercase').set(uppercase);
    });