JavaScript में ऑफ़लाइन क्षमताएं चालू करना

Firebase ऐप्लिकेशन तब भी काम करते हैं, जब आपका ऐप्लिकेशन कुछ समय के लिए अपना नेटवर्क कनेक्शन बंद कर देता है. हम मौजूदगी को मॉनिटर करने और लोकल स्टेटस को सर्वर की स्थिति के साथ सिंक करने के लिए, कई टूल उपलब्ध कराते हैं. इनके बारे में इस दस्तावेज़ में बताया गया है.

मौजूदगी मैनेज करना

रीयलटाइम ऐप्लिकेशन में, यह पता लगाना अक्सर मददगार होता है कि क्लाइंट कब कनेक्ट और डिसकनेक्ट होते हैं. उदाहरण के लिए, हो सकता है कि किसी उपयोगकर्ता के डिसकनेक्ट होने पर, आप उसे 'ऑफ़लाइन' के तौर पर मार्क करना चाहें.

Firebase डेटाबेस क्लाइंट, ऐसे बुनियादी नियम उपलब्ध कराते हैं जिनका इस्तेमाल करके किसी क्लाइंट के Firebase डेटाबेस सर्वर से डिसकनेक्ट होने पर, डेटाबेस में डेटा लिखा जा सकता है. ये अपडेट होते हैं, चाहे क्लाइंट बिना किसी परेशानी के डिसकनेक्ट हो रहा हो या नहीं. इससे कनेक्शन टूट जाने या क्लाइंट क्रैश होने पर भी, डेटा मिटाने के लिए इन पर भरोसा किया जा सकता है. डिसकनेक्ट करने पर, राइटिंग से जुड़ी सभी कार्रवाइयां की जा सकती हैं. इनमें सेटिंग, अपडेट, और हटाने जैसी कार्रवाइयां शामिल हैं.

डिसकनेक्ट होने पर डेटा लिखने का एक आसान उदाहरण, onDisconnect प्रिमिटिव का इस्तेमाल करके दिया गया है:

वेब मॉड्यूलर एपीआई

import { getDatabase, ref, onDisconnect } from "firebase/database";

const db = getDatabase();
const presenceRef = ref(db, "disconnectmessage");
// Write a string when this client loses connection
onDisconnect(presenceRef).set("I disconnected!");

वेब नेमस्पेसेड एपीआई

var presenceRef = firebase.database().ref("disconnectmessage");
// Write a string when this client loses connection
presenceRef.onDisconnect().set("I disconnected!");

डिसकनेक्ट करने का तरीका

जब आप onDisconnect() कार्रवाई सेट करते हैं, तो कार्रवाई Firebase रीयल टाइम डेटाबेस सर्वर पर होती है. सर्वर, सुरक्षा की जांच करके यह पक्का करता है कि उपयोगकर्ता, अनुरोध किए गए इवेंट में बदलाव कर सकता है या नहीं. साथ ही, सर्वर आपके ऐप्लिकेशन के अमान्य होने पर, इसकी सूचना भी देता है. इसके बाद, सर्वर कनेक्शन को मॉनिटर करता है. अगर किसी भी समय कनेक्शन का समय खत्म हो जाता है या रीयलटाइम डेटाबेस क्लाइंट ने उसे बंद कर दिया होता है, तो सर्वर दूसरी बार सुरक्षा की जांच करता है (यह पक्का करने के लिए कि कार्रवाई अब भी मान्य है) और फिर इवेंट को शुरू करता है.

आपका ऐप्लिकेशन, लिखने की कार्रवाई पर कॉलबैक का इस्तेमाल कर सकता है, ताकि यह पक्का किया जा सके कि onDisconnect सही तरीके से अटैच हुआ है:

वेब मॉड्यूलर एपीआई

onDisconnect(presenceRef).remove().catch((err) => {
  if (err) {
    console.error("could not establish onDisconnect event", err);
  }
});

वेब नेमस्पेसेड एपीआई

presenceRef.onDisconnect().remove((err) => {
  if (err) {
    console.error("could not establish onDisconnect event", err);
  }
});

.cancel() पर कॉल करके भी onDisconnect इवेंट को रद्द किया जा सकता है:

वेब मॉड्यूलर एपीआई

const onDisconnectRef = onDisconnect(presenceRef);
onDisconnectRef.set("I disconnected");
// some time later when we change our minds
onDisconnectRef.cancel();

वेब नेमस्पेसेड एपीआई

var onDisconnectRef = presenceRef.onDisconnect();
onDisconnectRef.set("I disconnected");
// some time later when we change our minds
onDisconnectRef.cancel();

कनेक्शन की स्थिति का पता लगाया जा रहा है

मौजूदगी से जुड़ी कई सुविधाओं के लिए, आपके ऐप्लिकेशन के लिए यह जानना मददगार होता है कि वह कब ऑनलाइन है या कब ऑफ़लाइन है. Firebase रीयल टाइम डेटाबेस, /.info/connected में एक खास जगह उपलब्ध कराता है. जब भी Firebase रीयल टाइम डेटाबेस क्लाइंट के कनेक्शन की स्थिति में बदलाव होता है, तब यह जानकारी अपडेट हो जाती है. यहां एक उदाहरण दिया गया है:

वेब मॉड्यूलर एपीआई

import { getDatabase, ref, onValue } from "firebase/database";

const db = getDatabase();
const connectedRef = ref(db, ".info/connected");
onValue(connectedRef, (snap) => {
  if (snap.val() === true) {
    console.log("connected");
  } else {
    console.log("not connected");
  }
});

वेब नेमस्पेसेड एपीआई

var connectedRef = firebase.database().ref(".info/connected");
connectedRef.on("value", (snap) => {
  if (snap.val() === true) {
    console.log("connected");
  } else {
    console.log("not connected");
  }
});

/.info/connected एक बूलियन वैल्यू है, जो रीयल टाइम डेटाबेस क्लाइंट के बीच सिंक नहीं की जाती, क्योंकि वैल्यू, क्लाइंट की स्थिति पर निर्भर करती है. दूसरे शब्दों में, अगर एक क्लाइंट /.info/connected को गलत के तौर पर पढ़ता है, तो इस बात की कोई गारंटी नहीं है कि कोई दूसरा क्लाइंट भी 'गलत' पढ़ेगा.

हैंडलिंग में लगने वाले समय का अंतर

सर्वर टाइमस्टैंप

Firebase रीयल टाइम डेटाबेस सर्वर, सर्वर पर जनरेट किए गए टाइमस्टैंप को डेटा के तौर पर डालने का तरीका उपलब्ध कराते हैं. onDisconnect के साथ मिलकर, यह सुविधा आसानी से उस समय को नोट कर सकती है जब रीयल टाइम डेटाबेस क्लाइंट डिसकनेक्ट हो गया था:

वेब मॉड्यूलर एपीआई

import { getDatabase, ref, onDisconnect, serverTimestamp } from "firebase/database";

const db = getDatabase();
const userLastOnlineRef = ref(db, "users/joe/lastOnline");
onDisconnect(userLastOnlineRef).set(serverTimestamp());

वेब नेमस्पेसेड एपीआई

var userLastOnlineRef = firebase.database().ref("users/joe/lastOnline");
userLastOnlineRef.onDisconnect().set(firebase.database.ServerValue.TIMESTAMP);

क्लॉक स्क्यू

हालांकि, पढ़ने/लिखने में की जाने वाली ज़्यादातर कार्रवाइयों के लिए firebase.database.ServerValue.TIMESTAMP ज़्यादा सटीक और बेहतर है, लेकिन कभी-कभी यह Firebase रीयल टाइम डेटाबेस के सर्वर के हिसाब से, क्लाइंट के समय में बदलाव का अनुमान लगाने में मदद कर सकता है. /.info/serverTimeOffset जगह पर कॉलबैक अटैच करके, मिलीसेकंड में वैल्यू पाई जा सकती है. Firebase रीयल टाइम डेटाबेस क्लाइंट, सर्वर के समय का अनुमान लगाने के लिए, रिपोर्ट किए गए स्थानीय समय (मिलीसेकंड में Epoch समय) में जो वैल्यू जोड़ता है. ध्यान दें कि इस ऑफ़सेट के सटीक होने पर, नेटवर्किंग में लगने वाले समय की वजह से असर पड़ सकता है. इसलिए, इसका इस्तेमाल खास तौर पर, क्लॉक टाइम (एक सेकंड से ज़्यादा) में बड़े अंतर का पता लगाने के लिए किया जाता है.

वेब मॉड्यूलर एपीआई

import { getDatabase, ref, onValue } from "firebase/database";

const db = getDatabase();
const offsetRef = ref(db, ".info/serverTimeOffset");
onValue(offsetRef, (snap) => {
  const offset = snap.val();
  const estimatedServerTimeMs = new Date().getTime() + offset;
});

वेब नेमस्पेसेड एपीआई

var offsetRef = firebase.database().ref(".info/serverTimeOffset");
offsetRef.on("value", (snap) => {
  var offset = snap.val();
  var estimatedServerTimeMs = new Date().getTime() + offset;
});

मौजूदगी ऐप्लिकेशन का नमूना

डिसकनेक्ट करने की कार्रवाइयों को कनेक्शन की स्थिति पर नज़र रखने और सर्वर के टाइमस्टैंप के साथ जोड़कर, उपयोगकर्ता की मौजूदगी का सिस्टम बनाया जा सकता है. इस सिस्टम में, हर उपयोगकर्ता, डेटाबेस की लोकेशन पर डेटा सेव करता है, ताकि यह बताया जा सके कि रीयलटाइम डेटाबेस क्लाइंट ऑनलाइन है या नहीं. क्लाइंट इस जगह के ऑनलाइन आने पर, सही के तौर पर और डिसकनेक्ट होने पर टाइमस्टैंप को सेट करते हैं. इस टाइमस्टैंप से पता चलता है कि उपयोगकर्ता पिछली बार कब ऑनलाइन हुआ था.

ध्यान दें कि आपके ऐप्लिकेशन को उपयोगकर्ता के ऑनलाइन मार्क होने से पहले, डिसकनेक्ट करने की कार्रवाइयों की सूची बनानी चाहिए. इससे, सर्वर पर दोनों निर्देश भेजे जाने से पहले, क्लाइंट का नेटवर्क कनेक्शन टूट जाने की स्थिति से बचा जा सकता है.

यहां उपयोगकर्ता की मौजूदगी का एक सामान्य सिस्टम दिया गया है:

वेब मॉड्यूलर एपीआई

import { getDatabase, ref, onValue, push, onDisconnect, set, serverTimestamp } from "firebase/database";

// Since I can connect from multiple devices or browser tabs, we store each connection instance separately
// any time that connectionsRef's value is null (i.e. has no children) I am offline
const db = getDatabase();
const myConnectionsRef = ref(db, 'users/joe/connections');

// stores the timestamp of my last disconnect (the last time I was seen online)
const lastOnlineRef = ref(db, 'users/joe/lastOnline');

const connectedRef = ref(db, '.info/connected');
onValue(connectedRef, (snap) => {
  if (snap.val() === true) {
    // We're connected (or reconnected)! Do anything here that should happen only if online (or on reconnect)
    const con = push(myConnectionsRef);

    // When I disconnect, remove this device
    onDisconnect(con).remove();

    // Add this device to my connections list
    // this value could contain info about the device or a timestamp too
    set(con, true);

    // When I disconnect, update the last time I was seen online
    onDisconnect(lastOnlineRef).set(serverTimestamp());
  }
});

वेब नेमस्पेसेड एपीआई

// Since I can connect from multiple devices or browser tabs, we store each connection instance separately
// any time that connectionsRef's value is null (i.e. has no children) I am offline
var myConnectionsRef = firebase.database().ref('users/joe/connections');

// stores the timestamp of my last disconnect (the last time I was seen online)
var lastOnlineRef = firebase.database().ref('users/joe/lastOnline');

var connectedRef = firebase.database().ref('.info/connected');
connectedRef.on('value', (snap) => {
  if (snap.val() === true) {
    // We're connected (or reconnected)! Do anything here that should happen only if online (or on reconnect)
    var con = myConnectionsRef.push();

    // When I disconnect, remove this device
    con.onDisconnect().remove();

    // Add this device to my connections list
    // this value could contain info about the device or a timestamp too
    con.set(true);

    // When I disconnect, update the last time I was seen online
    lastOnlineRef.onDisconnect().set(firebase.database.ServerValue.TIMESTAMP);
  }
});