आपके बनाए जा रहे ऐप्लिकेशन के टाइप के आधार पर, यह पता लगाना आपके लिए फ़ायदेमंद हो सकता है कि आपके कौनसे उपयोगकर्ता या डिवाइस, इंटरनेट से कनेक्ट हैं. इसे "उपयोगकर्ता की मौजूदगी" का पता लगाना भी कहा जाता है.
उदाहरण के लिए, अगर आपको कोई सोशल नेटवर्क जैसा ऐप्लिकेशन बनाना है या आईओटी डिवाइसों का फ्लीट डिप्लॉय करना है, तो इस जानकारी का इस्तेमाल किया जा सकता है. इससे, ऑनलाइन और चैट करने के लिए उपलब्ध दोस्तों की सूची दिखाई जा सकती है. इसके अलावा, आईओटी डिवाइसों को "पिछली बार देखा गया" के हिसाब से क्रम में लगाया जा सकता है.
Cloud Firestore में प्रेज़ेंस की सुविधा डिफ़ॉल्ट रूप से उपलब्ध नहीं होती. हालांकि, प्रेज़ेंस सिस्टम बनाने के लिए, Firebase के अन्य प्रॉडक्ट का इस्तेमाल किया जा सकता है.
समाधान: रीयल टाइम डेटाबेस के साथ Cloud Functions
Cloud Firestore को Firebase रीयलटाइम डेटाबेस की नेटिव प्रेज़ेंस सुविधा से कनेक्ट करने के लिए, Cloud Functions का इस्तेमाल करें.
कनेक्शन स्टेटस की जानकारी देने के लिए, Realtime Database का इस्तेमाल करें. इसके बाद, Cloud Functions का इस्तेमाल करके उस डेटा को Cloud Firestore में मिरर करें.
रीयलटाइम डेटाबेस में मौजूदगी की जानकारी का इस्तेमाल करना
सबसे पहले, यह जानें कि Realtime Database में पारंपरिक प्रेज़ेंस सिस्टम कैसे काम करता है.
वेब
// 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); }); });
यह उदाहरण, रीयलटाइम डेटाबेस के प्रेज़ेंस सिस्टम का पूरा उदाहरण है. यह कई बार डिसकनेक्ट होने, क्रैश होने वगैरह की समस्याओं को ठीक करता है.
Cloud Firestore से कनेक्ट किया जा रहा है
Cloud Firestore में इसी तरह का समाधान लागू करने के लिए, रीयलटाइम डेटाबेस के उसी कोड का इस्तेमाल करें. इसके बाद, रीयलटाइम डेटाबेस और Cloud Firestore को सिंक में रखने के लिए, Cloud Functions का इस्तेमाल करें.
अगर आपने पहले से ही ऐसा नहीं किया है, तो अपने प्रोजेक्ट में Realtime Database जोड़ें. साथ ही, ऊपर दिए गए प्रेज़ेंस सलूशन को शामिल करें.
इसके बाद, आपको Cloud Firestore के साथ मौजूदगी की स्थिति को सिंक करना होगा. इसके लिए, ये तरीके अपनाएं:
- ऑफ़लाइन डिवाइस की Cloud Firestore कैश मेमोरी में, ताकि ऐप्लिकेशन को पता चल सके कि डिवाइस ऑफ़लाइन है.
- दुनिया भर में, क्लाउड फ़ंक्शन का इस्तेमाल करके यह पता लगाना कि Cloud Firestore को ऐक्सेस करने वाले सभी अन्य डिवाइसों को यह पता चल जाए कि यह डिवाइस ऑफ़लाइन है.
Cloud Firestore की लोकल कैश मेमोरी अपडेट की जा रही है
पहली समस्या को हल करने के लिए, Cloud Firestore की लोकल कैश फ़ाइल को अपडेट करना होगा. आइए, देखते हैं कि इसके लिए क्या-क्या बदलाव करने होंगे.
वेब
// ... 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); }); });
इन बदलावों के बाद, अब हम यह पक्का कर सकते हैं कि लोकल Cloud Firestore की स्थिति हमेशा डिवाइस के ऑनलाइन/ऑफ़लाइन स्टेटस को दिखाएगी. इसका मतलब है कि /status/{uid}
दस्तावेज़ को सुना जा सकता है. साथ ही, डेटा का इस्तेमाल करके यूज़र इंटरफ़ेस (यूआई) में बदलाव किया जा सकता है, ताकि कनेक्शन की स्थिति दिख सके.
वेब
userStatusFirestoreRef.onSnapshot(function(doc) { var isOnline = doc.data().state == 'online'; // ... use isOnline });
Cloud Firestore को दुनिया भर में अपडेट किया जा रहा है
हालांकि, हमारा ऐप्लिकेशन खुद को ऑनलाइन होने की जानकारी सही तरीके से देता है, लेकिन यह स्टेटस
अभी अन्य Cloud Firestore ऐप्लिकेशन में सही नहीं होगा. ऐसा इसलिए, क्योंकि "ऑफ़लाइन"
स्टेटस सिर्फ़ स्थानीय तौर पर लिखा जाता है और कनेक्शन वापस आने पर सिंक नहीं होगा. इससे बचने के लिए, हम Cloud Functions का इस्तेमाल करेंगे. यह रीयल टाइम डेटाबेस में status/{uid}
पाथ पर नज़र रखता है. Realtime Database की वैल्यू बदलने पर, यह वैल्यू Cloud Firestore के साथ सिंक हो जाएगी, ताकि सभी उपयोगकर्ताओं के स्टेटस सही हों.
Node.js
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); // ... } }); });
इस फ़ंक्शन को डिप्लॉय करने के बाद, आपके पास Cloud Firestore के साथ काम करने वाला पूरा प्रेज़ेंस सिस्टम होगा. यहां उन उपयोगकर्ताओं की निगरानी करने का उदाहरण दिया गया है जो 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); // ... } }); });
सीमाएं
अपने Cloud Firestore ऐप्लिकेशन में मौजूदगी की जानकारी जोड़ने के लिए, Realtime Database का इस्तेमाल किया जा सकता है. यह सुविधा स्केलेबल और असरदार है. हालांकि, इसकी कुछ सीमाएं हैं:
- डिबाउंसिंग - Cloud Firestore में रीयलटाइम में होने वाले बदलावों को सुनने के दौरान, इस समाधान से कई बदलाव ट्रिगर होने की संभावना होती है. अगर इन बदलावों से आपकी ज़रूरत से ज़्यादा इवेंट ट्रिगर होते हैं, तो Cloud Firestore इवेंट को मैन्युअल तरीके से डीबाउंस करें.
- कनेक्टिविटी - यह लागू करने का तरीका, Cloud Firestore से नहीं, बल्कि Realtime Database से कनेक्टिविटी को मेज़र करता है. अगर हर डेटाबेस के कनेक्शन की स्थिति एक जैसी नहीं है, तो हो सकता है कि यह समाधान, उपयोगकर्ता की मौजूदगी की स्थिति की गलत जानकारी दे.
- Android - Android पर, 60 सेकंड तक कोई गतिविधि न होने पर, Realtime Database बैकएंड से डिसकनेक्ट हो जाता है. निष्क्रियता का मतलब है कि कोई भी लिसनर चालू नहीं है या कोई भी कार्रवाई बाकी नहीं है. कनेक्शन को चालू रखने के लिए, हमारा सुझाव है कि आप
.info/connected
के अलावा किसी अन्य पाथ में वैल्यू इवेंट लिसनर जोड़ें. उदाहरण के लिए, हर सेशन की शुरुआत मेंFirebaseDatabase.getInstance().getReference((new Date()).toString()).keepSynced()
किया जा सकता है. ज़्यादा जानकारी के लिए, कनेक्शन की स्थिति का पता लगाना लेख पढ़ें.