बनाए जा रहे ऐप्लिकेशन के टाइप के हिसाब से, यह पता लगाना आपके लिए काम का हो सकता है कि आपके कौनसे उपयोगकर्ता या डिवाइस, इंटरनेट पर ऐक्टिव हैं. इसे "उपलब्धता का पता लगाना" भी कहा जाता है.
उदाहरण के लिए, अगर कोई सोशल नेटवर्क जैसा ऐप्लिकेशन बनाया जा रहा है या IoT डिवाइसों का फ़्लीट डिप्लॉय किया जा रहा है, तो इस जानकारी का इस्तेमाल करके, ऑनलाइन और चैट करने के लिए उपलब्ध दोस्तों की सूची दिखाई जा सकती है. इसके अलावा, IoT डिवाइसों को "पिछली बार कब देखा गया" के हिसाब से क्रम में लगाया जा सकता है.
Cloud Firestore में, उपलब्धता का पता लगाने की सुविधा इन-बिल्ट नहीं होती. हालांकि, उपलब्धता का पता लगाने वाला सिस्टम बनाने के लिए, Firebase के अन्य प्रॉडक्ट इस्तेमाल किए जा सकते हैं.
समाधान: रीयलटाइम डेटाबेस के साथ Cloud Functions का इस्तेमाल करना
Cloud Firestore को Firebase रीयलटाइम डेटाबेस की इन-बिल्ट उपलब्धता का पता लगाने वाली सुविधा से कनेक्ट करने के लिए, Cloud Functions का इस्तेमाल करें.
कनेक्शन की स्थिति की रिपोर्ट करने के लिए, रीयलटाइम डेटाबेस का इस्तेमाल करें. इसके बाद, उस डेटा को Cloud Firestore में मिरर करने के लिए, Cloud Functions का इस्तेमाल करें.
रीयलटाइम डेटाबेस में उपलब्धता का पता लगाने की सुविधा का इस्तेमाल करना
सबसे पहले, यह समझें कि रीयलटाइम डेटाबेस में, उपलब्धता का पता लगाने वाला पारंपरिक सिस्टम कैसे काम करता है.
वेब
// 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 का इस्तेमाल करें.
अगर आपने पहले से ही रीयलटाइम डेटाबेस को अपने प्रोजेक्ट में नहीं जोड़ा है, तो उसे जोड़ें और उपलब्धता का पता लगाने वाले ऊपर दिए गए सलूशन को शामिल करें.
इसके बाद, उपलब्धता की स्थिति को Cloud Firestore के साथ इन तरीकों से सिंक किया जाएगा:
- स्थानीय तौर पर, ऑफ़लाइन डिवाइस के Cloud Firestore कैश में, ताकि ऐप्लिकेशन को पता चल सके कि वह ऑफ़लाइन है.
- ग्लोबल तौर पर, Cloud Function का इस्तेमाल करके, ताकि Cloud Firestore को ऐक्सेस करने वाले अन्य सभी डिवाइसों को पता चल सके कि यह डिवाइस ऑफ़लाइन है.Cloud Firestore
इस ट्यूटोरियल में सुझाए गए फ़ंक्शन क्लाइंट ऐप्लिकेशन में नहीं चलाए जा सकते. इन्हें Cloud Functions for Firebase पर डिप्लॉय करना होगा. साथ ही, इनके लिए Firebase Admin SDK से सर्वर-साइड लॉजिक की ज़रूरत होती है. ज़्यादा जानकारी के लिए, Cloud Functions का दस्तावेज़ देखें.
Cloud Firestore's लोकल कैश को अपडेट करना
आइए, पहली समस्या को हल करने के लिए ज़रूरी बदलावों पर एक नज़र डालते हैं. यह समस्या, 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 Function का इस्तेमाल करेंगे. यह रीयलटाइम डेटाबेस में status/{uid} पाथ पर नज़र रखता है. रीयलटाइम डेटाबेस की वैल्यू में बदलाव होने पर, यह वैल्यू 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 ऐप्लिकेशन में उपलब्धता का पता लगाने की सुविधा जोड़ना, स्केल किया जा सकता है और यह असरदार है. हालांकि, इसकी कुछ सीमाएं हैं:
- डिबाउंसिंग - Cloud Firestore में रीयल टाइम में होने वाले बदलावों को सुनने पर, इस सलूशन से कई बदलाव ट्रिगर होने की संभावना होती है. अगर इन बदलावों से आपकी ज़रूरत से ज़्यादा इवेंट ट्रिगर होते हैं, तो इवेंट को मैन्युअल तरीके से डिबाउंस करें.Cloud Firestore
- कनेक्टिविटी - यह लागू करने का तरीका, रीयलटाइम डेटाबेस से कनेक्टिविटी को मेज़र करता है, न कि Cloud Firestore से. अगर हर डेटाबेस के कनेक्शन का स्टेटस एक जैसा नहीं है, तो इस सलूशन से उपलब्धता की गलत स्थिति की रिपोर्ट मिल सकती है.
- Android - Android पर, रीयलटाइम डेटाबेस 60 सेकंड तक कोई गतिविधि न होने पर,
बैकएंड से डिसकनेक्ट हो जाता है. कोई गतिविधि न होने का मतलब है कि कोई भी लिसनर खुला नहीं है या कोई भी कार्रवाई पेंडिंग नहीं है. कनेक्शन को खुला रखने के लिए, हमारा सुझाव है कि
.info/connectedके अलावा, किसी पाथ में वैल्यू इवेंट लिसनर जोड़ें. उदाहरण के लिए, हर सेशन की शुरुआत मेंFirebaseDatabase.getInstance().getReference((new Date()).toString()).keepSynced()किया जा सकता है. ज़्यादा जानकारी के लिए, कनेक्शन की स्थिति का पता लगाना लेख पढ़ें.