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