Cloud Firestore के ट्रिगर


Cloud Functions की मदद से, आप Cloud Firestore में इवेंट मैनेज कर सकते हैं. इसके लिए क्लाइंट कोड को अपडेट करने की ज़रूरत नहीं है. दस्तावेज़ स्नैपशॉट इंटरफ़ेस या एडमिन SDK से Cloud Firestore में बदलाव किए जा सकते हैं.

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

  1. किसी खास दस्तावेज़ में बदलाव होने का इंतज़ार करता है.
  2. तब ट्रिगर होता है, जब कोई इवेंट होता है और अपने टास्क करता है.
  3. ऐसा डेटा ऑब्जेक्ट हासिल करता है जिसमें बताए गए दस्तावेज़ में स्टोर किए गए डेटा का स्नैपशॉट होता है. इवेंट लिखने या अपडेट करने के लिए, डेटा ऑब्जेक्ट में दो स्नैपशॉट होते हैं. ये स्नैपशॉट, ट्रिगर किए जाने वाले इवेंट से पहले और बाद की डेटा स्थिति को दिखाते हैं.

Firestore इंस्टेंस की लोकेशन और फ़ंक्शन की जगह के बीच की दूरी, नेटवर्क के लिए इंतज़ार का समय तय कर सकती है. परफ़ॉर्मेंस को ऑप्टिमाइज़ करने के लिए, जहां ज़रूरी हो वहां फ़ंक्शन की जगह की जानकारी दें.

Cloud Firestore फ़ंक्शन ट्रिगर

'Firebase के लिए Cloud Functions', functions.firestore ऑब्जेक्ट को एक्सपोर्ट करता है. इसकी मदद से, खास Cloud Firestore इवेंट से जुड़े हैंडलर बनाए जा सकते हैं.

इवेंट टाइप ट्रिगर
onCreate तब ट्रिगर होता है, जब किसी दस्तावेज़ को पहली बार लिखा जाता है.
onUpdate तब ट्रिगर होता है, जब कोई दस्तावेज़ पहले से मौजूद होता है और उसकी वैल्यू में बदलाव होता है.
onDelete तब ट्रिगर होता है, जब डेटा वाला दस्तावेज़ मिटा दिया जाता है.
onWrite onCreate, onUpdate या onDelete ट्रिगर होने पर ट्रिगर होता है.

अगर आपने अभी तक किसी प्रोजेक्ट को 'Firebase के लिए Cloud Functions' के लिए चालू नहीं किया है, तो 'Firebase के लिए Cloud Functions' प्रोजेक्ट को कॉन्फ़िगर और सेट अप करने के लिए, शुरू करें: अपने पहले फ़ंक्शन लिखें और उन्हें डिप्लॉय करें लेख पढ़ें.

Cloud Firestore से ट्रिगर किए गए फ़ंक्शन लिखना

फ़ंक्शन ट्रिगर तय करें

Cloud Firestore ट्रिगर तय करने के लिए, दस्तावेज़ का पाथ और इवेंट टाइप तय करें:

Node.js

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

exports.myFunction = functions.firestore
  .document('my-collection/{docId}')
  .onWrite((change, context) => { /* ... */ });

दस्तावेज़ के पाथ में, किसी खास दस्तावेज़ या वाइल्डकार्ड पैटर्न का रेफ़रंस दिया जा सकता है.

किसी एक दस्तावेज़ के बारे में बताएं

अगर किसी दस्तावेज़ में किसी भी बदलाव के लिए इवेंट ट्रिगर करना है, तो इस फ़ंक्शन का इस्तेमाल करें.

Node.js

// Listen for any change on document `marie` in collection `users`
exports.myFunctionName = functions.firestore
    .document('users/marie').onWrite((change, context) => {
      // ... Your code here
    });

वाइल्डकार्ड का इस्तेमाल करके दस्तावेज़ों का एक ग्रुप तय करें

अगर आपको दस्तावेज़ों के ग्रुप में ट्रिगर अटैच करना है, जैसे कि किसी कलेक्शन में मौजूद कोई दस्तावेज़, तो दस्तावेज़ आईडी की जगह {wildcard} का इस्तेमाल करें:

Node.js

// Listen for changes in all documents in the 'users' collection
exports.useWildcard = functions.firestore
    .document('users/{userId}')
    .onWrite((change, context) => {
      // If we set `/users/marie` to {name: "Marie"} then
      // context.params.userId == "marie"
      // ... and ...
      // change.after.data() == {name: "Marie"}
    });

इस उदाहरण में, जब users में किसी भी दस्तावेज़ के किसी फ़ील्ड में बदलाव किया जाता है, तो वह userId नाम के वाइल्डकार्ड से मेल खाता है.

अगर users के किसी दस्तावेज़ में सब-कलेक्शन हैं और उन सब-कलेक्शन के दस्तावेज़ों में से किसी एक फ़ील्ड में बदलाव होता है, तो userId वाइल्डकार्ड नहीं ट्रिगर होता है.

वाइल्डकार्ड से मेल खाने वाले नतीजे, दस्तावेज़ के पाथ से लिए जाते हैं और context.params में सेव किए जाते हैं. अश्लील कलेक्शन या दस्तावेज़ के आईडी को बदलने के लिए, जितने चाहें उतने वाइल्डकार्ड तय किए जा सकते हैं, उदाहरण के लिए:

Node.js

// Listen for changes in all documents in the 'users' collection and all subcollections
exports.useMultipleWildcards = functions.firestore
    .document('users/{userId}/{messageCollectionId}/{messageId}')
    .onWrite((change, context) => {
      // If we set `/users/marie/incoming_messages/134` to {body: "Hello"} then
      // context.params.userId == "marie";
      // context.params.messageCollectionId == "incoming_messages";
      // context.params.messageId == "134";
      // ... and ...
      // change.after.data() == {body: "Hello"}
    });

इवेंट ट्रिगर

नया दस्तावेज़ बनाने के बाद फ़ंक्शन को ट्रिगर करना

जब भी किसी कलेक्शन में कोई नया दस्तावेज़ बनाया जाता है, तब उसे ट्रिगर करने के लिए फ़ंक्शन को ट्रिगर किया जा सकता है. इसके लिए, वाइल्डकार्ड के साथ onCreate() हैंडलर का इस्तेमाल करें. उदाहरण के तौर पर दिया गया यह फ़ंक्शन, हर बार नई उपयोगकर्ता प्रोफ़ाइल जोड़ने पर createUser को कॉल करता है:

Node.js

exports.createUser = functions.firestore
    .document('users/{userId}')
    .onCreate((snap, context) => {
      // Get an object representing the document
      // e.g. {'name': 'Marie', 'age': 66}
      const newValue = snap.data();

      // access a particular field as you would any JS property
      const name = newValue.name;

      // perform desired operations ...
    });

दस्तावेज़ अपडेट होने पर फ़ंक्शन ट्रिगर करना

वाइल्डकार्ड के साथ onUpdate() फ़ंक्शन का इस्तेमाल करके दस्तावेज़ अपडेट किए जाने पर, किसी फ़ंक्शन को फ़ायर करने के लिए भी ट्रिगर किया जा सकता है. यह उदाहरण, फ़ंक्शन updateUser को तब कॉल करता है, जब कोई उपयोगकर्ता अपनी प्रोफ़ाइल बदलता है:

Node.js

exports.updateUser = functions.firestore
    .document('users/{userId}')
    .onUpdate((change, context) => {
      // Get an object representing the document
      // e.g. {'name': 'Marie', 'age': 66}
      const newValue = change.after.data();

      // ...or the previous value before this update
      const previousValue = change.before.data();

      // access a particular field as you would any JS property
      const name = newValue.name;

      // perform desired operations ...
    });

दस्तावेज़ मिटाए जाने पर फ़ंक्शन ट्रिगर करना

वाइल्डकार्ड के साथ onDelete() फ़ंक्शन का इस्तेमाल करके, दस्तावेज़ मिटाए जाने पर भी फ़ंक्शन ट्रिगर किया जा सकता है. यह उदाहरण जब कोई उपयोगकर्ता अपनी उपयोगकर्ता प्रोफ़ाइल मिटा देता है, तो उसे deleteUser कॉल किया जाता है:

Node.js

exports.deleteUser = functions.firestore
    .document('users/{userID}')
    .onDelete((snap, context) => {
      // Get an object representing the document prior to deletion
      // e.g. {'name': 'Marie', 'age': 66}
      const deletedValue = snap.data();

      // perform desired operations ...
    });

दस्तावेज़ में सभी बदलावों के लिए फ़ंक्शन ट्रिगर करना

अगर आपको इवेंट के टाइप से ज़्यादा फ़र्क़ नहीं पड़ता है, तो वाइल्डकार्ड के साथ onWrite() फ़ंक्शन का इस्तेमाल करके, Cloud Firestore दस्तावेज़ में हुए सभी बदलावों को सुना जा सकता है. इस उदाहरण में, modifyUser को तब कॉल किया जाता है, जब कोई उपयोगकर्ता बनाया जाता है, अपडेट किया जाता है या मिटाया जाता है:

Node.js

exports.modifyUser = functions.firestore
    .document('users/{userID}')
    .onWrite((change, context) => {
      // Get an object with the current document value.
      // If the document does not exist, it has been deleted.
      const document = change.after.exists ? change.after.data() : null;

      // Get an object with the previous document value (for update or delete)
      const oldDocument = change.before.data();

      // perform desired operations ...
    });

डेटा पढ़ना और लिखना

जब कोई फ़ंक्शन ट्रिगर होता है, तो यह इवेंट से जुड़े डेटा का स्नैपशॉट देता है. इस स्नैपशॉट का इस्तेमाल, इवेंट को ट्रिगर करने वाले दस्तावेज़ को पढ़ने या उसमें बदलाव करने के लिए किया जा सकता है. इसके अलावा, अपने डेटाबेस के अन्य हिस्सों को ऐक्सेस करने के लिए, Firebase एडमिन SDK का इस्तेमाल किया जा सकता है.

इवेंट का डेटा

रीडिंग डेटा

जब कोई फ़ंक्शन ट्रिगर होता है, तब हो सकता है कि आप अपडेट किए गए दस्तावेज़ से डेटा लेना चाहें या अपडेट से पहले डेटा लेना चाहें. change.before.data() का इस्तेमाल करके, पिछला डेटा पाया जा सकता है. इसमें अपडेट से पहले का दस्तावेज़ का स्नैपशॉट होता है. इसी तरह, change.after.data() में अपडेट के बाद दस्तावेज़ के स्नैपशॉट की स्थिति शामिल होती है.

Node.js

exports.updateUser2 = functions.firestore
    .document('users/{userId}')
    .onUpdate((change, context) => {
      // Get an object representing the current document
      const newValue = change.after.data();

      // ...or the previous value before this update
      const previousValue = change.before.data();
    });

किसी दूसरे ऑब्जेक्ट की तरह ही, प्रॉपर्टी को भी ऐक्सेस किया जा सकता है. इसके अलावा, खास फ़ील्ड को ऐक्सेस करने के लिए get फ़ंक्शन का इस्तेमाल किया जा सकता है:

Node.js

// Fetch data using standard accessors
const age = snap.data().age;
const name = snap.data()['name'];

// Fetch data using built in accessor
const experience = snap.get('experience');

डेटा लिखना

हर फ़ंक्शन को शुरू करने पर, आपके Cloud Firestore डेटाबेस में एक खास दस्तावेज़ जुड़ा होता है. आपके पास उस दस्तावेज़ को, फ़ंक्शन में दिखाए गए स्नैपशॉट की ref प्रॉपर्टी में, DocumentReference के तौर पर ऐक्सेस करने का विकल्प है.

यह DocumentReference, Cloud Firestore Node.js SDK टूल से लिया गया है. इसमें update(), set(), और remove() जैसे तरीके शामिल हैं, ताकि फ़ंक्शन को ट्रिगर करने वाले दस्तावेज़ में आसानी से बदलाव किया जा सके.

Node.js

// Listen for updates to any `user` document.
exports.countNameChanges = functions.firestore
    .document('users/{userId}')
    .onUpdate((change, context) => {
      // Retrieve the current and previous value
      const data = change.after.data();
      const previousData = change.before.data();

      // We'll only update if the name has changed.
      // This is crucial to prevent infinite loops.
      if (data.name == previousData.name) {
        return null;
      }

      // Retrieve the current count of name changes
      let count = data.name_change_count;
      if (!count) {
        count = 0;
      }

      // Then return a promise of a set operation to update the count
      return change.after.ref.set({
        name_change_count: count + 1
      }, {merge: true});
    });

वह डेटा जो ट्रिगर इवेंट से बाहर का है

Cloud फ़ंक्शन, भरोसेमंद एनवायरमेंट में काम करते हैं. इसका मतलब है कि उन्हें आपके प्रोजेक्ट पर सेवा खाते के तौर पर अनुमति मिली हुई है. Firebase एडमिन SDK टूल का इस्तेमाल करके पढ़ने और लिखने के लिए:

Node.js

const admin = require('firebase-admin');
admin.initializeApp();

const db = admin.firestore();

exports.writeToFirestore = functions.firestore
  .document('some/doc')
  .onWrite((change, context) => {
    db.doc('some/otherdoc').set({ ... });
  });

सीमाएं

Cloud Functions के लिए Cloud Firestore ट्रिगर के लिए इन सीमाओं पर ध्यान दें:

  • ऑर्डर करने की कोई गारंटी नहीं है. तीव्र बदलाव किसी अनपेक्षित क्रम में फ़ंक्शन को शुरू करने को ट्रिगर कर सकते हैं.
  • इवेंट कम से कम एक बार डिलीवर किए जाते हैं, लेकिन किसी एक इवेंट की वजह से कई फ़ंक्शन शुरू हो सकते हैं. एक बार होने वाली मैकेनिक्स पर निर्भर रहने से बचें और खराब फ़ंक्शन लिखें.
  • Datastore मोड में Cloud Firestore के लिए Cloud Functions (2nd gen) की ज़रूरत होती है. Cloud Functions (1st gen) में, डेटास्टोर मोड काम नहीं करता.
  • Cloud Functions (1st gen) सिर्फ़ "(डिफ़ॉल्ट)" डेटाबेस के साथ काम करता है और यह Cloud Firestore नाम वाले डेटाबेस के साथ काम नहीं करता. नाम वाले डेटाबेस के लिए इवेंट कॉन्फ़िगर करने के लिए, कृपया Cloud Functions (2nd gen) का इस्तेमाल करें.
  • ट्रिगर, किसी एक डेटाबेस से जुड़ा होता है. एक से ज़्यादा डेटाबेस से मैच करने वाला ट्रिगर नहीं बनाया जा सकता.
  • किसी डेटाबेस को मिटाने से, उस डेटाबेस के ट्रिगर अपने-आप नहीं मिटते हैं. ट्रिगर, इवेंट को डिलीवर करना बंद कर देता है, लेकिन वह तब तक मौजूद रहता है, जब तक ट्रिगर को मिटाया नहीं जाता.
  • अगर मैच होने वाले किसी इवेंट में, अनुरोध की संख्या से ज़्यादा हो जाती है, तो हो सकता है कि वह इवेंट Cloud Functions (1st gen) पर न भेजा जाए.
    • अनुरोध के साइज़ की वजह से डिलीवर नहीं होने वाले इवेंट, प्लैटफ़ॉर्म लॉग में लॉग इन किए जाते हैं. साथ ही, इन्हें प्रोजेक्ट के लॉग के इस्तेमाल के तौर पर गिना जाता है.
    • आपको ये लॉग, लॉग एक्सप्लोरर में error की गंभीरता की सीमा से ज़्यादा होने की वजह से Cloud फ़ंक्शन पर डिलीवर नहीं किया जा सका. साथ ही, ये लॉग मिल सकते हैं. फ़ंक्शन का नाम, functionName फ़ील्ड में देखा जा सकता है. अगर receiveTimestamp फ़ील्ड अब भी एक घंटे बाद का है, तो बताए गए दस्तावेज़ को पढ़कर, असल इवेंट के कॉन्टेंट का अनुमान लगाया जा सकता है. इसके लिए, टाइमस्टैंप से पहले और बाद में मिले स्नैपशॉट का इस्तेमाल करें.
    • इस तरह के वीडियो अपलोड न करने के लिए, ये काम किए जा सकते हैं:
      • Cloud Functions (2nd gen) पर माइग्रेट और अपग्रेड करना
      • दस्तावेज़ का साइज़ छोटा करें
      • वे Cloud Functions मिटाएं जिनके बारे में जानकारी दी गई है
    • बाहर रखे गए इवेंट का इस्तेमाल करके, डेटा लॉग करने की सुविधा बंद की जा सकती है. हालांकि, ध्यान रखें कि आपत्तिजनक इवेंट अब भी डिलीवर नहीं किए जा सकेंगे.