إذا كنت تستخدم واجهات برمجة التطبيقات FCM لإنشاء طلبات الإرسال آليًا، قد تلاحظ مع مرور الوقت أنّك تهدر الموارد من خلال إرسال الرسائل إلى الأجهزة غير النشطة التي تتضمّن عمليات تسجيل قديمة. يمكن أن يؤثّر هذا الموقف في بيانات عرض الرسائل التي يتم تسجيلها في Firebase أو البيانات التي يتم تصديرها إلى BigQuery، ما يؤدي إلى انخفاض كبير (ولكن غير صالح في الواقع) في معدّلات العرض. يناقش هذا الدليل بعض الإجراءات التي يمكنك اتّخاذها للمساعدة في ضمان استهداف الرسائل بكفاءة وإعداد تقارير صالحة عن التسليم.
عمليات التسجيل القديمة والمنتهية الصلاحية
عمليات التسجيل القديمة مرتبطة بأجهزة غير نشطة لم يتم ربطها بحساب FCM لأكثر من شهر. ومع مرور الوقت، تقل احتمالية اتصال الجهاز بشبكة FCM مرة أخرى. ومن غير المرجّح أن يتم تسليم الرسائل وعمليات التوزيع على نطاق واسع للمواضيع لهذه التسجيلات القديمة.
هناك عدة أسباب قد تؤدي إلى انتهاء صلاحية عملية التسجيل. على سبيل المثال، قد يتم فقدان الجهاز المرتبط بالتسجيل أو إتلافه أو وضعه في مكان للتخزين ثم نسيانه.
في نظام التشغيل Android، عندما يكون التسجيل غير نشط لمدة 270 يومًا، يعتبره FCM منتهي الصلاحية ويتم جمع البيانات غير الضرورية. بعد انتهاء صلاحية عملية التسجيل، تضع FCM علامة على عملية التسجيل باعتبارها غير صالحة وترفض إرسال الرسائل إليها. يُرجى العِلم أنّ خدمة Firebase Installations (FIS) هي التي تدير معرّفات عمليات التثبيت في Firebase (FIDs)، وليس خدمة FCM. في حالات نادرة، إذا اتصل جهاز مرة أخرى وتم فتح التطبيق بعد أن تم جمع البيانات غير الضرورية الخاصة بتسجيله، سيسجّل تطبيق العميل مرة أخرى باستخدام FCM، وذلك باستخدام معرّف FID الذي تم استرداده من FIS. يُرجى العِلم بأنّ معرّف FID قد يتغيّر، راجِع مقالة إدارة عمليات تثبيت Firebase للحصول على تفاصيل حول الحالات التي يتم فيها إعادة إصدار معرّفات FID.
بالنسبة إلى المنصات الأخرى، مثل iOS، يعتمد FCM على خدمة الإشعارات الفورية الأساسية (مثل APNs)، التي لا تتضمّن مدة انتهاء صلاحية مماثلة تستند إلى عدم النشاط لمدة 270 يومًا. ننصحك بالحفاظ على صلاحية التسجيل وإزالة التسجيلات القديمة بشكل استباقي.
أفضل الممارسات الأساسية
هناك بعض الممارسات الأساسية التي يجب اتّباعها في أي تطبيق يستخدم واجهات برمجة التطبيقات FCM لإنشاء طلبات الإرسال آليًا. في ما يلي أفضل الممارسات الرئيسية:
- استرداد أرقام تعريف عمليات التثبيت في Firebase (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. يتوافق كل معرّف مستند في المجموعة مع معرّف مستخدم، ويخزّن المستند المعرّف الحالي لجهاز Firebase ووقت آخر تعديل له. استخدِم الدالة
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()) لتفعيل عملية التسجيل وتسليم معرّف FID من خلال
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 (يُنصح بها)
بالنسبة إلى تطبيقات العميل التي تستخدم واجهات برمجة التطبيقات الخاصة بمعرّف 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؟
لمزيد من المعلومات حول التسليم، اطّلِع على مقالة فهم عملية تسليم الرسائل.