FCM রেজিস্ট্রেশন টোকেন ব্যবস্থাপনার জন্য সর্বোত্তম অনুশীলন

আপনি যদি প্রোগ্রাম্যাটিকভাবে সেন্ড রিকোয়েস্ট তৈরি করতে FCM API ব্যবহার করেন, তাহলে সময়ের সাথে সাথে আপনি দেখতে পারেন যে, মেয়াদোত্তীর্ণ রেজিস্ট্রেশন টোকেনসহ নিষ্ক্রিয় ডিভাইসগুলিতে মেসেজ পাঠিয়ে আপনি রিসোর্স অপচয় করছেন। এই পরিস্থিতিটি Firebase কনসোলে রিপোর্ট করা মেসেজ ডেলিভারি ডেটা বা BigQuery-তে এক্সপোর্ট করা ডেটাকে প্রভাবিত করতে পারে, যার ফলে ডেলিভারি রেটে একটি নাটকীয় (কিন্তু প্রকৃতপক্ষে বৈধ নয়) পতন দেখা যায়। এই নির্দেশিকাটিতে কার্যকর মেসেজ টার্গেটিং এবং বৈধ ডেলিভারি রিপোর্টিং নিশ্চিত করতে আপনি নিতে পারেন এমন কিছু পদক্ষেপ নিয়ে আলোচনা করা হয়েছে।

পুরনো এবং মেয়াদোত্তীর্ণ নিবন্ধন টোকেন

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

একটি টোকেন অকার্যকর হয়ে যাওয়ার বেশ কয়েকটি কারণ রয়েছে। উদাহরণস্বরূপ, টোকেনটি যে ডিভাইসের সাথে যুক্ত, সেটি হারিয়ে যেতে পারে, নষ্ট হয়ে যেতে পারে, অথবা সংরক্ষণে রেখে দেওয়ার পর তা ভুলে যাওয়া হতে পারে।

অ্যান্ড্রয়েডের ক্ষেত্রে, যখন কোনো পুরোনো টোকেন ২৭০ দিন ধরে নিষ্ক্রিয় থাকে, তখন FCM সেটিকে মেয়াদোত্তীর্ণ বলে গণ্য করে। একটি টোকেনের মেয়াদ শেষ হয়ে গেলে, FCM সেটিকে অবৈধ হিসেবে চিহ্নিত করে এবং সেটিতে পাঠানো বার্তা প্রত্যাখ্যান করে। তবে, এমন বিরল ক্ষেত্রে যদি ডিভাইসটি পুনরায় সংযুক্ত হয় এবং অ্যাপটি খোলা হয়, তাহলে FCM সেই অ্যাপ ইনস্ট্যান্সটির জন্য একটি নতুন টোকেন ইস্যু করে।

iOS-এর মতো অন্যান্য প্ল্যাটফর্মের জন্য, FCM অন্তর্নিহিত পুশ সার্ভিসের (যেমন, APNs) উপর নির্ভর করে, যেটিতে নিষ্ক্রিয়তার কারণে ২৭০ দিনের টোকেন মেয়াদোত্তীর্ণ হওয়ার নিয়ম নেই। তাই আমরা আপনাকে সক্রিয়ভাবে টোকেনের সতেজতা বজায় রাখতে এবং মেয়াদোত্তীর্ণ রেজিস্ট্রেশন টোকেনগুলি মুছে ফেলার পরামর্শ দিই।

মৌলিক সর্বোত্তম অনুশীলন

যেসব অ্যাপ প্রোগ্রাম্যাটিকভাবে প্রেরণের অনুরোধ তৈরি করতে FCM API ব্যবহার করে, সেগুলোর ক্ষেত্রে কিছু মৌলিক নিয়ম মেনে চলা উচিত। প্রধান সেরা নিয়মগুলো হলো:

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

নিবন্ধন টোকেনগুলি পুনরুদ্ধার এবং সংরক্ষণ করুন

আপনার অ্যাপটি প্রথমবার চালু করার সময়, FCM SDK ক্লায়েন্ট অ্যাপ ইনস্ট্যান্সের জন্য একটি রেজিস্ট্রেশন টোকেন তৈরি করে। এই টোকেনটিই আপনাকে API থেকে পাঠানো টার্গেটেড সেন্ড রিকোয়েস্টে অন্তর্ভুক্ত করতে হবে, অথবা টপিক টার্গেট করার জন্য টপিক সাবস্ক্রিপশনে যোগ করতে হবে।

আমরা দৃঢ়ভাবে সুপারিশ করছি যে আপনার অ্যাপটি প্রাথমিক স্টার্টআপের সময় এই টোকেনটি সংগ্রহ করবে এবং একটি টাইমস্ট্যাম্প সহ আপনার অ্যাপ সার্ভারে সংরক্ষণ করবে । এই টাইমস্ট্যাম্পটি আপনার কোড এবং সার্ভার দ্বারা প্রয়োগ করতে হবে, কারণ এটি FCM SDK-গুলো আপনাকে সরবরাহ করে না।

এছাড়াও, টোকেনটি সার্ভারে সংরক্ষণ করা এবং টাইমস্ট্যাম্প পরিবর্তিত হলে তা আপডেট করা গুরুত্বপূর্ণ, যেমন:

  • অ্যাপটি একটি নতুন ডিভাইসে পুনরুদ্ধার করা হয়েছে।
  • ব্যবহারকারী অ্যাপটি আনইনস্টল বা পুনরায় ইনস্টল করে।
  • ব্যবহারকারী অ্যাপের ডেটা মুছে ফেলেন
  • FCM এর বিদ্যমান টোকেনের মেয়াদ শেষ হয়ে গেলে অ্যাপটি পুনরায় সক্রিয় হয়।

উদাহরণ: Cloud Firestore টোকেন এবং টাইমস্ট্যাম্প সংরক্ষণ করুন

উদাহরণস্বরূপ, আপনি Cloud Firestore ব্যবহার করে fcmTokens নামের একটি কালেকশনে টোকেন সংরক্ষণ করতে পারেন। কালেকশনটির প্রতিটি ডকুমেন্ট আইডি একটি ইউজার আইডির সাথে সম্পর্কিত, এবং ডকুমেন্টটিতে বর্তমান রেজিস্ট্রেশন টোকেন ও তার সর্বশেষ আপডেটের টাইমস্ট্যাম্প সংরক্ষিত থাকে। এই কোটলিন উদাহরণে দেখানো অনুযায়ী set ফাংশনটি ব্যবহার করুন:

    /**
     * Persist token to third-party servers.
     *
     * Modify this method to associate the user's FCM registration token with any server-side account
     * maintained by your application.
     *
     * @param token The new token.
     */
    private fun sendTokenToServer(token: String?) {
        // If you're running your own server, call API to send token and today's date for the user

        // Example shown below with Firestore
        // Add token and timestamp to Firestore for this user
        val deviceToken = hashMapOf(
            "token" to token,
            "timestamp" to FieldValue.serverTimestamp(),
        )
        // Get user ID from Firebase Auth or your own server
        Firebase.firestore.collection("fcmTokens").document("myuserid")
            .set(deviceToken)
    }

যখনই কোনো টোকেন পুনরুদ্ধার করা হয়, sendTokenToServer কল করার মাধ্যমে সেটি Cloud Firestore সংরক্ষণ করা হয়:

    /**
     * Called if the FCM registration token is updated. This may occur if the security of
     * the previous token had been compromised. Note that this is called when the
     * FCM registration token is initially generated so this is where you would retrieve the token.
     */
    override fun onNewToken(token: String) {
        Log.d(TAG, "Refreshed token: $token")

        // If you want to send messages to this application instance or
        // manage this apps subscriptions on the server side, send the
        // FCM registration token to your app server.
        sendTokenToServer(token)
    }
        var token = Firebase.messaging.token.await()

        // Check whether the retrieved token matches the one on your server for this user's device
        val preferences = this.getPreferences(Context.MODE_PRIVATE)
        val tokenStored = preferences.getString("deviceToken", "")
        lifecycleScope.launch {
            if (tokenStored == "" || tokenStored != token)
            {
                // If you have your own server, call API to send the above token and Date() for this user's device

                // Example shown below with Firestore
                // Add token and timestamp to Firestore for this user
                val deviceToken = hashMapOf(
                    "token" to token,
                    "timestamp" to FieldValue.serverTimestamp(),
                )

                // Get user ID from Firebase Auth or your own server
                Firebase.firestore.collection("fcmTokens").document("myuserid")
                    .set(deviceToken).await()
            }
        }

টোকেনের সতেজতা বজায় রাখুন এবং মেয়াদোত্তীর্ণ টোকেনগুলি সরিয়ে ফেলুন

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

আপনার ব্যবহারের ধরনের ওপর নির্ভর করে এক মাস খুব কম বা খুব বেশি হতে পারে, তাই আপনার জন্য উপযুক্ত মানদণ্ড নির্ধারণ করার দায়িত্ব আপনারই।

FCM ব্যাকএন্ড থেকে অবৈধ টোকেন প্রতিক্রিয়া সনাক্ত করুন

FCM থেকে আসা অবৈধ টোকেন প্রতিক্রিয়াগুলি শনাক্ত করুন এবং আপনার সিস্টেম থেকে অবৈধ বা মেয়াদোত্তীর্ণ বলে পরিচিত যেকোনো রেজিস্ট্রেশন টোকেন মুছে দিয়ে তার প্রতিক্রিয়া জানান। HTTP v1 API-এর ক্ষেত্রে, এই ত্রুটির বার্তাগুলি নির্দেশ করতে পারে যে আপনার পাঠানো অনুরোধটি অবৈধ বা মেয়াদোত্তীর্ণ টোকেনকে লক্ষ্য করে করা হয়েছিল:

  • UNREGISTERED (HTTP 404)
  • INVALID_ARGUMENT (HTTP 400)

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

    // Registration token comes from the client FCM SDKs
    const registrationToken = 'YOUR_REGISTRATION_TOKEN';

    const message = {
    data: {
        // Information you want to send inside of notification
    },
    token: registrationToken
    };

    // Send message to device with provided registration token
    getMessaging().send(message)
    .then((response) => {
        // Response is a message ID string.
    })
    .catch((error) => {
        // Delete token for user if error code is UNREGISTERED or INVALID_ARGUMENT.
        if (error.errorCode == "messaging/registration-token-not-registered") {
            // If you're running your own server, call API to delete the
            token for the user

            // Example shown below with Firestore
            // Get user ID from Firebase Auth or your own server
            Firebase.firestore.collection("fcmTokens").document(user.uid).delete()
        }
    });

যদি কোনো অ্যান্ড্রয়েড ডিভাইসের টোকেন ২৭০ দিন নিষ্ক্রিয় থাকার পর মেয়াদোত্তীর্ণ হয়ে যায়, অথবা যদি কোনো ক্লায়েন্ট স্পষ্টভাবে নিবন্ধন বাতিল করে, তাহলে FCM একটি অবৈধ টোকেন প্রতিক্রিয়া ফেরত দেয়। আপনার নিজস্ব সংজ্ঞা অনুযায়ী মেয়াদোত্তীর্ণ অবস্থা আরও সঠিকভাবে ট্র্যাক করার প্রয়োজন হলে, আপনি সক্রিয়ভাবে মেয়াদোত্তীর্ণ রেজিস্ট্রেশন টোকেনগুলি সরিয়ে ফেলতে পারেন।

নিয়মিতভাবে টোকেন আপডেট করুন

আমরা আপনাকে আপনার সার্ভারে থাকা সমস্ত রেজিস্ট্রেশন টোকেন পর্যায়ক্রমে পুনরুদ্ধার এবং আপডেট করার পরামর্শ দিই। এর জন্য আপনাকে যা করতে হবে তা হলো:

  • আপনার ক্লায়েন্ট অ্যাপে উপযুক্ত এপিআই কল (যেমন অ্যাপল প্ল্যাটফর্মের জন্য token(completion): অথবা অ্যান্ড্রয়েডের জন্য getToken() ) ব্যবহার করে বর্তমান টোকেনটি পুনরুদ্ধার করার জন্য অ্যাপ লজিক যোগ করুন এবং তারপর সংরক্ষণের জন্য বর্তমান টোকেনটি (একটি টাইমস্ট্যাম্প সহ) আপনার অ্যাপ সার্ভারে পাঠান। এটি একটি মাসিক কাজ হতে পারে যা সমস্ত ক্লায়েন্ট বা টোকেনকে অন্তর্ভুক্ত করার জন্য কনফিগার করা হয়েছে।
  • টোকেন পরিবর্তিত হয়েছে কি না, তা নির্বিশেষে নিয়মিত বিরতিতে টোকেনের টাইমস্ট্যাম্প আপডেট করার জন্য সার্ভার লজিক যোগ করুন।

WorkManager ব্যবহার করে টোকেন আপডেট করার অ্যান্ড্রয়েড লজিকের উদাহরণের জন্য, Firebase ব্লগে “Managing Cloud Messaging Tokens” দেখুন।

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

মেয়াদোত্তীর্ণ নিবন্ধন টোকেনগুলি মুছে ফেলুন

কোনো ডিভাইসে মেসেজ পাঠানোর আগে, নিশ্চিত করুন যে ডিভাইসটির রেজিস্ট্রেশন টোকেনের টাইমস্ট্যাম্পটি আপনার নির্ধারিত মেয়াদোত্তীর্ণ টোকেন সময়ের মধ্যে আছে। উদাহরণস্বরূপ, আপনি Cloud Functions for Firebase ব্যবহার করে একটি দৈনিক চেক চালাতে পারেন, যা নিশ্চিত করবে যে টাইমস্ট্যাম্পটি একটি নির্দিষ্ট মেয়াদোত্তীর্ণ টোকেন সময়ের মধ্যে আছে, যেমন: const EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30; এবং তারপর মেয়াদোত্তীর্ণ টোকেনগুলো মুছে ফেলতে পারেন।

exports.pruneTokens = functions.pubsub.schedule('every 24 hours').onRun(async (context) => {
  // Get all documents where the timestamp exceeds is not within the past month
  const staleTokensResult = await admin.firestore().collection('fcmTokens')
      .where("timestamp", "<", Date.now() - EXPIRATION_TIME)
      .get();
  // Delete devices with stale tokens
  staleTokensResult.forEach(function(doc) { doc.ref.delete(); });
});

টপিক থেকে মেয়াদোত্তীর্ণ টোকেন আনসাবস্ক্রাইব করুন

আপনি যদি টপিক ব্যবহার করেন, তাহলে যে টপিকগুলোতে টোকেনগুলো সাবস্ক্রাইব করা আছে, সেখান থেকে মেয়াদোত্তীর্ণ টোকেনগুলো অনিবন্ধিত করতে চাইতে পারেন। এর জন্য দুটি ধাপ অনুসরণ করতে হয়:

  1. আপনার অ্যাপটিকে মাসে একবার এবং যখনই রেজিস্ট্রেশন টোকেন পরিবর্তিত হবে, তখন টপিকগুলোতে পুনরায় সাবস্ক্রাইব করতে হবে। এটি একটি স্ব-নিরাময়কারী সমাধান তৈরি করে, যেখানে অ্যাপটি আবার সক্রিয় হলে সাবস্ক্রিপশনগুলো স্বয়ংক্রিয়ভাবে পুনরায় প্রদর্শিত হয়।
  2. যদি কোনো অ্যাপ ইনস্ট্যান্স এক মাস ধরে (বা আপনার নির্ধারিত নিষ্ক্রিয়তার সময়সীমা পর্যন্ত) নিষ্ক্রিয় থাকে, তাহলে FCM ব্যাকএন্ড থেকে টোকেন-টু-টপিক ম্যাপিং মুছে ফেলার জন্য Firebase Admin SDK ব্যবহার করে সেটিকে টপিকগুলো থেকে আনসাবস্ক্রাইব করা উচিত।

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

ডেলিভারির সাফল্য পরিমাপ করুন

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

কোনো টোকেনে বার্তা পাঠানোর আগে নিম্নলিখিত বিষয়গুলো বিবেচনা করুন:

  • Google Analytics, BigQuery-তে সংগৃহীত ডেটা, বা অন্যান্য ট্র্যাকিং সংকেত কি টোকেনটির সক্রিয়তা নির্দেশ করে?
  • পূর্ববর্তী ডেলিভারির প্রচেষ্টাগুলো কি দীর্ঘ সময় ধরে ধারাবাহিকভাবে ব্যর্থ হয়েছে?
  • গত এক মাসে আপনাদের সার্ভারে রেজিস্ট্রেশন টোকেনটি কি আপডেট করা হয়েছে?
  • অ্যান্ড্রয়েড ডিভাইসগুলোর ক্ষেত্রে, droppedDeviceInactive এর কারণে FCM ডেটা API কি উচ্চ হারে বার্তা বিতরণে ব্যর্থতা রিপোর্ট করে?

ডেলিভারি সম্পর্কে আরও তথ্যের জন্য, ‘মেসেজ ডেলিভারি বোঝা’ দেখুন।