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

আপনি যে ধরণের অ্যাপ তৈরি করছেন তার উপর নির্ভর করে, আপনার কোন ব্যবহারকারী বা ডিভাইস সক্রিয়ভাবে অনলাইনে আছেন তা সনাক্ত করা আপনার জন্য কার্যকর হতে পারে — অন্যথায় এটি "উপস্থিতি সনাক্তকরণ" নামে পরিচিত।

উদাহরণস্বরূপ, যদি আপনি একটি সোশ্যাল নেটওয়ার্কের মতো একটি অ্যাপ তৈরি করেন অথবা IoT ডিভাইসের একটি বহর মোতায়েন করেন, তাহলে আপনি এই তথ্য ব্যবহার করে অনলাইনে থাকা এবং চ্যাট করার জন্য বিনামূল্যে থাকা বন্ধুদের একটি তালিকা প্রদর্শন করতে পারেন, অথবা আপনার IoT ডিভাইসগুলিকে "শেষ দেখা" অনুসারে সাজাতে পারেন।

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 অ্যাক্সেসকারী অন্যান্য সমস্ত ডিভাইস জানতে পারে যে এই নির্দিষ্ট ডিভাইসটি অফলাইনে রয়েছে।

এই টিউটোরিয়ালে সুপারিশকৃত ফাংশনগুলি কোনও ক্লায়েন্ট অ্যাপে চালানো যাবে না । এগুলি অবশ্যই Cloud Functions for Firebase এ স্থাপন করা উচিত এবং Firebase Admin SDK থেকে সার্ভার-সাইড লজিক প্রয়োজন। বিস্তারিত নির্দেশিকাগুলির জন্য, Cloud Functions ডকুমেন্টেশন দেখুন।

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} ডকুমেন্টটি শুনতে পারেন এবং সংযোগের অবস্থা প্রতিফলিত করার জন্য আপনার UI পরিবর্তন করতে ডেটা ব্যবহার করতে পারেন।

ওয়েব

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

এই ফাংশনটি স্থাপন করার পর, আপনার কাছে 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 সাথে নয়, রিয়েলটাইম ডাটাবেসের সাথে সংযোগ পরিমাপ করে। যদি প্রতিটি ডাটাবেসের সাথে সংযোগের অবস্থা একই না হয়, তাহলে এই সমাধানটি একটি ভুল উপস্থিতির অবস্থা রিপোর্ট করতে পারে।
  • অ্যান্ড্রয়েড - অ্যান্ড্রয়েডে, রিয়েলটাইম ডেটাবেস ৬০ সেকেন্ড নিষ্ক্রিয় থাকার পরে ব্যাকএন্ড থেকে সংযোগ বিচ্ছিন্ন হয়ে যায়। নিষ্ক্রিয়তার অর্থ হল কোনও খোলা শ্রোতা বা মুলতুবি থাকা ক্রিয়াকলাপ নেই। সংযোগটি খোলা রাখার জন্য, আমরা আপনাকে .info/connected ছাড়াও একটি পাথে একটি মান ইভেন্ট শ্রোতা যোগ করার পরামর্শ দিয়েছি। উদাহরণস্বরূপ, আপনি প্রতিটি সেশনের শুরুতে FirebaseDatabase.getInstance().getReference((new Date()).toString()).keepSynced() করতে পারেন। আরও তথ্যের জন্য, সংযোগ অবস্থা সনাক্তকরণ দেখুন।