क्लाउड फायरस्टोर में उपस्थिति बनाएँ

आप जिस प्रकार के ऐप का निर्माण कर रहे हैं, उसके आधार पर, आपके लिए यह पता लगाना उपयोगी हो सकता है कि आपके कौन से उपयोगकर्ता या डिवाइस सक्रिय रूप से ऑनलाइन हैं - अन्यथा इसे "उपस्थिति का पता लगाने" के रूप में जाना जाता है।

उदाहरण के लिए, यदि आप एक सोशल नेटवर्क जैसा ऐप बना रहे हैं या IoT उपकरणों का एक बेड़ा तैनात कर रहे हैं, तो आप इस जानकारी का उपयोग उन मित्रों की सूची प्रदर्शित करने के लिए कर सकते हैं जो ऑनलाइन हैं और चैट करने के लिए निःशुल्क हैं, या अपने IoT उपकरणों को "अंतिम बार देखा गया" के आधार पर क्रमबद्ध कर सकते हैं। ।"

क्लाउड फायरस्टोर मूल रूप से उपस्थिति का समर्थन नहीं करता है, लेकिन आप उपस्थिति प्रणाली बनाने के लिए अन्य फायरबेस उत्पादों का लाभ उठा सकते हैं।

समाधान: रीयलटाइम डेटाबेस के साथ क्लाउड फ़ंक्शंस

क्लाउड फायरस्टोर को फायरबेस रीयलटाइम डेटाबेस की मूल उपस्थिति सुविधा से कनेक्ट करने के लिए, क्लाउड फ़ंक्शंस का उपयोग करें।

कनेक्शन स्थिति की रिपोर्ट करने के लिए रीयलटाइम डेटाबेस का उपयोग करें, फिर उस डेटा को क्लाउड फायरस्टोर में मिरर करने के लिए क्लाउड फ़ंक्शंस का उपयोग करें।

रीयलटाइम डेटाबेस में उपस्थिति का उपयोग करना

सबसे पहले, विचार करें कि पारंपरिक उपस्थिति प्रणाली रीयलटाइम डेटाबेस में कैसे काम करती है।

वेब

// Fetch the current user's ID from Firebase Authentication.
var uid = firebase.auth().currentUser.uid;

// Create a reference to this user's specific status node.
// This is where we will store data about being online/offline.
var userStatusDatabaseRef = firebase.database().ref('/status/' + uid);

// We'll create two constants which we will write to 
// the Realtime database when this device is offline
// or online.
var isOfflineForDatabase = {
    state: 'offline',
    last_changed: firebase.database.ServerValue.TIMESTAMP,
};

var isOnlineForDatabase = {
    state: 'online',
    last_changed: firebase.database.ServerValue.TIMESTAMP,
};

// Create a reference to the special '.info/connected' path in 
// Realtime Database. This path returns `true` when connected
// and `false` when disconnected.
firebase.database().ref('.info/connected').on('value', function(snapshot) {
    // If we're not currently connected, don't do anything.
    if (snapshot.val() == false) {
        return;
    };

    // If we are currently connected, then use the 'onDisconnect()' 
    // method to add a set which will only trigger once this 
    // client has disconnected by closing the app, 
    // losing internet, or any other means.
    userStatusDatabaseRef.onDisconnect().set(isOfflineForDatabase).then(function() {
        // The promise returned from .onDisconnect().set() will
        // resolve as soon as the server acknowledges the onDisconnect() 
        // request, NOT once we've actually disconnected:
        // https://firebase.google.com/docs/reference/js/firebase.database.OnDisconnect

        // We can now safely set ourselves as 'online' knowing that the
        // server will mark us as offline once we lose connection.
        userStatusDatabaseRef.set(isOnlineForDatabase);
    });
});

यह उदाहरण एक संपूर्ण रीयलटाइम डेटाबेस उपस्थिति प्रणाली है। यह कई डिस्कनेक्शन, क्रैश आदि को संभालता है।

क्लाउड फायरस्टोर से कनेक्ट हो रहा है

क्लाउड फायरस्टोर में समान समाधान लागू करने के लिए समान रीयलटाइम डेटाबेस कोड का उपयोग करें, फिर रीयलटाइम डेटाबेस और क्लाउड फायरस्टोर को सिंक में रखने के लिए क्लाउड फ़ंक्शंस का उपयोग करें।

यदि आपने पहले से नहीं किया है, तो अपने प्रोजेक्ट में रीयलटाइम डेटाबेस जोड़ें और उपरोक्त उपस्थिति समाधान शामिल करें।

इसके बाद आप निम्नलिखित विधियों के माध्यम से उपस्थिति स्थिति को क्लाउड फायरस्टोर में सिंक्रनाइज़ करेंगे:

  1. स्थानीय रूप से, ऑफ़लाइन डिवाइस के क्लाउड फायरस्टोर कैश में ताकि ऐप को पता चले कि यह ऑफ़लाइन है।
  2. विश्व स्तर पर, क्लाउड फ़ंक्शन का उपयोग करना ताकि क्लाउड फायरस्टोर तक पहुंचने वाले अन्य सभी डिवाइस जान सकें कि यह विशिष्ट डिवाइस ऑफ़लाइन है।

क्लाउड फायरस्टोर का स्थानीय कैश अपडेट किया जा रहा है

आइए पहले मुद्दे को पूरा करने के लिए आवश्यक परिवर्तनों पर एक नज़र डालें - क्लाउड फायरस्टोर के स्थानीय कैश को अपडेट करना।

वेब

// ...
var userStatusFirestoreRef = firebase.firestore().doc('/status/' + uid);

// Firestore uses a different server timestamp value, so we'll 
// create two more constants for Firestore state.
var isOfflineForFirestore = {
    state: 'offline',
    last_changed: firebase.firestore.FieldValue.serverTimestamp(),
};

var isOnlineForFirestore = {
    state: 'online',
    last_changed: firebase.firestore.FieldValue.serverTimestamp(),
};

firebase.database().ref('.info/connected').on('value', function(snapshot) {
    if (snapshot.val() == false) {
        // Instead of simply returning, we'll also set Firestore's state
        // to 'offline'. This ensures that our Firestore cache is aware
        // of the switch to 'offline.'
        userStatusFirestoreRef.set(isOfflineForFirestore);
        return;
    };

    userStatusDatabaseRef.onDisconnect().set(isOfflineForDatabase).then(function() {
        userStatusDatabaseRef.set(isOnlineForDatabase);

        // We'll also add Firestore set here for when we come online.
        userStatusFirestoreRef.set(isOnlineForFirestore);
    });
});

इन परिवर्तनों के साथ अब हमने यह सुनिश्चित कर लिया है कि स्थानीय क्लाउड फायरस्टोर स्थिति हमेशा डिवाइस की ऑनलाइन/ऑफ़लाइन स्थिति को दर्शाएगी। इसका मतलब है कि आप /status/{uid} दस्तावेज़ को सुन सकते हैं और कनेक्शन स्थिति को प्रतिबिंबित करने के लिए अपने यूआई को बदलने के लिए डेटा का उपयोग कर सकते हैं।

वेब

userStatusFirestoreRef.onSnapshot(function(doc) {
    var isOnline = doc.data().state == 'online';
    // ... use isOnline
});

वैश्विक स्तर पर क्लाउड फायरस्टोर को अपडेट करना

हालाँकि हमारा एप्लिकेशन स्वयं ऑनलाइन उपस्थिति की सही रिपोर्ट करता है, यह स्थिति अभी तक अन्य क्लाउड फायरस्टोर ऐप्स में सटीक नहीं होगी क्योंकि हमारा "ऑफ़लाइन" स्टेटस लेखन केवल स्थानीय है और कनेक्शन बहाल होने पर सिंक नहीं किया जाएगा। इसका मुकाबला करने के लिए, हम एक क्लाउड फ़ंक्शन का उपयोग करेंगे जो रीयलटाइम डेटाबेस में status/{uid} पथ को देखता है। जब रीयलटाइम डेटाबेस मान बदलता है तो मान क्लाउड फायरस्टोर से सिंक हो जाएगा ताकि सभी उपयोगकर्ताओं की स्थिति सही हो।

नोड.जे.एस

firebase.firestore().collection('status')
    .where('state', '==', 'online')
    .onSnapshot(function(snapshot) {
        snapshot.docChanges().forEach(function(change) {
            if (change.type === 'added') {
                var msg = 'User ' + change.doc.id + ' is online.';
                console.log(msg);
                // ...
            }
            if (change.type === 'removed') {
                var msg = 'User ' + change.doc.id + ' is offline.';
                console.log(msg);
                // ...
            }
        });
    });

एक बार जब आप इस फ़ंक्शन को तैनात कर देते हैं, तो आपके पास क्लाउड फायरस्टोर के साथ चलने वाली एक संपूर्ण उपस्थिति प्रणाली होगी। नीचे किसी भी उपयोगकर्ता के लिए निगरानी का एक उदाहरण दिया गया है जो where() क्वेरी का उपयोग करके ऑनलाइन आते हैं या ऑफ़लाइन हो जाते हैं।

वेब

firebase.firestore().collection('status')
    .where('state', '==', 'online')
    .onSnapshot(function(snapshot) {
        snapshot.docChanges().forEach(function(change) {
            if (change.type === 'added') {
                var msg = 'User ' + change.doc.id + ' is online.';
                console.log(msg);
                // ...
            }
            if (change.type === 'removed') {
                var msg = 'User ' + change.doc.id + ' is offline.';
                console.log(msg);
                // ...
            }
        });
    });

सीमाएँ

अपने क्लाउड फायरस्टोर ऐप में उपस्थिति जोड़ने के लिए रीयलटाइम डेटाबेस का उपयोग करना स्केलेबल और प्रभावी है लेकिन इसकी कुछ सीमाएँ हैं:

  • डिबाउंसिंग - क्लाउड फायरस्टोर में रीयलटाइम परिवर्तनों को सुनते समय, यह समाधान कई परिवर्तनों को ट्रिगर करने की संभावना है। यदि ये परिवर्तन आपकी इच्छा से अधिक घटनाओं को ट्रिगर करते हैं, तो क्लाउड फायरस्टोर घटनाओं को मैन्युअल रूप से खारिज कर दें।
  • कनेक्टिविटी - यह कार्यान्वयन रियलटाइम डेटाबेस से कनेक्टिविटी को मापता है, क्लाउड फायरस्टोर से नहीं। यदि प्रत्येक डेटाबेस की कनेक्शन स्थिति समान नहीं है, तो यह समाधान गलत उपस्थिति स्थिति की रिपोर्ट कर सकता है।
  • एंड्रॉइड - एंड्रॉइड पर, रीयलटाइम डेटाबेस 60 सेकंड की निष्क्रियता के बाद बैकएंड से डिस्कनेक्ट हो जाता है। निष्क्रियता का अर्थ है कोई खुला श्रोता या लंबित संचालन नहीं। कनेक्शन को खुला रखने के लिए, हमने अनुशंसा की है कि आप .info/connected के अलावा एक पथ में एक वैल्यू इवेंट श्रोता जोड़ें। उदाहरण के लिए आप प्रत्येक सत्र की शुरुआत में FirebaseDatabase.getInstance().getReference((new Date()).toString()).keepSynced() कर सकते हैं। अधिक जानकारी के लिए, कनेक्शन स्थिति का पता लगाना देखें।