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


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

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

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

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

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

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

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

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

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

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

  • डिफ़ॉल्ट रीयलटाइम डेटाबेस उदाहरण: 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);
    });