إذا كنت تستخدم واجهات برمجة التطبيقات FCM لإنشاء طلبات الإرسال آليًا، قد تلاحظ مع مرور الوقت أنّك تهدر الموارد من خلال إرسال الرسائل إلى الأجهزة غير النشطة التي تتضمّن عمليات تسجيل قديمة. يمكن أن يؤثر هذا الموقف في بيانات تسليم الرسائل المسجّلة في وحدة تحكّم Firebase أو البيانات التي يتم تصديرها إلى BigQuery، حيث تظهر على شكل انخفاض كبير (ولكنه غير صحيح في الواقع) في معدلات التسليم. يتناول هذا الدليل بعض الإجراءات التي يمكنك اتّخاذها للمساعدة في ضمان استهداف الرسائل بكفاءة وإعداد تقارير التسليم الصالحة.
عمليات التسجيل القديمة والمنتهية الصلاحية
عمليات التسجيل القديمة مرتبطة بأجهزة غير نشطة لم يتم ربطها بحساب FCM لأكثر من شهر. ومع مرور الوقت، يصبح من غير المرجّح أن يتصل الجهاز بخدمة "FCM" مرة أخرى. ومن غير المرجّح أن يتم تسليم الرسائل وعمليات التوزيع على نطاق واسع للمواضيع لهذه التسجيلات القديمة.
هناك عدة أسباب قد تؤدي إلى أن يصبح التسجيل قديمًا. على سبيل المثال، قد يتم فقدان الجهاز المرتبط بالتسجيل أو إتلافه أو وضعه في مكان للتخزين ثم نسيانه.
على أجهزة Android، عندما يكون التسجيل غير نشط لمدة 270 يومًا، FCM يعتبره منتهي الصلاحية ويجمعه في المهملات. بعد انتهاء صلاحية عملية التسجيل، تضع FCM علامة على عملية التسجيل باعتبارها غير صالحة وترفض إرسال الرسائل إليها. يُرجى العِلم أنّ خدمة Firebase Installations (FIS) هي التي تدير معرّفات عمليات التثبيت في Firebase (FIDs)، وليس خدمة FCM. في حالات نادرة، عندما يتصل جهاز مرة أخرى ويتم فتح التطبيق بعد أن يتم جمع بيانات التسجيل الخاصة به، يسجّل تطبيق العميل مرة أخرى في FCM باستخدام معرّف Firebase (FID) الذي تم استرداده من خدمة FIS. يُرجى العِلم أنّ معرّف FID قد يتغيّر. يمكنك الاطّلاع على إدارة عمليات تثبيت Firebase لمعرفة تفاصيل حول حالات إعادة إصدار معرّفات FID.
بالنسبة إلى المنصات الأخرى، مثل iOS، تعتمد FCM على خدمة الإشعارات الفورية الأساسية (مثل APNs)، والتي لا تنتهي صلاحيتها بعد 270 يومًا من عدم النشاط. ننصحك بالحفاظ على صلاحية التسجيل وإزالة التسجيلات القديمة بشكل استباقي.
أفضل الممارسات الأساسية
هناك بعض الممارسات الأساسية التي يجب اتّباعها في أي تطبيق يستخدم واجهات برمجة تطبيقات FCM لإنشاء طلبات الإرسال آليًا. أفضل الممارسات الرئيسية هي:
- استرداد معرّفات Firebase Installation IDs (FIDs) من FCM وتخزينها على خادم تطبيقك من الأدوار المهمة للخادم تتبُّع معرّف FID المسجَّل لكل عميل والاحتفاظ بقائمة محدَّثة بمعرّفات FID النشطة. ننصحك بشدة بتنفيذ طابع زمني للتسجيل في قاعدة البيانات وتعديله كلما تم تحميل تسجيل.
- الحفاظ على حداثة عمليات التسجيل وإزالة عمليات التسجيل القديمة: بالإضافة إلى إزالة عمليات التسجيل التي لم يعُد FCM يعتبرها صالحة، قد تحتاج إلى مراقبة العلامات الأخرى التي تشير إلى أنّ عمليات التسجيل أصبحت قديمة وإزالتها بشكل استباقي. يتناول هذا الدليل بعض الخيارات المتاحة لك لتحقيق ذلك.
استرداد معرّفات عمليات تثبيت Firebase وتخزينها
عند بدء تشغيل تطبيقك لأول مرة، تسجِّل حزمة تطوير البرامج (SDK) FCM نسخة التطبيق مع FCM وتعرض رقم تعريف التثبيت على Firebase (FID). هذا هو المعرّف الذي يجب تضمينه في طلبات الإرسال المستهدَفة من واجهة برمجة التطبيقات، أو استخدامه للاشتراك في المواضيع.
ننصحك بشدة بحفظ معرّف FID على خادم تطبيقك مع طابع زمني كلما تم تحميله. من خلال تعديل الطابع الزمني في كل طلب تحميل، يعرف الخادم آخر مرة تم فيها فتح مثيل التطبيق ومزامنته بنجاح مع الخلفية في FCM.
بناءً على ما إذا كانت ميزة الإعداد التلقائي مفعَّلة أو غير مفعَّلة (بما في ذلك غير متاحة)، عليك التعامل مع التسجيل والتحديثات على النحو التالي:
- (يُنصح به) عند تفعيل ميزة "بدء التشغيل التلقائي": تعمل حزمة SDK تلقائيًا على إبقاء التسجيل محدّثًا وتتبُّع التغييرات. يتم استدعاء دالة الاستدعاء
onRegistered()بانتظام في عمليات المزامنة الروتينية أثناء بدء تشغيل التطبيق، وكذلك عند حدوث تغييرات في معرّف FID. ما عليك سوى تنفيذ دالة الاستدعاء هذه لتحميل معرّف FID إلى خادمك وحفظ الطابع الزمني الحالي. - عند إيقاف الإعداد التلقائي: لن يتم تلقائيًا استدعاء دالة الاستدعاء
onRegistered()عند البدء. لتتبُّع عمليات التسجيل والحفاظ على حداثتها، عليك طلب بيانات منregister()عند بدء تشغيل التطبيق، مثلاً على Android، فيonCreate()للنشاط الرئيسي. يؤدي الطلب الناجح إلى بدء عملية تسجيل FCM باستخدام معرّف FID وتسليمه إلى دالة الاستدعاءonRegistered()، ما يسمح لتطبيقك بتحميل معرّف FID وتعديل الطابع الزمني على الخادم.
مثال: تخزين أرقام تعريف الميزات والطوابع الزمنية في Cloud Firestore
على سبيل المثال، يمكنك استخدام Cloud Firestore لتخزين معرّفات الميزات في مجموعة باسم fcmRegistrations. يتوافق كل معرّف مستند في المجموعة مع معرّف مستخدم،
ويخزّن المستند معرّف FID الحالي والطابع الزمني لآخر تعديل. استخدِم الدالة set كما هو موضّح في مثال Kotlin التالي:
private fun sendRegistrationToServer(installationId: String?) {
// If you're running your own server, call API to send registration details and today's date for the user
// Example shown uses Firestore
// Add FID and timestamp to Firestore for this user
val deviceFid = hashMapOf(
"installationId" to installationId,
"timestamp" to FieldValue.serverTimestamp(),
)
// Get user ID from Firebase Auth or your own server
Firebase.firestore.collection("fcmRegistrations").document("myuserid")
.set(deviceFid)
}
عندما يتم تسجيل معرّف تثبيت Firebase أو تعديله بنجاح، يتم استدعاء دالة الاستدعاء
onRegistered(). يجب تنفيذ دالة الاستدعاء هذه لتحميل معرّف FID
وتعديل الطابع الزمني:
override fun onRegistered(installationId: String) {
Log.d(TAG, "Registered installation ID: $installationId")
// Send the Firebase Installation ID (FID) to your app server. Your app
// server should save the FID and update the timestamp upon receipt.
sendRegistrationToServer(installationId)
}
في الحالات التي يتم فيها إيقاف الإعداد التلقائي، يمكنك استدعاء
register()
عند بدء تشغيل التطبيق (على سبيل المثال، في onCreate()) لتشغيل عملية التسجيل وعرض
معرّف مثيل Firebase من خلال
onRegistered():
// Trigger manual registration if auto-initialization is turned off.
FirebaseMessaging.getInstance().register()
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// The registration callback onRegistered() will be invoked with the current FID.
} else {
Log.w(TAG, "Failed to register with Firebase Cloud Messaging", task.exception)
}
}
الحفاظ على حداثة التسجيل وإزالة التسجيلات القديمة
ليس من السهل دائمًا تحديد ما إذا كان التسجيل جديدًا أو قديمًا. لتغطية جميع الحالات، يجب اعتماد حدّ أقصى لتحديد متى تعتبر التسجيلات قديمة. بشكل تلقائي، يعتبر FCM التسجيل قديمًا إذا لم يتم ربط مثيل التطبيق الخاص به لمدة شهر. ومن المرجّح أن يكون أي تسجيل أقدم من شهر واحد لجهاز غير نشط، وإلا كان الجهاز النشط سيجدّد تسجيله.
بناءً على حالة الاستخدام، قد يكون الشهر قصيرًا جدًا أو طويلاً جدًا، لذا يعود الأمر إليك لتحديد المعايير التي تناسبك.
رصد الردود غير الصالحة من الواجهة الخلفية FCM
احرص على رصد الردود غير الصالحة من FCM والرد عليها من خلال حذف أي عمليات تسجيل معروف أنّها غير صالحة أو منتهية الصلاحية من نظامك. باستخدام الإصدار 1 من HTTP API، قد تشير رسائل الخطأ هذه إلى أنّ طلب الإرسال يستهدف عمليات تسجيل غير صالحة أو منتهية الصلاحية:
UNREGISTERED(HTTP 404)-
INVALID_ARGUMENT(HTTP 400)
إذا كنت متأكدًا من أنّ حمولة الرسالة صالحة وتلقّيت أيًا من هذين الردّين لتسجيل مستهدَف، يمكنك حذف سجلّ هذا التسجيل بأمان، لأنّه لن يكون صالحًا مرة أخرى. على سبيل المثال، لحذف التسجيلات غير الصالحة من Cloud Firestore، يمكنك نشر دالة وتنفيذها على النحو التالي:
// Firebase Installation ID comes from the client FCM SDKs
const firebaseInstallationId = 'YOUR_FIREBASE_INSTALLATION_ID';
const message = {
data: {
// Information you want to send inside of notification
},
fid: firebaseInstallationId
};
// Send message to device with provided Firebase Installation ID
getMessaging().send(message)
.then((response) => {
// Response is a message ID string.
})
.catch((error) => {
// Delete registration 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 registration for the user
// Example shown uses Firestore
// Get user ID from Firebase Auth or your own server
Firebase.firestore.collection("fcmRegistrations").document(user.uid).delete()
}
});
تعرض FCM ردًا غير صالح إذا انتهت صلاحية تسجيل جهاز Android بعد 270 يومًا من عدم النشاط، أو إذا ألغى العميل التسجيل صراحةً. إذا كنت بحاجة إلى تتبُّع التسجيلات القديمة بدقة أكبر وفقًا لتعريفاتك الخاصة، يمكنك إزالة التسجيلات القديمة بشكل استباقي.
تعديل عمليات التسجيل بانتظام
بغض النظر عمّا إذا كانت عمليات التسجيل تستند إلى معرّفات FID أو رموز التسجيل القديمة، يجب أن يحرص الخادم دائمًا على تعديل الطابع الزمني للتسجيل في قاعدة البيانات عند كل طلب تحميل. يعمل هذا الطابع الزمني كمؤشر على تثبيت التطبيق، ما يتيح للعميل فتح التطبيق بنجاح والمزامنة مع الخلفية FCM. اعتمادًا على واجهات برمجة التطبيقات التي تستخدمها، نفِّذ الاستراتيجية المناسبة:
واجهات برمجة التطبيقات Firebase Installation ID (ننصح بها)
بالنسبة إلى تطبيقات العملاء التي تستخدم واجهات برمجة تطبيقات FID، لا تحتاج إلى جدولة مهام دورية في الخلفية في تطبيق العميل لاسترداد عمليات التسجيل أو إعادة تحميلها. تتولّى حزمة SDK تلقائيًا عمليات إعادة التحميل في إطار عملية الإعداد التلقائي، وتوفّر بانتظام معرّف التثبيت الحالي الصحيح إلى دالة معاودة الاتصال onRegistered() عند إجراء عمليات المزامنة الروتينية أثناء بدء تشغيل التطبيق.
لإبقاء الخادم محدَّثًا، نفِّذ استراتيجيات التحميل عند بدء التشغيل الموضّحة في مقالة استرداد معرّفات تثبيت Firebase وتخزينها:
- تفعيل الإعداد التلقائي: تتأكّد حزمة SDK تلقائيًا من إرسال أحدث معرّف FID إلى خادمك عند إجراء عمليات المزامنة الروتينية أثناء عمليات بدء تشغيل التطبيق.
- إيقاف الإعداد التلقائي أو عدم إتاحته: يمكنك استدعاء
register()عند بدء تشغيل التطبيق (على سبيل المثال، في نظام التشغيل Android، في النشاط الرئيسيonCreate()) لفرض تسلسل التسجيل وتشغيل عرض FID إلىonRegistered()معاودة الاتصال.
تضمن هذه الاستراتيجيات حصول خادمك دائمًا على أحدث معرّف نشط لجهاز Android، ويمكنه استرداد البيانات من عمليات التحميل الفاشلة تلقائيًا، ما يجعل التطبيق مرنًا للغاية.
واجهات برمجة التطبيقات المتوقّفة نهائيًا لرموز التسجيل المميّزة
إذا كنت تستخدم رموز تسجيل قديمة، لن تدير حزمة تطوير البرامج (SDK) للعميل عمليات إعادة التحميل تلقائيًا في عمليات المزامنة الروتينية. لذلك، ننصحك باسترداد جميع رموز التسجيل وتعديلها بشكل دوري على الخادم. يتطلّب ذلك منك ما يلي:
- أضِف منطق التطبيق في تطبيق العميل لاسترداد الرمز المميّز الحالي باستخدام
طلب البيانات المناسب من واجهة برمجة التطبيقات (مثل
token(completion):لمنصات Apple أوgetToken()لنظام التشغيل Android)، ثم أرسِل الرمز المميّز الحالي إلى خادم التطبيق لتخزينه (مع طابع زمني). يمكن أن تكون هذه مهمة شهرية تم إعدادها لتغطية جميع العملاء أو الرموز المميّزة. - أضِف منطق الخادم لتعديل الطابع الزمني للرمز المميّز على فترات منتظمة، بغض النظر عمّا إذا كان الرمز المميّز قد تغيّر أم لا.
للاطّلاع على مثال على منطق Android لتعديل الرموز المميزة القديمة باستخدام WorkManager، راجِع إدارة الرموز المميزة في خدمة المراسلة عبر السحابة الإلكترونية على مدونة Firebase.
أيًا كان النمط الزمني الذي تتبعه، احرص على تعديل الرموز المميزة بشكل دوري. ويُعدّ معدّل التحديث مرة واحدة شهريًا توازنًا جيدًا بين التأثير في البطارية ورصد الرموز المميّزة غير النشطة للتسجيل. من خلال إجراء عملية إعادة التحميل هذه، يمكنك أيضًا التأكّد من أنّ أي جهاز يصبح غير نشط سيُعيد تحميل عملية التسجيل عند إعادة تنشيطه. ولا فائدة من إعادة التحميل بشكل متكرر أكثر من مرة واحدة في الأسبوع.
إزالة عمليات التسجيل القديمة
قبل إرسال رسائل إلى جهاز، تأكَّد من أنّ الطابع الزمني لتسجيل الجهاز يقع ضمن فترة انتهاء الصلاحية. على سبيل المثال، يمكنك
تنفيذ Cloud Functions for Firebase لإجراء فحص يومي للتأكّد من أنّ
الطابع الزمني يقع ضمن فترة زمنية محدّدة لعدم النشاط، مثل const
EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30;، ثم إزالة
عمليات التسجيل غير النشطة:
exports.pruneRegistrations = functions.pubsub.schedule('every 24 hours').onRun(async (context) => {
// Get all documents where the timestamp exceeds is not within the past month
const staleRegistrationsResult = await admin.firestore().collection('fcmRegistrations')
.where("timestamp", "<", Date.now() - EXPIRATION_TIME)
.get();
// Delete devices with stale registrations
staleRegistrationsResult.forEach(function(doc) { doc.ref.delete(); });
});
إلغاء اشتراك عمليات التسجيل القديمة في المواضيع
إذا كنت تستخدم المواضيع، قد تحتاج أيضًا إلى إلغاء اشتراك التسجيلات القديمة من المواضيع التي اشتركت فيها. يتضمن ذلك خطوتَين:
- يجب أن يعيد تطبيقك الاشتراك في المواضيع كلما تغيّر معرّف التثبيت في Firebase (FID). يتيح ذلك ظهور الاشتراكات تلقائيًا عند إعادة تفعيل التطبيق.
- إذا ظلّت إحدى مثيلات التطبيق غير نشطة لمدة شهر واحد (أو مدة عدم النشاط التي تحدّدها)، عليك إلغاء اشتراكها في المواضيع باستخدام Firebase Admin SDK لحذف عملية الربط بين معرّف تثبيت Firebase والموضوع من الخلفية FCM.
تتمثل فائدة هاتين الخطوتين في أن عمليات التوزيع ستحدث بشكل أسرع نظرًا لوجود عدد أقل من التسجيلات القديمة التي يمكن التوزيع إليها، وستتم إعادة اشتراك مثيلات التطبيق القديمة تلقائيًا بمجرد أن تصبح نشطة مرة أخرى.
قياس نجاح التسليم
للحصول على أدق صورة عن تسليم الرسائل، من الأفضل إرسال الرسائل فقط إلى نُسخ التطبيق المستخدَمة بشكل نشط. وهذا مهم بشكل خاص إذا كنت ترسل رسائل بانتظام إلى مواضيع تضم أعدادًا كبيرة من المشتركين، فإذا كان جزء من هؤلاء المشتركين غير نشطين، يمكن أن يكون التأثير على إحصاءات التسليم كبيرًا بمرور الوقت.
قبل استهداف الرسائل بمثيل تطبيق، يجب مراعاة ما يلي:
- هل تشير "إحصاءات Google" أو البيانات التي يتم تسجيلها في BigQuery أو إشارات التتبُّع الأخرى إلى أنّ التسجيل نشط؟
- هل فشلت محاولات التسليم السابقة بشكل متكرّر على مدار فترة زمنية؟
- هل تم تعديل رقم تعريف عملية التثبيت في Firebase على خوادمك خلال الشهر الماضي؟
- بالنسبة إلى أجهزة Android، هل تسجّل FCM Data API
نسبة عالية من حالات تعذُّر تسليم الرسائل بسبب
droppedDeviceInactive؟
لمزيد من المعلومات حول التسليم، يُرجى الاطّلاع على فهم تسليم الرسائل.