Notifikasi Firebase berperilaku berbeda bergantung pada status latar depan/latar belakang aplikasi penerima. Jika Anda ingin aplikasi latar depan menerima pesan notifikasi atau pesan data, Anda harus menulis kode untuk menangani callback onMessageReceived
. Untuk penjelasan tentang perbedaan antara pesan notifikasi dan data, lihat Jenis pesan .
Menangani pesan
Untuk menerima pesan, gunakan layanan yang memperluas FirebaseMessagingService . Layanan Anda harus mengganti callback onMessageReceived
dan onDeletedMessages
. Itu harus menangani pesan apa pun dalam waktu 20 detik setelah diterima (10 detik di Android Marshmallow). Jendela waktu mungkin lebih pendek tergantung pada penundaan OS yang terjadi sebelum memanggil onMessageReceived
. Setelah itu, berbagai perilaku OS seperti batas eksekusi latar belakang Android O dapat mengganggu kemampuan Anda untuk menyelesaikan pekerjaan. Untuk informasi lebih lanjut, lihat ikhtisar kami tentang prioritas pesan .
onMessageReceived
disediakan untuk sebagian besar jenis pesan, dengan pengecualian berikut:
Pesan notifikasi dikirimkan saat aplikasi Anda berada di latar belakang . Dalam hal ini, notifikasi dikirimkan ke baki sistem perangkat. Pengguna yang mengetuk notifikasi akan membuka peluncur aplikasi secara default.
Pesan dengan pemberitahuan dan muatan data, saat diterima di latar belakang . Dalam hal ini, pemberitahuan dikirimkan ke baki sistem perangkat, dan muatan data dikirimkan sebagai tambahan maksud dari Aktivitas peluncur Anda.
Kesimpulan:
Status aplikasi | Pemberitahuan | Data | Keduanya |
---|---|---|---|
Latar depan | onMessageReceived | onMessageReceived | onMessageReceived |
Latar belakang | Baki sistem | onMessageReceived | Pemberitahuan: baki sistem Data: dalam tambahan maksud. |
Edit manifes aplikasi
Untuk menggunakan FirebaseMessagingService
, Anda perlu menambahkan yang berikut di manifes aplikasi Anda:
<service android:name=".java.MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
Selain itu, Anda disarankan untuk menyetel nilai default untuk menyesuaikan tampilan notifikasi. Anda dapat menentukan ikon default kustom dan warna default kustom yang diterapkan setiap kali nilai yang setara tidak diatur dalam payload notifikasi.
Tambahkan baris ini di dalam tag application
untuk menyetel ikon default khusus dan warna khusus:
<!-- 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 menampilkan ikon default khusus untuk
- Semua pesan notifikasi dikirim dari Notifications composer .
- Setiap pesan notifikasi yang tidak menetapkan ikon secara eksplisit di payload notifikasi.
Android menggunakan warna default khusus untuk
- Semua pesan notifikasi dikirim dari Notifications composer .
- Setiap pesan notifikasi yang tidak menetapkan warna secara eksplisit dalam payload notifikasi.
Jika tidak ada ikon default khusus yang disetel dan tidak ada ikon yang disetel dalam payload notifikasi, Android akan menampilkan ikon aplikasi yang dirender dalam warna putih.
Timpa onMessageReceived
Dengan mengganti metode FirebaseMessagingService.onMessageReceived
, Anda bisa melakukan tindakan berdasarkan objek RemoteMessage yang diterima dan mendapatkan data pesan:
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. }
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. }
Ganti onDeletedMessages
Dalam beberapa situasi, FCM mungkin tidak mengirimkan pesan. Hal ini terjadi jika ada terlalu banyak pesan (>100) yang tertunda untuk aplikasi Anda di perangkat tertentu saat terhubung atau jika perangkat tidak terhubung ke FCM selama lebih dari satu bulan. Dalam kasus ini, Anda mungkin menerima callback ke FirebaseMessagingService.onDeletedMessages()
Saat instance aplikasi menerima callback ini, instance aplikasi harus melakukan sinkronisasi penuh dengan server aplikasi Anda. Jika Anda belum mengirim pesan ke aplikasi di perangkat tersebut dalam 4 minggu terakhir, FCM tidak akan memanggil onDeletedMessages()
.Tangani pesan notifikasi di aplikasi latar belakang
Saat aplikasi Anda berada di latar belakang, Android mengarahkan pesan notifikasi ke baki sistem. Ketukan pengguna pada notifikasi membuka peluncur aplikasi secara default.
Ini termasuk pesan yang berisi notifikasi dan payload data (dan semua pesan yang dikirim dari konsol Notifications). Dalam kasus ini, pemberitahuan dikirimkan ke baki sistem perangkat, dan muatan data dikirimkan sebagai tambahan maksud dari Aktivitas peluncur Anda.
Untuk wawasan tentang pengiriman pesan ke aplikasi Anda, lihat dasbor pelaporan FCM , yang mencatat jumlah pesan yang dikirim dan dibuka di perangkat Apple dan Android, beserta data untuk "tayangan" (pemberitahuan yang dilihat oleh pengguna) untuk aplikasi Android.
Aplikasi yang Dibatasi Latar Belakang (Android P atau yang lebih baru)
FCM tidak boleh mengirimkan pesan ke aplikasi yang dimasukkan ke dalam batasan latar belakang oleh pengguna (seperti melalui: Pengaturan -> Aplikasi dan Pemberitahuan -> [nama aplikasi] -> Baterai). Setelah aplikasi Anda dihapus dari pembatasan latar belakang, pesan baru ke aplikasi akan dikirimkan seperti sebelumnya. Untuk mencegah pesan hilang dan dampak pembatasan latar belakang lainnya, pastikan untuk menghindari perilaku buruk yang dicantumkan oleh upaya Android vitals . Perilaku ini dapat menyebabkan perangkat Android merekomendasikan kepada pengguna agar aplikasi Anda dibatasi di latar belakang. Aplikasi Anda dapat memeriksa apakah latar belakangnya dibatasi menggunakan: isBackgroundRestricted() .Terima pesan FCM dalam mode boot langsung
Pengembang yang ingin mengirim pesan FCM ke aplikasi bahkan sebelum perangkat dibuka kuncinya dapat mengaktifkan aplikasi Android untuk menerima pesan saat perangkat dalam mode boot langsung. Misalnya, Anda mungkin ingin pengguna aplikasi Anda menerima notifikasi alarm bahkan pada perangkat yang terkunci.
Saat membuat kasus penggunaan ini, amati praktik terbaik dan pembatasan umum untuk mode boot langsung . Sangat penting untuk mempertimbangkan visibilitas pesan yang mendukung boot langsung; setiap pengguna dengan akses ke perangkat dapat melihat pesan ini tanpa memasukkan kredensial pengguna.
Prasyarat
- Perangkat harus diatur untuk mode boot langsung.
- Perangkat harus menginstal layanan Google Play versi terbaru (19.0.54 atau lebih baru).
- Aplikasi harus menggunakan FCM SDK (
com.google.firebase:firebase-messaging
) untuk menerima pesan FCM.
Aktifkan penanganan pesan mode boot langsung di aplikasi Anda
Di file Gradle tingkat aplikasi, tambahkan dependensi pada pustaka dukungan booting langsung FCM:
implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0'
Membuat booting langsung
FirebaseMessagingService
aplikasi menjadi sadar dengan menambahkan atributandroid:directBootAware="true"
dalam manifes aplikasi:<service android:name=".java.MyFirebaseMessagingService" android:exported="false" android:directBootAware="true"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
Penting untuk memastikan bahwa FirebaseMessagingService
ini dapat dijalankan dalam mode boot langsung. Periksa persyaratan berikut:
- Layanan tidak boleh mengakses penyimpanan yang dilindungi kredensial saat berjalan dalam mode boot langsung.
- Layanan tidak boleh mencoba menggunakan komponen, seperti
Activities
,BroadcastReceivers
, atauServices
lain yang tidak ditandai sebagai direct boot aware saat dijalankan dalam mode direct boot. - Pustaka apa pun yang digunakan layanan juga tidak boleh mengakses penyimpanan yang dilindungi kredensial atau memanggil komponen non-directBootAware saat berjalan dalam mode boot langsung. Ini berarti bahwa pustaka apa pun yang digunakan aplikasi yang dipanggil dari layanan harus sadar boot langsung, atau aplikasi perlu memeriksa apakah itu berjalan dalam mode boot langsung dan tidak memanggilnya dalam mode itu. Misalnya, Firebase SDK bekerja dengan boot langsung (mereka dapat disertakan dalam aplikasi tanpa merusaknya dalam mode boot langsung), tetapi banyak API Firebase tidak mendukung pemanggilan dalam mode boot langsung.
- Jika aplikasi menggunakan
Application
khusus,Application
juga harus sadar boot langsung (tidak ada akses ke penyimpanan yang dilindungi kredensial dalam mode boot langsung).
Untuk panduan mengirim pesan ke perangkat dalam mode boot langsung, lihat Mengirim pesan yang mendukung boot langsung .