एफसीएम पंजीकरण टोकन प्रबंधन के लिए सर्वोत्तम अभ्यास

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

बासी और समाप्त हो चुके पंजीकरण टोकन

बासी पंजीकरण टोकन निष्क्रिय उपकरणों से जुड़े टोकन हैं जो एक महीने से अधिक समय से एफसीएम से कनेक्ट नहीं हुए हैं। जैसे-जैसे समय बीतता है, डिवाइस के दोबारा एफसीएम से कनेक्ट होने की संभावना कम होती जाती है। इन पुराने टोकन के लिए संदेश भेजने और विषय फ़ैनआउट कभी भी वितरित होने की संभावना नहीं है।

ऐसे कई कारण हैं जिनकी वजह से कोई टोकन पुराना हो सकता है। उदाहरण के लिए, जिस डिवाइस से टोकन जुड़ा हुआ है वह खो सकता है, नष्ट हो सकता है, या भंडारण में रखा जा सकता है और भुला दिया जा सकता है।

जब पुराने टोकन निष्क्रियता के 270 दिनों तक पहुंच जाएंगे, तो एफसीएम उन्हें समाप्त टोकन मान लेगा। एक बार जब कोई टोकन समाप्त हो जाता है, तो एफसीएम इसे अमान्य के रूप में चिह्नित करता है और इसे भेजे जाने को अस्वीकार कर देता है। हालाँकि, एफसीएम उस दुर्लभ स्थिति में ऐप इंस्टेंस के लिए एक नया टोकन जारी करता है जब डिवाइस फिर से कनेक्ट होता है और ऐप खुल जाता है।

बुनियादी सर्वोत्तम प्रथाएँ

कुछ बुनियादी प्रथाएं हैं जिनका आपको किसी भी ऐप में पालन करना चाहिए जो प्रोग्रामेटिक रूप से अनुरोध भेजने के लिए एफसीएम एपीआई का उपयोग करता है। मुख्य सर्वोत्तम प्रथाएँ हैं:

  • एफसीएम से पंजीकरण टोकन प्राप्त करें और उन्हें अपने सर्वर पर संग्रहीत करें। सर्वर के लिए एक महत्वपूर्ण भूमिका प्रत्येक ग्राहक के टोकन का ट्रैक रखना और सक्रिय टोकन की एक अद्यतन सूची रखना है। हम आपके कोड और आपके सर्वर में एक टोकन टाइमस्टैम्प लागू करने और नियमित अंतराल पर इस टाइमस्टैम्प को अपडेट करने की दृढ़ता से अनुशंसा करते हैं।
  • टोकन की ताजगी बनाए रखें और पुराने टोकन हटा दें। उन टोकन को हटाने के अलावा जिन्हें एफसीएम अब वैध नहीं मानता है, आप अन्य संकेतों की निगरानी करना चाह सकते हैं कि टोकन पुराने हो गए हैं और उन्हें सक्रिय रूप से हटा दें। यह मार्गदर्शिका इसे प्राप्त करने के लिए आपके कुछ विकल्पों पर चर्चा करती है।

पंजीकरण टोकन पुनर्प्राप्त करें और संग्रहीत करें

आपके ऐप के प्रारंभिक स्टार्टअप पर, एफसीएम एसडीके क्लाइंट ऐप इंस्टेंस के लिए एक पंजीकरण टोकन उत्पन्न करता है। यह वह टोकन है जिसे आपको एपीआई से लक्षित प्रेषण अनुरोधों में शामिल करना होगा, या विषयों को लक्षित करने के लिए विषय सदस्यता में जोड़ना होगा।

हम दृढ़तापूर्वक अनुशंसा करते हैं कि आपका ऐप प्रारंभिक स्टार्टअप पर इस टोकन को पुनः प्राप्त करें और इसे टाइमस्टैम्प के साथ अपने ऐप सर्वर पर सहेजें। यह टाइमस्टैम्प आपके कोड और आपके सर्वर द्वारा कार्यान्वित किया जाना चाहिए, क्योंकि यह आपके लिए एफसीएम एसडीके द्वारा प्रदान नहीं किया गया है।

साथ ही, टोकन को सर्वर पर सहेजना और टाइमस्टैम्प में जब भी बदलाव हो, उसे अपडेट करना महत्वपूर्ण है, जैसे कि कब:

  • ऐप को एक नए डिवाइस पर पुनर्स्थापित किया गया है
  • उपयोगकर्ता ऐप को अनइंस्टॉल या पुनः इंस्टॉल करता है
  • उपयोगकर्ता ऐप डेटा साफ़ करता है
  • एफसीएम का मौजूदा टोकन समाप्त होने के बाद ऐप फिर से सक्रिय हो जाता है

उदाहरण: क्लाउड फायरस्टोर में टोकन और टाइमस्टैम्प स्टोर करें

उदाहरण के लिए, आप 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 पर कॉल करके क्लाउड फायरस्टोर में संग्रहीत किया जाता है:

    /**
     * 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 किसी टोकन को पुराना मानता है यदि उसका ऐप इंस्टेंस एक महीने से कनेक्ट नहीं हुआ है। एक महीने से अधिक पुराना कोई भी टोकन निष्क्रिय डिवाइस होने की संभावना है; एक सक्रिय उपकरण अन्यथा अपने टोकन को ताज़ा कर देता।

आपके उपयोग के मामले के आधार पर, एक महीना बहुत छोटा या बहुत लंबा हो सकता है, इसलिए यह आप पर निर्भर है कि आप कौन सा मानदंड निर्धारित करते हैं जो आपके लिए काम करता है।

एफसीएम बैकएंड से अमान्य टोकन प्रतिक्रियाओं का पता लगाएं

एफसीएम से अमान्य टोकन प्रतिक्रियाओं का पता लगाना सुनिश्चित करें और अपने सिस्टम से किसी भी पंजीकरण टोकन को हटाकर प्रतिक्रिया दें जो अमान्य माना जाता है या समाप्त हो गया है। HTTP v1 API के साथ, ये त्रुटि संदेश संकेत दे सकते हैं कि आपके भेजने के अनुरोध ने अमान्य या समाप्त टोकन को लक्षित किया है:

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

यदि आप निश्चित हैं कि संदेश पेलोड वैध है और आपको लक्षित टोकन के लिए इनमें से कोई भी प्रतिक्रिया प्राप्त होती है, तो इस टोकन के अपने रिकॉर्ड को हटाना सुरक्षित है, क्योंकि यह फिर कभी मान्य नहीं होगा। उदाहरण के लिए, क्लाउड फायरस्टोर से अमान्य टोकन हटाने के लिए, आप निम्न जैसा फ़ंक्शन तैनात और चला सकते हैं:

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

एफसीएम केवल एक अमान्य टोकन प्रतिक्रिया लौटाएगा यदि टोकन 270 दिनों के बाद समाप्त हो गया है या यदि कोई ग्राहक स्पष्ट रूप से अपंजीकृत है। यदि आपको अपनी परिभाषाओं के अनुसार बासीपन को अधिक सटीक रूप से ट्रैक करने की आवश्यकता है, तो आप सक्रिय रूप से बासी पंजीकरण टोकन हटा सकते हैं।

नियमित आधार पर टोकन अपडेट करें

हम अनुशंसा करते हैं कि आप समय-समय पर अपने सर्वर पर सभी पंजीकरण टोकन पुनर्प्राप्त और अद्यतन करें। इसके लिए आपको यह आवश्यक है:

  • उपयुक्त एपीआई कॉल (जैसे token(completion): ऐप्पल प्लेटफ़ॉर्म के लिए या एंड्रॉइड के लिए getToken() ) का उपयोग करके वर्तमान टोकन को पुनः प्राप्त करने के लिए अपने क्लाइंट ऐप में ऐप लॉजिक जोड़ें और फिर स्टोरेज के लिए अपने ऐप सर्वर पर वर्तमान टोकन भेजें (एक के साथ) टाइमस्टैम्प)। यह सभी ग्राहकों या टोकन को कवर करने के लिए कॉन्फ़िगर किया गया एक मासिक कार्य हो सकता है।
  • टोकन के टाइमस्टैम्प को नियमित अंतराल पर अपडेट करने के लिए सर्वर लॉजिक जोड़ें, भले ही टोकन बदल गया हो या नहीं।

वर्कमैनेजर का उपयोग करके टोकन अपडेट करने के लिए एंड्रॉइड लॉजिक के उदाहरण के लिए, फायरबेस ब्लॉग पर क्लाउड मैसेजिंग टोकन प्रबंधित करना देखें।

आप जो भी समय पैटर्न अपनाएं, समय-समय पर टोकन अपडेट करना सुनिश्चित करें। प्रति माह एक बार अद्यतन आवृत्ति बैटरी प्रभाव और निष्क्रिय पंजीकरण टोकन का पता लगाने के बीच एक अच्छा संतुलन बनाती है। इस रिफ्रेश को करके, आप यह भी सुनिश्चित करते हैं कि कोई भी उपकरण जो निष्क्रिय हो जाता है वह दोबारा सक्रिय होने पर अपना पंजीकरण रिफ्रेश करेगा। साप्ताहिक से अधिक बार रिफ्रेश करने का कोई लाभ नहीं है।

पुराने पंजीकरण टोकन हटाएँ

किसी डिवाइस पर संदेश भेजने से पहले, सुनिश्चित करें कि डिवाइस के पंजीकरण टोकन का टाइमस्टैम्प आपकी निष्क्रियता विंडो अवधि के भीतर है। उदाहरण के लिए, आप यह सुनिश्चित करने के लिए दैनिक जांच चलाने के लिए फायरबेस के लिए क्लाउड फ़ंक्शंस लागू कर सकते हैं कि टाइमस्टैम्प एक परिभाषित स्थिरता विंडो अवधि के भीतर है जैसे 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. यदि कोई ऐप इंस्टेंस एक महीने के लिए निष्क्रिय है (या आपकी खुद की स्टेलनेस विंडो) तो आपको एफसीएम बैकएंड से टोकन टू टॉपिक मैपिंग को हटाने के लिए फायरबेस एडमिन एसडीके का उपयोग करके इसे विषयों से अनसब्सक्राइब करना चाहिए।

इन दो चरणों का लाभ यह है कि आपके फ़ैनआउट तेज़ी से होंगे क्योंकि फ़ैन आउट करने के लिए कम पुराने टोकन हैं, और आपके पुराने ऐप इंस्टेंसेस फिर से सक्रिय होने पर स्वचालित रूप से पुनः सदस्यता ले लेंगे।

डिलीवरी की सफलता को मापें

संदेश वितरण की सबसे सटीक तस्वीर प्राप्त करने के लिए, केवल सक्रिय रूप से उपयोग किए जाने वाले ऐप इंस्टेंसेस पर ही संदेश भेजना सबसे अच्छा है। यह विशेष रूप से महत्वपूर्ण है यदि आप नियमित रूप से बड़ी संख्या में ग्राहकों वाले विषयों पर संदेश भेजते हैं; यदि उन ग्राहकों का एक हिस्सा वास्तव में निष्क्रिय है, तो आपके डिलीवरी आंकड़ों पर प्रभाव समय के साथ महत्वपूर्ण हो सकता है।

संदेशों को किसी टोकन पर लक्षित करने से पहले, विचार करें:

  • क्या Google Analytics, BigQuery में कैप्चर किया गया डेटा, या अन्य ट्रैकिंग सिग्नल इंगित करते हैं कि टोकन सक्रिय है?
  • क्या पिछले डिलीवरी प्रयास समय के साथ लगातार विफल रहे हैं?
  • क्या पिछले महीने आपके सर्वर पर पंजीकरण टोकन अपडेट किया गया है?
  • एंड्रॉइड उपकरणों के लिए, क्या एफसीएम डेटा एपीआई droppedDeviceInactive के कारण संदेश वितरण विफलताओं के उच्च प्रतिशत की रिपोर्ट करता है?

डिलीवरी के बारे में अधिक जानकारी के लिए, संदेश डिलीवरी को समझना देखें।