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

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

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

لتلقي الرسائل، استخدام الخدمة التي تمتد FirebaseMessagingService . الخدمة الخاص بك يجب تجاوز onMessageReceived و onDeletedMessages رد. يجب أن يتعامل مع أي رسالة في غضون 20 ثانية من استلامها (10 ثوانٍ على Android Marshmallow). قد يكون إطار زمني أقصر اعتمادا على التأخير OS المتكبدة قبل الدعوة onMessageReceived . بعد ذلك الوقت، ومختلف السلوكيات OS مثل الروبوت 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 الكائن والحصول على بيانات الرسالة:

جافا

@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.
}

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}")

        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.
    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.
}

تجاوز onDeletedMessages

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

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

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

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

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

التطبيقات المقيدة في الخلفية (Android P أو الأحدث)

FCM قد لا تسليم الرسائل إلى التطبيقات التي وضعت في تقييد الخلفية من قبل المستخدم (مثل عن طريق: إعداد -> تطبيقات وإعلام -> [APPNAME] -> البطارية). بمجرد إزالة تطبيقك من قيود الخلفية ، سيتم تسليم الرسائل الجديدة إلى التطبيق كما كان من قبل. من أجل منع الرسائل المفقودة وغيرها من الآثار تقييد الخلفية، احرص على تجنب السلوكيات السيئة المدرجة من قبل الحيويه الروبوت الجهد. قد تؤدي هذه السلوكيات إلى أن يوصي جهاز Android المستخدم بتقييد تطبيقك في الخلفية. التطبيق يمكن معرفة ما اذا كان هو الخلفية يقتصر استخدام: isBackgroundRestricted () .

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

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

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

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

  • يجب إعداد الجهاز على وضع التمهيد المباشر.
  • يجب أن يكون الجهاز مثبتًا عليه إصدار حديث من خدمات Google Play (19.0.54 أو أحدث).
  • التطبيق يجب أن تستخدم SDK FCM ( 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 سوف تحتاج أيضا إلى أن يكون التمهيد المباشر علم (أي الوصول إلى التخزين المحمي الاعتماد في وضع التشغيل المباشر).

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