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


Cloud Functions से आप इसमें इवेंट मैनेज कर सकते हैं Firebase Realtime Database के लिए क्लाइंट कोड अपडेट करने की ज़रूरत नहीं है. Cloud Functions से आपको पूरे एडमिन के साथ Realtime Database कार्रवाइयां करने की सुविधा मिलती है साथ ही, यह पक्का करता है कि Realtime Database में किया गया हर बदलाव प्रोसेस हो गया है अलग-अलग करें. DataSnapshot या Admin SDK की मदद से, Firebase Realtime Database में बदलाव किए जा सकते हैं.

किसी सामान्य लाइफ़साइकल में, Firebase Realtime Database फ़ंक्शन ये काम करता है:

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

Realtime Database फ़ंक्शन को ट्रिगर करना

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

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

फ़ंक्शन की मदद से, Realtime Database इवेंट को दो लेवल पर मैनेज किया जा सकता है. पहला, सिर्फ़ बनाने, अपडेट करने या मिटाने वाले इवेंट के लिए सुनना. दूसरा, किसी पाथ में हुए किसी भी तरह के बदलाव के लिए सुनना. Cloud Functions, Realtime Database के लिए इन इवेंट हैंडलर के साथ काम करता है:

  • onWrite(), यह तब ट्रिगर होता है, जब Realtime Database में डेटा बनाया जाता है, अपडेट किया जाता है या मिटाया जाता है.
  • onCreate(), जो Realtime Database में नया डेटा बनने पर ट्रिगर होता है.
  • onUpdate(), जो Realtime Database में डेटा के अपडेट होने पर ट्रिगर होता है .
  • onDelete(), यह तब ट्रिगर होता है, जब Realtime Database से डेटा मिटाया जाता है .

इंस्टेंस और पाथ के बारे में बताएं

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

  • डिफ़ॉल्ट Realtime Database इंस्टेंस: functions.database.ref('/foo/bar')
  • "my-app-db-2" नाम का इंस्टेंस: functions.database.instance('my-app-db-2').ref('/foo/bar')

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

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

दोनों ही मामलों में, Firebase यह समझता है कि इवेंट /foo/bar पर होगा, और इवेंट डेटा में /foo/bar पर पुराना और नया डेटा. अगर इवेंट डेटा बड़ा हो सकता है, तो अपने डेटाबेस के रूट के पास एक फ़ंक्शन के बजाय, गहरे पाथ पर कई फ़ंक्शन इस्तेमाल करें. सबसे अच्छी परफ़ॉर्मेंस के लिए, सिर्फ़ अनुरोध करें डेटा को ज़्यादा गहराई से इकट्ठा किया जा सकता है.

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

वाइल्डकार्ड वाले पाथ, एक ही बार लिखे गए कई इवेंट से मैच कर सकते हैं.

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

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

इवेंट डेटा मैनेज करना

Realtime Database इवेंट को मैनेज करते समय, रिटर्न किया गया डेटा ऑब्जेक्ट एक 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/v1');
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 इसके अलावा, इस प्रॉपर्टी की मदद से यह जांच की जा सकती है कि Realtime Database में सेव किए गए डेटा से पहले इवेंट. 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);
    });