تلقي الرسائل في تطبيق 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() عندما يتلقى مثيل التطبيق رد الاتصال هذا ، يجب أن يقوم بإجراء مزامنة كاملة مع خادم التطبيق الخاص بك. إذا لم تكن قد أرسلت رسالة إلى التطبيق على هذا الجهاز خلال الأسابيع الأربعة الماضية ، فلن تستدعي FCM onDeletedMessages() .

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

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

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

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

تلقي رسائل FCM في وضع التمهيد المباشر

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

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

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

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

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

  1. في ملف Gradle على مستوى التطبيق ، أضف تبعية إلى مكتبة دعم التمهيد المباشر FCM:

    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 أثناء التشغيل في وضع التمهيد المباشر. هذا يعني أن أي مكتبات يستخدمها التطبيق يتم استدعاؤها من الخدمة إما أن تكون على دراية بالتمهيد المباشر ، أو سيحتاج التطبيق إلى التحقق مما إذا كان يعمل في وضع التمهيد المباشر وعدم الاتصال بها في هذا الوضع. على سبيل المثال ، تعمل حزم Firebase SDK مع التمهيد المباشر (يمكن تضمينها في أحد التطبيقات دون تعطله في وضع التمهيد المباشر) ، ولكن العديد من واجهات برمجة تطبيقات Firebase لا تدعم الاستدعاء في وضع التمهيد المباشر.
  • إذا كان التطبيق يستخدم Application مخصصًا ، فسيحتاج Application أيضًا إلى أن يكون على دراية بالتمهيد المباشر (لا يمكن الوصول إلى وحدة التخزين المحمية ببيانات الاعتماد في وضع التمهيد المباشر).

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