إذا كنت تستخدم واجهات برمجة تطبيقات FCM لإنشاء طلبات الإرسال آليًا، قد تجد أنّك بمرور الوقت تهدر الموارد من خلال إرسال رسائل إلى أجهزة غير نشطة ذات تسجيلات قديمة. يمكن أن يؤثر هذا الموقف في بيانات تسليم الرسائل المسجّلة في وحدة تحكّم Firebase أو البيانات التي يتم تصديرها إلى BigQuery، حيث تظهر على شكل انخفاض كبير (ولكنه غير صحيح في الواقع) في معدلات التسليم. يتناول هذا الدليل بعض الإجراءات التي يمكنك اتّخاذها للمساعدة في ضمان استهداف الرسائل بكفاءة وإعداد تقارير التسليم الصالحة.
عمليات التسجيل القديمة والمنتهية الصلاحية
ترتبط عمليات التسجيل القديمة بالأجهزة غير النشطة التي لم تتصل بـ "FCM" لأكثر من شهر. ومع مرور الوقت، يصبح من غير المرجّح أن يتصل الجهاز بخدمة "FCM" مرة أخرى. ومن غير المرجّح أن يتم تسليم الرسائل المرسَلة وعمليات توزيع المواضيع لهذه التسجيلات القديمة.
هناك عدة أسباب قد تؤدي إلى أن يصبح التسجيل قديمًا. على سبيل المثال، قد يتم فقدان الجهاز المرتبط بالتسجيل أو تدميره أو وضعه في مكان تخزين ونسيانه.
على أجهزة Android، عندما يكون التسجيل غير نشط لمدة 270 يومًا، FCM يعتبره منتهي الصلاحية ويجمعه في المهملات. بعد انتهاء صلاحية التسجيل، يضع FCM علامة عليه كغير صالح ويرفض الإرسال إليه. يُرجى العِلم أنّ معرّفات Firebase Installation IDs (FIDs) تتم إدارتها من خلال خدمة Firebase Installations service (FIS)، وليس من خلال "مراسلة Firebase السحابية". في حالات نادرة، عندما يتصل جهاز مرة أخرى ويتم فتح التطبيق بعد أن يتم جمع بيانات التسجيل الخاصة به، يسجّل تطبيق العميل مرة أخرى في FCM باستخدام معرّف Firebase (FID) الذي تم استرداده من خدمة FIS. يُرجى العِلم أنّ معرّف FID قد يتغيّر. يمكنك الاطّلاع على إدارة عمليات تثبيت Firebase لمعرفة تفاصيل حول حالات إعادة إصدار معرّفات FID.
بالنسبة إلى المنصات الأخرى، مثل iOS، تعتمد FCM على خدمة الإشعارات الفورية الأساسية (مثل APNs)، والتي لا تنتهي صلاحيتها بعد 270 يومًا من عدم النشاط. ننصحك بالحفاظ على حداثة التسجيلات وإزالة التسجيلات القديمة بشكل استباقي.
أفضل الممارسات الأساسية
هناك بعض الممارسات الأساسية التي يجب اتّباعها في أي تطبيق يستخدم واجهات برمجة تطبيقات FCM لإنشاء طلبات الإرسال آليًا. أفضل الممارسات الرئيسية هي:
- استرداد معرّفات Firebase Installation IDs (FIDs) من FCM وتخزينها على خادم تطبيقك من الأدوار المهمة للخادم تتبُّع معرّف FID المسجَّل لكل عميل والاحتفاظ بقائمة محدَّثة بمعرّفات FID النشطة. ننصح بشدة بتنفيذ طابع زمني للتسجيل في قاعدة البيانات، وتحديثه كلما تم تحميل تسجيل.
- الحفاظ على حداثة التسجيلات وإزالة التسجيلات القديمة: بالإضافة إلى إزالة عمليات التسجيل التي لم يعُد FCM يعتبرها صالحة، قد تحتاج إلى مراقبة العلامات الأخرى التي تشير إلى أنّ عمليات التسجيل أصبحت قديمة وإزالتها بشكل استباقي. يتناول هذا الدليل بعض الخيارات المتاحة لك لتحقيق ذلك.
استرداد معرّفات Firebase Installation وتخزينها
عند بدء تشغيل تطبيقك لأول مرة، تسجّل حزمة تطوير البرامج (SDK) لـ "FCM" نسخة التطبيق في "FCM" وتعرض رقم تعريف تثبيت Firebase (FID). هذا هو المعرّف الذي يجب تضمينه في طلبات الإرسال المستهدَفة من واجهة برمجة التطبيقات، أو استخدامه للاشتراكات في المواضيع.
ننصح بشدة بحفظ معرّف تثبيت Firebase على خادم التطبيق مع طابع زمني عند تحميله. من خلال تعديل الطابع الزمني في كل طلب تحميل، يعرف الخادم آخر مرة تم فيها فتح مثيل التطبيق ومزامنته بنجاح مع الخلفية في FCM.
بناءً على ما إذا كانت ميزة الإعداد التلقائي مفعَّلة أو غير مفعَّلة (بما في ذلك غير متاحة)، عليك التعامل مع التسجيل والتحديثات على النحو التالي:
- (إجراء يُنصح به) عند تفعيل الإعداد التلقائي: تحافظ حزمة تطوير البرامج (SDK) تلقائيًا على تحديث التسجيل وتراقب التغييرات. يتم استدعاء دالة الاستدعاء
onRegistered()بانتظام في عمليات المزامنة الروتينية أثناء بدء تشغيل التطبيق، وكذلك عند حدوث تغييرات في معرّف FID. ما عليك سوى تنفيذ هذه الدالة لرفع معرّف FID إلى خادمك وحفظ الطابع الزمني الحالي. - عند إيقاف الإعداد التلقائي: لن يتم تلقائيًا استدعاء دالة الاستدعاء
onRegistered()عند البدء. لتتبُّع عمليات التسجيل والحفاظ على تحديثها، يمكنك استدعاءregister()عند بدء تشغيل التطبيق، على سبيل المثال، في نظام التشغيل Android، في النشاط الرئيسيonCreate(). يؤدي الطلب الناجح إلى بدء عملية تسجيل FCM باستخدام معرّف FID وتسليمه إلى دالة الاستدعاءonRegistered()، ما يسمح لتطبيقك بتحميل معرّف FID وتعديل الطابع الزمني على الخادم.
مثال: تخزين أرقام تعريف الميزات والطوابع الزمنية في Cloud Firestore
على سبيل المثال، يمكنك استخدام Cloud Firestore لتخزين معرّفات FID في مجموعة باسم 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 والردّ عليها من خلال حذف أي عمليات تسجيل من نظامك معروف أنّها غير صالحة أو منتهية الصلاحية. باستخدام واجهة برمجة التطبيقات HTTP v1، قد تشير رسائل الخطأ هذه إلى أنّ طلب الإرسال استهدف تسجيلات غير صالحة أو منتهية الصلاحية:
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 يومًا من عدم النشاط، أو إذا ألغى العميل التسجيل صراحةً. إذا كنت بحاجة إلى تتبُّع التسجيلات القديمة بدقة أكبر وفقًا لتعريفاتك الخاصة، يمكنك إزالة التسجيلات القديمة بشكل استباقي.
تعديل التسجيلات بشكل منتظم
بغض النظر عمّا إذا كانت عمليات التسجيل تستند إلى معرّفات مثيلات Firebase أو رموز التسجيل المميّزة القديمة، يجب أن يحدّث الخادم دائمًا الطابع الزمني للتسجيل في قاعدة البيانات عند كل طلب تحميل. يعمل هذا الطابع الزمني كإشارة لتثبيت التطبيق، مما يتيح للعميل فتح التطبيق بنجاح والمزامنة مع الواجهة الخلفية لـ FCM. بناءً على واجهات برمجة التطبيقات التي تستخدمها، يمكنك تنفيذ الاستراتيجية المناسبة:
واجهات برمجة التطبيقات Firebase Installation ID (ننصح بها)
بالنسبة إلى تطبيقات العملاء التي تستخدم واجهات برمجة تطبيقات FID، لا تحتاج إلى جدولة مهام دورية في الخلفية في تطبيق العميل لاسترداد عمليات التسجيل أو إعادة تحميلها. تتولّى حزمة تطوير البرامج (SDK)
عمليات إعادة التحميل تلقائيًا في إطار الإعداد التلقائي، وتوفّر
بانتظام معرّف مثيل Firebase الحالي الصحيح لدالة الاستدعاء
onRegistered()
عند إجراء عمليات المزامنة الروتينية أثناء بدء تشغيل التطبيق.
لإبقاء الخادم محدَّثًا، نفِّذ استراتيجيات التحميل عند بدء التشغيل الموضّحة في مقالة استرداد معرّفات تثبيت Firebase وتخزينها:
- تفعيل الإعداد التلقائي: تضمن حزمة تطوير البرامج (SDK) تلقائيًا إرسال أحدث معرّف مثيل Firebase إلى خادمك في عمليات المزامنة الروتينية أثناء بدء تشغيل التطبيق.
- إيقاف الإعداد التلقائي أو عدم إتاحته: يمكنك استدعاء
register()عند بدء تشغيل التطبيق (على سبيل المثال، في نظام التشغيل Android، في النشاط الرئيسيonCreate()) لفرض تسلسل التسجيل وتشغيل عرض FID إلىonRegistered()معاودة الاتصال.
تضمن هذه الاستراتيجيات أن يكون لدى الخادم دائمًا أحدث معرّف FID نشط، ويمكنه التعافي من عمليات التحميل الفاشلة تلقائيًا، ما يجعل التطبيق مرنًا للغاية.
واجهات برمجة التطبيقات المتوقفة نهائيًا لرموز التسجيل المميّزة
إذا كنت تستخدم رموز تسجيل قديمة، لن تدير حزمة تطوير البرامج (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). يتيح ذلك ظهور الاشتراكات تلقائيًا عند إعادة تفعيل التطبيق.
- إذا كانت نسخة التطبيق غير نشطة لمدة شهر (أو فترة عدم النشاط التي تحدّدها)، عليك إلغاء اشتراكها في المواضيع باستخدام مدير SDK في Firebase لحذف عملية ربط معرّف تثبيت Firebase بالموضوع من خلفية FCM.
تتمثل فائدة هاتين الخطوتين في أن عمليات التوزيع ستحدث بشكل أسرع نظرًا لوجود عدد أقل من التسجيلات القديمة التي يمكن التوزيع إليها، وستتم إعادة اشتراك مثيلات التطبيق القديمة تلقائيًا بمجرد أن تصبح نشطة مرة أخرى.
قياس نجاح التسليم
للحصول على أدق صورة عن تسليم الرسائل، من الأفضل إرسال الرسائل فقط إلى نُسخ التطبيق المستخدَمة بشكل نشط. وهذا مهم بشكل خاص إذا كنت ترسل رسائل بانتظام إلى مواضيع تضم أعدادًا كبيرة من المشتركين، فإذا كان جزء من هؤلاء المشتركين غير نشطين، يمكن أن يكون التأثير على إحصاءات التسليم كبيرًا بمرور الوقت.
قبل استهداف الرسائل لمثيل تطبيق، يجب مراعاة ما يلي:
- هل تشير "إحصاءات Google" أو البيانات التي تم تسجيلها في BigQuery أو إشارات التتبُّع الأخرى إلى أنّ التسجيل نشط؟
- هل فشلت محاولات التسليم السابقة باستمرار على مدار فترة زمنية؟
- هل تم تعديل معرّف تثبيت Firebase على خوادمك في الشهر الماضي؟
- بالنسبة إلى أجهزة Android، هل تسجّل واجهة FCM Data API نسبة عالية من حالات تعذُّر تسليم الرسائل بسبب
droppedDeviceInactive؟
لمزيد من المعلومات حول التسليم، يُرجى الاطّلاع على فهم تسليم الرسائل.