استلام الرسائل في تطبيق Android

تختلف طريقة عمل إشعارات Firebase حسب حالة التطبيق المستلِم في المقدّمة/الخلفية. إذا كنت تريد أن تتلقّى التطبيقات التي تعمل في المقدّمة رسائل إشعارات أو رسائل بيانات، عليك كتابة رمز لمعالجة مكالمة onMessageReceived. للحصول على تفسير للفرق بين إشعارات البيانات والرسائل، يُرجى الاطّلاع على أنواع الرسائل.

التعامل مع الرسائل

ولتلقّي رسائل، استخدِم خدمة تتضمّن امتدادات FirebaseMessagingService يجب أن تلغي خدمتك onMessageReceived وonDeletedMessages طلبات إعادة الاتصال.

قد تكون الفترة الزمنية لمعالجة الرسالة أقصر من 20 ثانية بناءً على التأخيرات يتم تكبدها قبل الاتصال بـ onMessageReceived، بما في ذلك تأخيرات نظام التشغيل ووقت بدء تشغيل التطبيق سلسلة التعليمات الرئيسية التي تحظرها عمليات أخرى أو onMessageReceived السابق المكالمات التي تستغرق وقتًا طويلاً جدًا. وبعد ذلك الوقت، قد تتداخل سلوكيات نظام التشغيل المختلفة، مثل إيقاف العمليات في Android أو حدود التنفيذ في الخلفية في Android O، مع قدرتك على إكمال عملك.

يتوفّر onMessageReceived لمعظم أنواع الرسائل، مع استثناءات التالية:

  • رسائل الإشعارات التي يتم تسليمها عندما يعمل تطبيقك في الخلفية: في هذه الدورة، فإن الإشعار يتم إرساله إلى لوحة نظام الجهاز. عند النقر على إشعار، يفتح المستخدم مشغّل التطبيقات تلقائيًا.

  • الرسائل التي تحتوي على كل من الإشعارات وحمولة البيانات عند استلامها في الخلفية في هذه الحالة، يتم إرسال الإشعار إلى علبة نظام الجهاز، ويتم إرسال حمولة البيانات في الإضافات الخاصة بنيّة نشاط مشغّل التطبيقات.

وباختصار:

حالة التطبيق الإشعار البيانات كلاهما
لون الواجهة onMessageReceived onMessageReceived onMessageReceived
الخلفية علبة النظام onMessageReceived الإشعار: علبة النظام
البيانات: في إضافات الطلب
لمزيد من المعلومات عن أنواع الرسائل، يُرجى الاطّلاع على مقالة الإشعارات ورسائل البيانات.

تعديل بيان التطبيق

لاستخدام FirebaseMessagingService، عليك إضافة ما يلي في بيان تطبيقك:

<service
    android:name=".java.MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

ننصحك أيضًا بضبط القيم التلقائية لتخصيص مظهر الإشعارات. يمكنك تحديد رمز تلقائي مخصّص ولون تلقائي مخصّص يتم تطبيقهما في حال عدم ضبط قيم مكافئة في الحمولة البرمجية للإشعار.

أضف هذه الخطوط داخل علامة application لضبط الرمز التلقائي المخصّص واللون المخصّص:

<!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
     See README(https://goo.gl/l4GJaQ) for more. -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/ic_stat_ic_notification" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
     notification message. See README(https://goo.gl/6BKBk7) for more. -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="@color/colorAccent" />

يعرض Android الرمز التلقائي المخصّص

  • سيتم إرسال جميع رسائل الإشعارات من منشئ الإشعارات
  • أي رسالة إشعار لا تضبط الرمز صراحةً في الحمولة

يستخدم Android اللون الافتراضي المخصص

  • جميع رسائل الإشعارات المُرسَلة من أداة إنشاء الإشعارات
  • أي رسالة إشعار لم يتم فيها تحديد اللون في الإشعار بشكل صريح حمولة البيانات.

إذا لم يتم ضبط رمز تلقائي مخصَّص ولم يتم ضبط رمز في حمولة الإشعارات، يعرض Android رمز التطبيق المعروض باللون الأبيض.

إلغاء onMessageReceived

من خلال إلغاء الطريقة FirebaseMessagingService.onMessageReceived، يمكنك تنفيذ الإجراءات استنادًا إلى عنصر RemoteMessage المستلَم والحصول على بيانات الرسالة:

Kotlin+KTX

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: ${remoteMessage.from}")

    // Check if message contains a data payload.
    if (remoteMessage.data.isNotEmpty()) {
        Log.d(TAG, "Message data payload: ${remoteMessage.data}")

        // Check if data needs to be processed by long running job
        if (needsToBeScheduled()) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob()
        } else {
            // Handle message within 10 seconds
            handleNow()
        }
    }

    // Check if message contains a notification payload.
    remoteMessage.notification?.let {
        Log.d(TAG, "Message Notification Body: ${it.body}")
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

Java

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());

        if (/* Check if data needs to be processed by long running job */ true) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob();
        } else {
            // Handle message within 10 seconds
            handleNow();
        }

    }

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

إلغاء onDeletedMessages

في بعض الحالات، قد لا يُرسِل FCM رسالة. يحدث هذا عندما يكون هناك عدد كبير جدًا رسالة (أكثر من 100) معلَّقة لـ تطبيقك على جهاز معيّن أثناء اتصاله أو إذا لم يكن الجهاز متصلاً FCM في أكثر من شهر واحد في هذه الحالات، قد تتلقّى طلبًا للرجوع إلى FirebaseMessagingService.onDeletedMessages() وعندما تتلقّى نسخة التطبيق هذا الطلب للرجوع، من المفترض أن تُجري مزامنة كاملة مع خادم التطبيق. إذا لم ترسل رسالة إلى التطبيق على هذا الجهاز خلال آخر 4 أسابيع، لن يتصل FCM بـ onDeletedMessages().

معالجة رسائل الإشعارات في تطبيق يعمل في الخلفية

عندما يعمل التطبيق في الخلفية، يوجّه Android رسائل الإشعارات إلى لوحة النظام. يؤدي نقر المستخدم على الإشعار إلى فتح مشغّل التطبيقات من خلال الافتراضي.

ويشمل ذلك الرسائل التي تتضمّن كلاً من الإشعارات والبيانات. (وجميع الرسائل المرسلة من وحدة التحكم في الإشعارات). وفي هذه الحالات، يتم إرسال الإشعار إلى عنوان لوحة النظام، ويتم تسليم حمولة البيانات في إضافات نشاط مشغّل التطبيقات.

للحصول على إحصاءات عن إرسال الرسائل إلى تطبيقك، اطّلِع على FCMلوحة بيانات إعداد التقارير التي تسجِّل عدد الرسائل المُرسَلة والمُفتحة على أجهزة Apple وAndroid، بالإضافة إلى بيانات "مرّات الظهور" (الإشعارات التي يراها المستخدمون) لتطبيقات Android.

تلقّي رسائل "المراسلة عبر السحابة الإلكترونية من Firebase" في وضع التشغيل المباشر

يمكن للمطوّرين الذين يريدون إرسال رسائل FCM إلى التطبيقات حتى قبل فتح قفل الجهاز تفعيل تطبيق Android لتلقّي الرسائل عندما يكون الجهاز في وضع التشغيل المباشر. على سبيل المثال، قد تريد أن يتلقّى مستخدمو تطبيقك إشعارات الإنذار حتى على جهاز مقفل.

عند إنشاء حالة الاستخدام هذه، راقب العام أفضل الممارسات والقيود لوضع التشغيل المباشر من المهم من المهم جدًا مراعاة إمكانية ظهور إعلانات تشغيل مباشرة يشغّلها الرسائل؛ يمكن لأي مستخدم لديه حق الوصول إلى الجهاز عرض هذه الرسائل بدون إدخال بيانات اعتماد المستخدم.

المتطلبات الأساسية

  • يجب إعداد الجهاز للتشغيل المباشر.
  • يجب أن يتوفّر على الجهاز إصدار حديث من خدمات Google Play مثبَّت (الإصدار 19.0.54 أو إصدار أحدث).
  • يجب أن يستخدم التطبيق حزمة تطوير البرامج (SDK) لخدمة "المراسلة عبر السحابة الإلكترونية من Firebase" (com.google.firebase:firebase-messaging) لتلقّي رسائل المراسلة عبر السحابة الإلكترونية من Firebase.

تفعيل معالجة الرسائل في وضع التشغيل المباشر في تطبيقك

  1. في ملف Gradle على مستوى التطبيق، أضِف تبعية إلى مكتبة دعم التشغيل المباشر للمراسلة عبر السحابة الإلكترونية من Firebase:

    implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0'
    
  2. يمكنك جعل تمهيد FirebaseMessagingService المباشر للتطبيق على دراية بها من خلال إضافة السمة android:directBootAware="true" في بيان التطبيق:

    <service
        android:name=".java.MyFirebaseMessagingService"
        android:exported="false"
        android:directBootAware="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    

من المهم التأكّد من أنّه يمكن تشغيل هذا FirebaseMessagingService في وضع التشغيل المباشر. يُرجى التحقّق مما يلي:

  • يجب ألا تصل الخدمة إلى وحدة تخزين محمية ببيانات الاعتماد أثناء التشغيل في وضع التشغيل المباشر.
  • ويجب ألا تحاول الخدمة استخدام مكونات، مثل Activities أو BroadcastReceivers أو Services الأخرى التي لا يتم وضع علامة عليها بأنّها "مدركة للتشغيل المباشر" أثناء التشغيل في وضع التشغيل المباشر.
  • يجب أيضًا ألا تصل أي مكتبات تستخدمها الخدمة إلى وحدة تخزين محمية ببيانات الاعتماد أو لاستدعاء مكونات غير directBootAware أثناء التشغيل في وضع التشغيل المباشر. وهذا يعني أنّ أي مكتبات يستخدمها التطبيق ويتم استدعاؤها من الخدمة يجب أن تكون على دراية بالتشغيل المباشر، أو يجب أن يتحقّق التطبيق ممّا إذا كان يعمل في وضع التشغيل المباشر وألا يستدعيها في هذا الوضع. على سبيل المثال، تعمل حِزم تطوير البرامج (SDK) لمنصة Firebase مع التشغيل المباشر (يمكن تضمينها في تطبيق بدون تعطله في وضع التشغيل المباشر)، إلا أن العديد من واجهات برمجة تطبيقات Firebase لا تتيح طلبه مباشرةً وضع التشغيل.
  • إذا كان التطبيق يستخدم Application مخصّصًا، يجب أن يكون Application على دراية بالتشغيل المباشر (لا يمكن الوصول إلى مساحة التخزين المحمية ببيانات الاعتماد في وضع التشغيل المباشر).

للحصول على إرشادات حول إرسال الرسائل إلى الأجهزة في وضع التشغيل المباشر، يمكنك الاطّلاع على إرسال رسائل مباشرة يتم تفعيل ميزة التمهيد: