Perilaku notifikasi Firebase berbeda-beda, tergantung apakah status aplikasi penerimanya sedang di latar depan atau latar belakang. Jika ingin aplikasi yang berada di latar depan menerima pesan notifikasi atau pesan data, Anda harus menulis kode untuk menangani callback onMessageReceived
.
Penjelasan mengenai perbedaan antara pesan notifikasi dan pesan data dapat dibaca di bagian Jenis pesan.
Menangani pesan
Untuk menerima pesan, gunakan layanan yang menyediakan
FirebaseMessagingService
.
Layanan Anda harus mengganti callback onMessageReceived
dan onDeletedMessages
.
onMessageReceived
disediakan untuk sebagian besar jenis pesan, dengan pengecualian berikut:
-
Pesan notifikasi yang dikirim saat aplikasi berada di latar belakang. Dalam hal ini, notifikasi dikirimkan ke area notifikasi perangkat. Ketika pengguna mengetuk notifikasi, peluncur aplikasi akan terbuka secara default.
-
Pesan dengan notifikasi dan payload data, saat diterima di latar belakang. Dalam hal ini, notifikasi dikirimkan ke area notifikasi perangkat, dan payload data dikirimkan di bagian tambahan dari intent Aktivitas peluncur.
Rangkuman:
Status aplikasi | Notifikasi | Data | Keduanya |
---|---|---|---|
Latar depan | onMessageReceived |
onMessageReceived |
onMessageReceived |
Latar belakang | Baki sistem | onMessageReceived |
Notifikasi: area notifikasi Data: di bagian tambahan intent. |
Callback onMessageReceived
diberi waktu tunggu yang cukup bagi Anda untuk sekadar memposting
notifikasi, tetapi timer tidak dirancang untuk memungkinkan aplikasi mengakses jaringan atau melakukan
pekerjaan tambahan. Oleh karena itu, jika aplikasi Anda melakukan sesuatu yang lebih rumit, Anda perlu melakukan
pekerjaan tambahan untuk memastikan aplikasi dapat menyelesaikan pekerjaannya.
Jika aplikasi Anda diperkirakan memerlukan waktu hampir 10 detik untuk menangani pesan, Anda harus
menjadwalkan tugas WorkManager
atau mengikuti
panduan WakeLock di bawah. Dalam beberapa
kasus, rentang waktu untuk menangani pesan mungkin kurang dari 10 detik, bergantung pada penundaan
yang terjadi sebelum panggilan onMessageReceived
, termasuk penundaan OS, waktu startup aplikasi,
thread utama yang diblokir oleh operasi lain, atau panggilan onMessageReceived
sebelumnya yang memerlukan waktu terlalu lama. Setelah timer tersebut berakhir, aplikasi Anda mungkin
dapat dikenai
penghentian proses
atau
batas eksekusi latar belakang. Perlu diingat, latensi untuk transaksi jaringan dan startup aplikasi dapat signifikan. Jika ragu,
rencanakan pemrosesan pesan Anda agar berjalan lama jika ada dependensi asinkron
seperti akses jaringan atau persyaratan pemuatan data yang intensif.
Mengedit manifes aplikasi
Untuk menggunakan FirebaseMessagingService
, Anda perlu menambahkan hal berikut di manifes aplikasi:
<service android:name=".java.MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
Anda sebaiknya juga mengatur nilai default untuk menyesuaikan tampilan notifikasi. Anda dapat menentukan ikon dan warna default kustom yang diterapkan setiap kali nilai yang setara tidak ditetapkan dalam payload notifikasi.
Tambahkan baris berikut di dalam tag application
untuk menetapkan ikon default kustom dan warna default kustom:
<!-- 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 kustom untuk
- Semua pesan notifikasi yang dikirim dari Notifications Composer.
- Pesan notifikasi yang tidak secara eksplisit menetapkan ikon dalam payload notifikasi.
Android menggunakan warna default kustom untuk
- Semua pesan notifikasi yang dikirim dari Notifications Composer.
- Pesan notifikasi yang tidak secara eksplisit menetapkan warna dalam payload notifikasi.
Jika tidak ada ikon default kustom yang ditetapkan dan tidak ada ikon yang ditetapkan dalam payload notifikasi, Android akan menampilkan ikon aplikasi dengan warna putih.
Mengganti onMessageReceived
Dengan mengganti metode FirebaseMessagingService.onMessageReceived
, Anda dapat melakukan tindakan berdasarkan objek RemoteMessage yang diterima dan mendapatkan data pesan:
Kotlin
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. }
Menjaga perangkat tetap aktif saat menangani pesan FCM
Jika aplikasi Anda memerlukan perangkat tetap aktif saat memproses pesan FCM, aplikasi harus
menahan WakeLock selama pemrosesan atau harus membuat tugas WorkManager. WakeLock berfungsi dengan baik
untuk aktivitas pemrosesan singkat yang mungkin melampaui waktu tunggu
default onMessageReceived
. Untuk alur kerja yang diperpanjang, seperti mengirim beberapa RPC seri ke server Anda, menggunakan
tugas WorkManager lebih tepat daripada WakeLock. Di bagian ini, kita akan berfokus pada cara menggunakan
WakeLock. WakeLock mencegah perangkat dari tertidur saat aplikasi Anda berjalan, yang dapat
meningkatkan penggunaan baterai, sehingga penggunaan WakeLock harus dicadangkan apabila aplikasi Anda
tidak boleh dijeda saat menangani pesan seperti:
- Notifikasi kepada pengguna dengan waktu yang terbatas.
- Interaksi dengan sesuatu di luar perangkat yang tidak boleh terganggu (seperti transfer jaringan atau komunikasi dengan perangkat lain, seperti smartwatch yang disambungkan).
Pertama, Anda harus memastikan bahwa aplikasi Anda meminta izin WakeLock (FCM SDK menyertakannya secara default, jadi biasanya tidak ada yang perlu ditambahkan).
<uses-permission android:name="android.permission.WAKE_LOCK" />
Kemudian, aplikasi Anda harus mendapatkan WakeLock di awal callback FirebaseMessagingService.onMessageReceived()
dan melepaskannya di akhir callback.
FirebaseMessagingService
kustom aplikasi:
@Override public void onMessageReceived(final RemoteMessage message) { // If this is a message that is time sensitive or shouldn't be interrupted WakeLock wakeLock = getSystemService(PowerManager.class).newWakeLock(PARTIAL_WAKE_LOCK, "myApp:messageReceived"); try { wakeLock.acquire(TIMEOUT_MS); // handle message ... finally { wakeLock.release(); } }
Mengganti onDeletedMessages
Dalam beberapa situasi, FCM mungkin tidak mengirimkan pesan. Hal ini terjadi jika ada terlalu banyak pesan (>100) yang tertunda untuk aplikasi Anda pada perangkat tertentu saat terhubung, atau jika perangkat belum terhubung ke FCM selama lebih dari satu bulan. Dalam hal ini, Anda mungkin akan menerima callback ke FirebaseMessagingService.onDeletedMessages()
.
Saat menerima callback ini, instance aplikasi harus melakukan sinkronisasi penuh dengan server aplikasi. Jika Anda belum mengirim pesan ke aplikasi pada perangkat tersebut dalam 4 minggu terakhir, FCM tidak akan memanggil onDeletedMessages()
.
Menangani pesan notifikasi dalam aplikasi di latar belakang
Ketika aplikasi Anda berada di latar belakang, Android akan mengarahkan pesan notifikasi ke area notifikasi. Ketika pengguna mengetuk notifikasi, peluncur aplikasi akan terbuka secara default.
Ini termasuk pesan yang berisi notifikasi dan payload data (dan semua pesan yang dikirim dari konsol Notifications). Dalam hal ini, notifikasi dikirim ke area notifikasi perangkat dan payload data dikirim di bagian tambahan dari intent Aktivitas peluncur.
Untuk melihat data terkait pengiriman pesan ke aplikasi Anda, lihat dasbor pelaporan FCM, yang mencatat jumlah pesan yang terkirim dan dibuka di perangkat Apple dan Android, beserta data untuk "tayangan" (notifikasi yang dilihat oleh pengguna) untuk aplikasi Android.
Menerima pesan FCM dalam mode booting langsung
Developer yang ingin mengirim pesan FCM ke aplikasi bahkan sebelum kunci perangkat dibuka dapat mengaktifkan aplikasi Android untuk menerima pesan saat perangkat dalam mode booting langsung. Misalnya, Anda mungkin ingin pengguna aplikasi Anda menerima notifikasi alarm meskipun perangkatnya sedang terkunci.
Saat menangani kasus penggunaan ini, ikuti praktik terbaik dan pembatasan umum untuk mode booting langsung. Pertimbangkan visibilitas pesan dalam mode booting langsung. Setiap pengguna yang memiliki akses ke perangkat dapat melihat pesan ini tanpa memasukkan kredensial pengguna.
Prasyarat
- Perangkat harus disiapkan untuk mode booting langsung.
- Layanan Google Play versi terbaru (19.0.54 atau yang lebih baru) harus terinstal di perangkat.
- Aplikasi harus menggunakan FCM SDK (
com.google.firebase:firebase-messaging
) untuk menerima pesan FCM.
Mengaktifkan penanganan pesan dalam mode booting langsung di aplikasi
Di file Gradle level aplikasi, tambahkan dependensi pada support library booting langsung FCM:
implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0'
Buat agar
FirebaseMessagingService
aplikasi Anda sadar booting langsung dengan cara 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>
Pastikan bahwa FirebaseMessagingService
ini dapat dijalankan dalam mode booting langsung. Periksa persyaratan berikut:
- Layanan tidak boleh mengakses penyimpanan yang dilindungi kredensial saat dijalankan dalam mode booting langsung.
- Layanan tidak boleh mencoba menggunakan komponen, seperti
Activities
,BroadcastReceivers
, atauServices
lain yang tidak ditandai sebagai sadar booting langsung saat dijalankan dalam mode booting langsung. - Library apa pun yang digunakan oleh layanan ini juga tidak boleh mengakses penyimpanan yang dilindungi kredensial dan tidak boleh memanggil komponen non-directBootAware saat dijalankan dalam mode booting langsung. Artinya, library apa pun yang digunakan aplikasi dan dipanggil dari layanan ini haruslah sadar booting langsung, atau aplikasi harus memeriksa apakah sedang berjalan dalam mode booting langsung dan tidak memanggil library dalam mode tersebut. Misalnya, Firebase SDK berfungsi dengan booting langsung (dapat disertakan dalam aplikasi tanpa mengalami error dalam mode booting langsung), tetapi banyak Firebase API tidak mendukung pemanggilan dalam mode booting langsung.
- Jika aplikasi menggunakan
Application
kustom,Application
juga harus sadar booting langsung (tidak memiliki akses ke penyimpanan yang dilindungi kredensial dalam mode booting langsung).
Untuk mendapatkan panduan tentang cara mengirim pesan ke perangkat dalam mode booting langsung, lihat Mengirim pesan dalam mode booting langsung.