أفضل الممارسات لإدارة الرمز المميز لتسجيل FCM

إذا كنت تستخدم واجهات برمجة تطبيقات FCM لإنشاء طلبات إرسال برمجيًا ، فقد تجد أنك ، بمرور الوقت ، تهدر الموارد عن طريق إرسال رسائل إلى أجهزة غير نشطة برموز تسجيل قديمة. يمكن أن يؤثر هذا الموقف على بيانات تسليم الرسائل التي تم الإبلاغ عنها في وحدة تحكم Firebase أو البيانات التي تم تصديرها إلى BigQuery ، والتي تظهر على أنها انخفاض كبير (ولكن ليس صحيحًا في الواقع) في معدلات التسليم. يناقش هذا الدليل بعض الإجراءات التي يمكنك اتخاذها للمساعدة في ضمان استهداف الرسائل بكفاءة وإعداد تقارير تسليم صحيحة.

أفضل الممارسات الأساسية

هناك بعض الممارسات الأساسية التي يجب عليك اتباعها في أي تطبيق يستخدم واجهات برمجة تطبيقات FCM لإنشاء طلبات الإرسال برمجيًا. أفضل الممارسات الرئيسية هي:

  • تخزين الرموز المميزة للتسجيل على الخادم الخاص بك. يتمثل الدور المهم للخادم في تتبع الرموز المميزة لكل عميل والاحتفاظ بقائمة محدثة من الرموز المميزة النشطة. نوصي بشدة بتطبيق طابع زمني مميز في شفرتك وخوادمك ، وتحديث هذا الطابع الزمني على فترات منتظمة.
  • قم بإزالة الرموز المميزة المخزنة التي أصبحت قديمة . بالإضافة إلى إزالة الرموز المميزة في الحالات الواضحة لاستجابات الرمز المميز غير الصالحة ، ستحتاج على الأرجح إلى مراقبة العلامات الأخرى التي تدل على أن الرمز المميز قديم. يناقش هذا الدليل بعض الخيارات المتاحة أمامك لتحقيق ذلك.

استرجاع وتخزين الرموز المميزة للتسجيل

عند بدء التشغيل الأولي لتطبيقك ، تنشئ FCM SDK رمزًا مميزًا للتسجيل لمثيل تطبيق العميل. هذا هو الرمز المميز الذي يجب عليك تضمينه في طلبات الإرسال المستهدفة من واجهة برمجة التطبيقات ، أو إضافته إلى اشتراكات الموضوعات لمواضيع الاستهداف.

كما هو مذكور في أدلة إعداد العميل لدينا ، يجب أن يسترد تطبيقك هذا الرمز المميز عند بدء التشغيل الأولي وحفظه في خادم التطبيق الخاص بك جنبًا إلى جنب مع طابع زمني . يجب أن يتم تنفيذ هذا الطابع الزمني من خلال التعليمات البرمجية الخاصة بك وخوادمك ، حيث لا يتم توفيره لك بواسطة FCM SDKs.

من المهم أيضًا حفظ الرمز المميز على الخادم وتحديث الطابع الزمني متى تغير ، مثل عندما:

  • تمت استعادة التطبيق على جهاز جديد
  • يقوم المستخدم بإلغاء تثبيت / إعادة تثبيت التطبيق
  • يقوم المستخدم بمسح بيانات التطبيق.

مثال: تخزين الرموز والطوابع الزمنية في Cloud Firestore

على سبيل المثال ، يمكنك استخدام Cloud Firestore لتخزين الرموز المميزة في مجموعة تسمى fcmTokens . يتوافق كل معرف مستند في المجموعة مع معرف المستخدم ، ويخزن المستند رمز التسجيل المميز الحالي والطابع الزمني الأخير الذي تم تحديثه. استخدم وظيفة set كما هو موضح في مثال Kotlin هذا:

    /**
     * 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)
    }

عندما يتم استرداد رمز مميز ، يتم تخزينه في Cloud Firestore عن طريق استدعاء 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

تأكد من اكتشاف استجابات الرمز المميز غير الصالحة من FCM والرد عن طريق حذف أي رموز مميزة للتسجيل من النظام الخاص بك والتي من المعروف أنها غير صالحة. باستخدام واجهة برمجة تطبيقات HTTP v1 ، قد تشير رسائل الخطأ هذه إلى أن طلب الإرسال الخاص بك يستهدف الرموز المميزة التي لا معنى لها أو غير الصالحة:

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

لاحظ أنه نظرًا لأنه يتم طرح INVALID_ARGUMENT أيضًا في حالات المشكلات في حمولة الرسالة ، فإنه يشير إلى رمز مميز غير صالح فقط إذا كانت الحمولة صالحة تمامًا. انظر أكواد الخطأ لمزيد من المعلومات.

إذا كنت متأكدًا من أن حمولة الرسالة صالحة وتلقيت أيًا من هذه الاستجابات لرمز مستهدف ، فمن الآمن حذف السجل الخاص بك من هذا الرمز المميز ، لأنه لن يكون صالحًا مرة أخرى أبدًا. على سبيل المثال ، لحذف الرموز المميزة غير الصالحة من 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 (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()
        }
    });

ضمان حداثة رمز التسجيل

لا يعد تحديد ما إذا كان الرمز المميز حديثًا أم قديمًا أمرًا سهلاً دائمًا. لتغطية جميع الحالات ، يجب عليك اعتماد حد عند اعتبار الرموز التي لا معنى لها ؛ توصيتنا شهرين. من المحتمل أن يكون أي رمز مضى عليه أكثر من شهرين جهازًا غير نشط ؛ كان من الممكن أن يقوم الجهاز النشط بتحديث رمزه المميز.

تحديث الرموز على أساس منتظم

نوصي باسترداد وتحديث جميع رموز التسجيل على الخادم الخاص بك بشكل دوري. هذا يتطلب منك:

  • أضف منطق التطبيق في تطبيق العميل الخاص بك لاسترداد الرمز المميز الحالي باستخدام استدعاء API المناسب (مثل token(completion): لأنظمة Apple أو getToken() لنظام Android) ثم أرسل الرمز المميز الحالي إلى خادم التطبيق الخاص بك للتخزين (مع طابع زمني ). قد تكون هذه وظيفة شهرية تم تكوينها لتغطية جميع العملاء / الرموز المميزة.
  • أضف منطق الخادم لتحديث الطابع الزمني للرمز المميز على فترات منتظمة ، بغض النظر عما إذا كان الرمز المميز قد تغير أم لا.

للحصول على مثال لمنطق Android لتحديث الرموز المميزة باستخدام WorkManager ، راجع إدارة رموز المراسلة السحابية على مدونة Firebase.

مهما كان نمط التوقيت الذي تتبعه ، تأكد من تحديث الرموز بشكل دوري. من المحتمل أن يؤدي تكرار التحديث مرة واحدة كل شهرين إلى توازن جيد بين تأثير البطارية مقابل اكتشاف الرموز المميزة للتسجيل غير النشط. من خلال القيام بهذا التحديث ، فإنك تضمن أيضًا أن أي جهاز يصبح غير نشط سيقوم بتحديث تسجيله عندما يصبح نشطًا مرة أخرى. لا توجد فائدة من إجراء التحديث بشكل متكرر أكثر من أسبوعيًا.

إزالة الرموز المميزة للتسجيل التي لا معنى لها

قبل إرسال الرسائل إلى أحد الأجهزة ، تأكد من أن الطابع الزمني لرمز تسجيل الجهاز يقع ضمن فترة نافذة الجمود. على سبيل المثال ، يمكنك تنفيذ وظائف السحابة لـ Firebase لإجراء فحص يومي للتأكد من أن الطابع الزمني يقع ضمن فترة نافذة ثابتة محددة مثل const EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 60; ثم قم بإزالة الرموز التي لا معنى لها:

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. إذا كان مثيل التطبيق في وضع الخمول لمدة شهرين (أو نافذة التوقف الخاصة بك) ، فيجب عليك إلغاء الاشتراك في الموضوعات التي تستخدم Firebase Admin SDK لحذف تعيين الرمز المميز / الموضوع من الواجهة الخلفية لـ FCM.

تكمن فائدة هاتين الخطوتين في أن المعجبين لديك سيحدثون بشكل أسرع نظرًا لوجود عدد أقل من الرموز المميزة التي لا معنى لها للتوزيع عليها ، وستتم إعادة الاشتراك في مثيلات التطبيق القديمة تلقائيًا بمجرد تنشيطها مرة أخرى.

قياس نجاح التسليم

بشكل عام ، ننصح باستهداف الرسائل بناءً على الإجراءات التي تمت ملاحظتها أو التقاطها من مثيلات التطبيق المستخدمة بشكل نشط. هذا مهم بشكل خاص إذا كنت ترسل رسائل بانتظام إلى مواضيع بها أعداد كبيرة من المشتركين ؛ إذا كان جزء من هؤلاء المشتركين غير نشطين بالفعل ، فقد يكون التأثير على إحصائيات التوصيل الخاصة بك كبيرًا بمرور الوقت.

قبل توجيه الرسائل إلى رمز مميز ، ضع في اعتبارك:

  • هل تشير Google Analytics أو البيانات الملتقطة في BigQuery أو إشارات التتبع الأخرى إلى أن الرمز المميز نشط؟
  • هل فشلت محاولات التسليم السابقة باستمرار على مدار فترة زمنية؟
  • هل تم تحديث رمز التسجيل على خوادمك في الشهرين الماضيين؟
  • بالنسبة لأجهزة Android ، هل تبلغ واجهة برمجة تطبيقات بيانات FCM عن نسبة عالية من حالات فشل تسليم الرسائل بسبب droppedDeviceInactive ؟

لمزيد من المعلومات حول التسليم ، راجع فهم تسليم الرسائل .