أفضل الممارسات لإدارة الرموز المميّزة للتسجيل في خدمة "المراسلة عبر السحابة الإلكترونية من Firebase"

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

الرموز المميّزة للتسجيل القديمة والمنتهية الصلاحية

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

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

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

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

هناك بعض الممارسات الأساسية التي يجب اتّباعها في أي تطبيق يستخدم واجهات برمجة تطبيقات "المراسلة عبر السحابة الإلكترونية من Firebase" لإنشاء طلبات الإرسال بشكل آلي. أفضل الممارسات الأساسية هي:

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

استرداد الرموز المميّزة للتسجيل وتخزينها

عند بدء تشغيل التطبيق للمرة الأولى، تُنشئ حزمة تطوير البرامج (SDK) لخدمة "المراسلة عبر السحابة الإلكترونية من Firebase" رمزًا مميّزًا للتسجيل لمثيل تطبيق العميل. وهذا هو الرمز المميّز الذي يجب تضمينه في طلبات الإرسال المستهدَفة من واجهة برمجة التطبيقات أو إضافته إلى اشتراكات المواضيع لاستهداف المواضيع.

ننصحك بشدة باسترداد هذا الرمز المميّز عند بدء التشغيل الأوّلي وحفظه في خادم تطبيقك بجانب طابع زمني. يجب أن يتم تنفيذ هذا الطابع الزمني من خلال الرمز البرمجي والخوادم، لأنّ حزم تطوير البرامج (SDK) الخاصة بخدمة "المراسلة عبر السحابة الإلكترونية من Firebase" غير متوفرة لك.

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

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

مثال: الرموز المميّزة للمتجر والطوابع الزمنية في 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()
            }
        }

الحفاظ على حداثة الرموز المميّزة وإزالة الرموز المميّزة القديمة

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

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

اكتشاف الاستجابات للرموز المميّزة غير الصالحة من واجهة "المراسلة عبر السحابة الإلكترونية من Firebase" الخلفية

تأكَّد من رصد الاستجابات للرموز المميّزة غير الصالحة من خدمة "المراسلة عبر السحابة الإلكترونية من Firebase" والتعامل معها من خلال حذف أي رموز مميَّزة للتسجيل تُعرف بأنها غير صالحة أو انتهت صلاحيتها من نظامك. من خلال واجهة برمجة التطبيقات 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 (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()
        }
    });

لن تعرض خدمة "المراسلة عبر السحابة الإلكترونية من Firebase" استجابة رمز مميّز غير صالح إلا في حال انتهاء صلاحية الرمز المميّز بعد 270 يومًا أو في حال إلغاء تسجيل العميل صراحةً. إذا كنت بحاجة إلى تتبُّع تلف البيانات بدقّة أكبر وفقًا لتعريفاتك، يمكنك إزالة الرموز المميّزة للتسجيل القديمة بشكلٍ استباقي.

تعديل الرموز المميّزة بشكل منتظم

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

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

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

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

إزالة الرموز المميّزة للتسجيل القديمة

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

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

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

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

قبل استهداف الرسائل برمز مميّز، ضَع في اعتبارك ما يلي:

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

لمزيد من المعلومات عن التسليم، يُرجى الاطِّلاع على مقالة فهم تسليم الرسائل.