إذا كنت تستخدم واجهات برمجة التطبيقات FCM لإنشاء طلبات الإرسال آليًا، قد تلاحظ بمرور الوقت أنّك تهدر الموارد من خلال إرسال الرسائل إلى الأجهزة غير النشطة التي تتضمّن رموز تسجيل قديمة. يمكن أن يؤثّر هذا الموقف في بيانات تسليم الرسائل التي يتم عرضها في وحدة تحكّم Firebase أو البيانات التي يتم تصديرها إلى BigQuery، ما يؤدي إلى انخفاض كبير (ولكن غير صالح فعليًا) في معدّلات التسليم. يناقش هذا الدليل بعض الإجراءات التي يمكنك اتّخاذها للمساعدة في ضمان استهداف الرسائل بكفاءة وإعداد تقارير صالحة عن التسليم.
رموز التسجيل القديمة والمنتهية الصلاحية
رموز التسجيل القديمة هي رموز مميزة مرتبطة بأجهزة غير نشطة لم تتصل بخدمة FCM لأكثر من شهر. ومع مرور الوقت، تقل احتمالية اتصال الجهاز بشبكة FCM مرة أخرى. ومن غير المحتمل أن يتم تسليم الرسائل وعمليات إرسال المواضيع إلى عدة أجهزة باستخدام الرموز المميزة القديمة.
هناك عدة أسباب قد تؤدي إلى انتهاء صلاحية الرمز المميز. على سبيل المثال، قد يتم فقدان الجهاز المرتبط بالرمز المميّز أو إتلافه أو وضعه في مكان للتخزين ثم نسيانه.
عندما تصل رموز الدخول غير النشطة إلى 270 يومًا من عدم النشاط، ستعتبرها FCM رموز دخول منتهية الصلاحية. بعد انتهاء صلاحية الرمز المميز، يضع FCM علامة عليه كرمز غير صالح ويرفض إرسال الرسائل إليه. ومع ذلك، FCM تصدر رمزًا مميزًا جديدًا لمثيل التطبيق في الحالة النادرة التي يعود فيها الجهاز إلى الاتصال بالإنترنت ويتم فتح التطبيق.
أفضل الممارسات الأساسية
هناك بعض الممارسات الأساسية التي يجب اتّباعها في أي تطبيق يستخدم واجهات برمجة التطبيقات FCM لإنشاء طلبات الإرسال آليًا. في ما يلي أفضل الممارسات الرئيسية:
- استرداد رموز التسجيل من FCM وتخزينها على الخادم يتمثّل أحد الأدوار المهمة للخادم في تتبُّع الرمز المميّز لكل عميل والاحتفاظ بقائمة محدّثة بالرموز المميّزة النشطة. ننصحك بشدة بتنفيذ طابع زمني للرمز المميّز في الرمز البرمجي والخوادم، وتعديل هذا الطابع الزمني على فترات منتظمة.
- الحفاظ على حداثة الرموز المميزة وإزالة الرموز القديمة: بالإضافة إلى إزالة الرموز المميزة التي لم يعُد يعتبرها FCM صالحة، ننصحك بمراقبة المؤشرات الأخرى التي تدل على أنّ الرموز المميزة أصبحت قديمة وإزالتها بشكل استباقي. يناقش هذا الدليل بعض الخيارات المتاحة لتحقيق ذلك.
استرداد رموز التسجيل وتخزينها
عند بدء تشغيل تطبيقك لأول مرة، تنشئ حزمة تطوير البرامج (SDK) FCM رمز تسجيل لنسخة تطبيق العميل. هذا هو الرمز المميّز الذي يجب تضمينه في طلبات الإرسال المستهدَفة من واجهة برمجة التطبيقات، أو إضافته إلى اشتراكات المواضيع لاستهداف المواضيع.
ننصح بشدة بأن يسترد تطبيقك هذا الرمز المميز عند بدء التشغيل الأوّلي وأن يحفظه على خادم تطبيقك مع الطابع الزمني. يجب أن يتم تنفيذ الطابع الزمني من خلال الرمز البرمجي والخوادم، لأنّ حِزم تطوير البرامج (SDK) من FCM لا توفّره لك.
من المهم أيضًا حفظ الرمز المميز على الخادم وتعديل الطابع الزمني كلما تغيّر، مثلاً في الحالات التالية:
- تمت استعادة التطبيق على جهاز جديد
- ألغى المستخدم تثبيت التطبيق أو أعاد تثبيته
- يمحو المستخدم بيانات التطبيق
- يصبح التطبيق نشطًا مرة أخرى بعد انتهاء صلاحية الرمز المميز الحالي بعد FCM
مثال: تخزين الرموز المميزة والطوابع الزمنية في 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
احرص على رصد الردود غير الصالحة للرموز المميزة من FCM والرد عليها من خلال حذف أي رموز مميزة للتسجيل معروف أنّها غير صالحة أو انتهت صلاحيتها من نظامك. باستخدام الإصدار 1 من واجهة برمجة تطبيقات HTTP، قد تشير رسائل الخطأ هذه إلى أنّ طلب الإرسال يستهدف رموزًا مميّزة غير صالحة أو منتهية الصلاحية:
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()
}
});
لن تعرض FCM استجابة رمز مميّز غير صالح إلا إذا انتهت صلاحية الرمز المميّز بعد 270 يومًا أو إذا ألغى العميل التسجيل بشكل صريح. إذا كنت بحاجة إلى تتبُّع حالة عدم الصلاحية بدقة أكبر وفقًا لتعريفاتك الخاصة، يمكنك إزالة رموز التسجيل غير الصالحة بشكل استباقي.
تعديل الرموز المميّزة بانتظام
ننصحك باسترجاع جميع رموز التسجيل وتعديلها بشكل دوري على الخادم. يتطلّب ذلك منك ما يلي:
- أضِف منطق التطبيق في تطبيق العميل لاسترداد الرمز المميّز الحالي باستخدام طلب البيانات المناسب من واجهة برمجة التطبيقات (مثل
token(completion):
لمنصات Apple أوgetToken()
لنظام Android)، ثم أرسِل الرمز المميّز الحالي إلى خادم تطبيقك لتخزينه (مع طابع زمني). يمكن أن تكون هذه مهمة شهرية تم إعدادها لتغطية جميع العملاء أو الرموز المميزة. - أضِف منطق الخادم لتعديل الطابع الزمني للرمز المميّز على فترات منتظمة، بغض النظر عمّا إذا كان الرمز المميّز قد تغيّر أم لا.
للاطّلاع على مثال على منطق Android لتعديل الرموز المميّزة باستخدام WorkManager، راجِع إدارة الرموز المميّزة لخدمة "المراسلة عبر السحابة الإلكترونية" على مدوّنة Firebase.
بغض النظر عن نمط التوقيت الذي تتّبعه، احرص على تعديل الرموز المميزة بشكل دوري. يوفّر معدّل التحديث مرة واحدة في الشهر توازنًا جيدًا بين تأثير البطارية ورصد رموز التسجيل غير النشطة. من خلال إجراء عملية إعادة التحميل هذه، يمكنك أيضًا التأكّد من أنّ أي جهاز يصبح غير نشط سيتم إعادة تسجيله عند إعادة تنشيطه. ولا فائدة من إعادة التحميل بشكل متكرر أكثر من مرة واحدة في الأسبوع.
إزالة رموز التسجيل القديمة
قبل إرسال رسائل إلى جهاز، تأكَّد من أنّ الطابع الزمني لرمز التسجيل الخاص بالجهاز يقع ضمن فترة انتهاء الصلاحية. على سبيل المثال، يمكنك تنفيذ 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(); });
});
إلغاء الاشتراك في المواضيع باستخدام الرموز المميزة القديمة
إذا كنت تستخدم المواضيع، قد تحتاج أيضًا إلى إلغاء تسجيل الرموز المميزة القديمة من المواضيع التي تم الاشتراك فيها. يتضمّن ذلك خطوتَين:
- يجب أن يعيد تطبيقك الاشتراك في المواضيع مرة واحدة في الشهر وكلما تغيّر رمز التسجيل. ويشكّل ذلك حلاً ذاتيًا، حيث تظهر الاشتراكات تلقائيًا عندما يصبح التطبيق نشطًا مرة أخرى.
- إذا ظلّت إحدى مثيلات التطبيق غير نشطة لمدة شهر واحد (أو مدة عدم النشاط التي تحدّدها)، عليك إلغاء اشتراكها في المواضيع باستخدام Firebase Admin SDK لحذف عملية الربط بين الرمز المميز والموضوع من الخلفية FCM.
تتمثّل فائدة هاتين الخطوتين في أنّ عمليات الإرسال إلى عدة أجهزة ستتم بشكل أسرع لأنّه سيكون هناك عدد أقل من الرموز المميزة القديمة التي سيتم إرسالها إليها، كما أنّ مثيلات التطبيق القديمة ستعيد الاشتراك تلقائيًا عند تنشيطها مرة أخرى.
قياس نجاح عملية التسليم
للحصول على صورة أكثر دقة عن عملية تسليم الرسائل، من الأفضل إرسال الرسائل فقط إلى مثيلات التطبيق المستخدَمة بشكل نشط. ويكون ذلك مهمًا بشكل خاص إذا كنت ترسل رسائل بانتظام إلى مواضيع تضم أعدادًا كبيرة من المشتركين، لأنّه إذا كان جزء من هؤلاء المشتركين غير نشط، يمكن أن يكون التأثير في إحصاءات التسليم كبيرًا بمرور الوقت.
قبل استهداف الرسائل برمز مميز، يجب مراعاة ما يلي:
- هل تشير "إحصاءات Google" أو البيانات التي يتم تسجيلها في BigQuery أو إشارات التتبّع الأخرى إلى أنّ الرمز المميّز نشط؟
- هل تعذّر إجراء عمليات التسليم السابقة بشكل متكرّر على مدار فترة زمنية؟
- هل تم تعديل رمز التسجيل المميز على خوادمك خلال الشهر الماضي؟
- بالنسبة إلى أجهزة Android، هل تسجّل FCM Data API
نسبة عالية من حالات تعذُّر تسليم الرسائل بسبب
droppedDeviceInactive
؟
لمزيد من المعلومات حول التسليم، اطّلِع على مقالة التعرّف على تسليم الرسائل.