ক্লাউড ফায়ারস্টোরে উপস্থিতি তৈরি করুন

আপনি কী ধরনের অ্যাপ তৈরি করছেন তার ওপর নির্ভর করে, আপনার কোন ব্যবহারকারী বা ডিভাইসগুলো সক্রিয়ভাবে অনলাইনে আছে তা শনাক্ত করা দরকারি হতে পারে — যা ‘উপস্থিতি’ শনাক্তকরণ নামেও পরিচিত।

For example, if you're building an app like a social network or deploying a fleet of IoT devices, you could use this information to display a list of friends that are online and free to chat, or sort your IoT devices by "last seen."

Cloud Firestore সরাসরি প্রেজেন্স সাপোর্ট নেই, কিন্তু আপনি অন্যান্য ফায়ারবেস প্রোডাক্ট ব্যবহার করে একটি প্রেজেন্স সিস্টেম তৈরি করতে পারেন।

সমাধান: রিয়েলটাইম ডেটাবেস সহ ক্লাউড ফাংশন

Cloud Firestore ফায়ারবেস রিয়েলটাইম ডেটাবেসের নেটিভ প্রেজেন্স ফিচারের সাথে সংযুক্ত করতে ক্লাউড ফাংশন ব্যবহার করুন।

কানেকশনের অবস্থা রিপোর্ট করার জন্য রিয়েলটাইম ডেটাবেস ব্যবহার করুন, তারপর সেই ডেটা Cloud Firestore মিরর করতে ক্লাউড ফাংশন ব্যবহার করুন।

রিয়েলটাইম ডেটাবেসে উপস্থিতি ব্যবহার করা

প্রথমে, রিয়েলটাইম ডেটাবেসে একটি প্রচলিত উপস্থিতি সিস্টেম কীভাবে কাজ করে তা বিবেচনা করুন।

ওয়েব

// 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 Firestore প্রেজেন্স স্টেট সিঙ্ক্রোনাইজ করবেন:

  1. স্থানীয়ভাবে, অফলাইন ডিভাইসটির Cloud Firestore ক্যাশে-তে, যাতে অ্যাপটি বুঝতে পারে যে এটি অফলাইন।
  2. বিশ্বব্যাপী একটি ক্লাউড ফাংশন ব্যবহার করা হয়, যাতে Cloud Firestore অ্যাক্সেসকারী অন্য সব ডিভাইস জানতে পারে যে এই নির্দিষ্ট ডিভাইসটি অফলাইন।

The functions recommended in this tutorial cannot run in a client app . They must be deployed to Cloud Functions for Firebase , and they require server-side logic from the Firebase Admin SDK. For detailed guidance, see the Cloud Functions documentation .

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);
    });
});

With these changes we've now ensured that the local Cloud Firestore state will always reflect the online/offline status of the device. This means you can listen to the /status/{uid} document and use the data to change your UI to reflect connection status.

ওয়েব

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

বিশ্বব্যাপী Cloud Firestore আপডেট করা হচ্ছে

যদিও আমাদের অ্যাপ্লিকেশনটি নিজের কাছে সঠিকভাবে অনলাইন উপস্থিতি রিপোর্ট করে, এই স্ট্যাটাসটি এখনও অন্যান্য Cloud Firestore অ্যাপে সঠিক হবে না, কারণ আমাদের "অফলাইন" স্ট্যাটাস রাইট শুধুমাত্র স্থানীয়ভাবে করা হয় এবং সংযোগ পুনরুদ্ধার হলে তা সিঙ্ক হয় না। এর সমাধান করতে, আমরা একটি ক্লাউড ফাংশন ব্যবহার করব যা রিয়েলটাইম ডেটাবেসের status/{uid} পাথটি পর্যবেক্ষণ করবে। যখন রিয়েলটাইম ডেটাবেসের মান পরিবর্তিত হবে, তখন সেই মানটি Cloud Firestore সিঙ্ক হয়ে যাবে, যাতে সকল ব্যবহারকারীর স্ট্যাটাস সঠিক থাকে।

নোড.জেএস

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);
                // ...
            }
        });
    });

Once you deploy this function, you'll have a complete presence system running with Cloud Firestore . Below is an example of monitoring for any users who come online or go offline using a where() query.

ওয়েব

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 অ্যাপে উপস্থিতি যোগ করতে রিয়েলটাইম ডেটাবেস ব্যবহার করা পরিবর্ধনযোগ্য ও কার্যকর, কিন্তু এর কিছু সীমাবদ্ধতা রয়েছে:

  • Debouncing - when listening to realtime changes in Cloud Firestore , this solution is likely to trigger multiple changes. If these changes trigger more events than you want, manually debounce the Cloud Firestore events.
  • Connectivity - this implementation measures connectivity to Realtime Database, not to Cloud Firestore . If the connection status to each database is not the same, this solution might report an incorrect presence state.
  • অ্যান্ড্রয়েড - অ্যান্ড্রয়েডে, ৬০ সেকেন্ড নিষ্ক্রিয় থাকার পর রিয়েলটাইম ডেটাবেস ব্যাকএন্ড থেকে সংযোগ বিচ্ছিন্ন করে দেয়। নিষ্ক্রিয়তা বলতে বোঝায় কোনো খোলা লিসেনার বা পেন্ডিং অপারেশন না থাকা। সংযোগটি খোলা রাখতে, আমরা আপনাকে .info/connected পাথ ছাড়া অন্য কোনো পাথে একটি ভ্যালু ইভেন্ট লিসেনার যোগ করার পরামর্শ দিই। উদাহরণস্বরূপ, আপনি প্রতিটি সেশনের শুরুতে FirebaseDatabase.getInstance().getReference((new Date()).toString()).keepSynced() ব্যবহার করতে পারেন। আরও তথ্যের জন্য, ‘সংযোগের অবস্থা শনাক্তকরণ’ দেখুন।