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