Dengan FCM AndroidConfigV2, Anda dapat mengirim pesan berbasis intent ke perangkat Android dengan pengiriman notifikasi yang tepat waktu dan API yang disederhanakan.
Panduan ini membahas cara memigrasikan permintaan pengiriman backend Anda dari AndroidConfig
ke AndroidConfigV2 dan cara mengupdate klien aplikasi Android Anda
dari penanganan onMessageReceived lama ke callback klien v2 baru,
onNotificationReceived dan onBackgroundSyncReceived.
Yang baru di AndroidConfigV2
FCM AndroidConfigV2 API menyederhanakan pengalaman developer dengan memperkenalkan dua jenis pesan:
RemoteNotification: Direkomendasikan untuk semua pesan FCM yang menampilkan notifikasi mendesak dan sensitif terhadap waktu yang dapat dilihat pengguna. Pesan ini mengabaikan langkah-langkah penghematan baterai dan dikirim tanpa penundaan. Di perangkat, FCM SDK dan layanan Google Play bertanggung jawab untuk memposting notifikasi keNotificationManagerAndroid.BackgroundSync: Pesan data yang tidak mendesak yang ditujukan untuk sinkronisasi latar belakang dan update status aplikasi. Pengiriman dapat dikelompokkan atau ditunda untuk mengoptimalkan masa pakai baterai.
| Fitur | Lama (AndroidConfig v1) |
Baru (AndroidConfigV2) |
|---|---|---|
| Kolom konfigurasi | message.android |
message.android_v2 |
| Definisi prioritas | priority: "high" atau priority: "normal" eksplisit |
Tersirat oleh jenis union (remote_notification untuk pemberitahuan mendesak versus background_sync untuk sinkronisasi yang tidak mendesak) |
| Posting notifikasi | Aplikasi memanggil NotificationManager.notify() secara manual |
FCM SDK dan GMS Core memposting secara langsung atau menggunakan NotificationResponse |
| Callback klien | • onMessageReceived(RemoteMessage)• onDeletedMessages() |
• onNotificationReceived(RemoteMessage)• onBackgroundSyncReceived(RemoteMessage)• onDeletedMessages() |
| Dapat diciutkan | Bervariasi; memerlukan setelan eksplisit | Kedua jenis pesan dapat diciutkan atau tidak dapat diciutkan (tidak dapat diciutkan secara default) |
Mengizinkan permintaan kirim AndroidConfigV2
Anda dapat terus menggunakan token akses OAuth 2.0 yang berasal dari akun layanan Firebase menggunakan Kredensial Default Aplikasi Google atau Admin SDK, dan mengirim permintaan POST ke endpoint messages:send HTTP v1.
Jika Anda tidak menggunakan akun layanan Firebase, pastikan untuk menetapkan akun khusus Anda ke peran Admin Firebase Cloud Messaging API (roles/firebase.messagingAdmin)
dan meminta cakupan OAuth 2.0 https://www.googleapis.com/auth/firebase.messaging
saat membuat token akses:
POST https://fcm.googleapis.com/v1/projects/YOUR_PROJECT_ID/messages:send HTTP/1.1
Authorization: Bearer YOUR_OAUTH_ACCESS_TOKEN
Content-Type: application/json
Memperbarui permintaan kirim server (REST)
Untuk mengirim permintaan AndroidConfigV2 menggunakan REST API, ganti objek android
dalam isi permintaan Anda dengan android_v2. Dalam android_v2, tentukan parameter umum (seperti ttl, collapse_key, data, dan restricted_package_name), serta berikan salah satu kolom gabungan berikut: remote_notification atau background_sync.
Mengirim pesan RemoteNotification
Untuk mengirim notifikasi mendesak yang ditampilkan kepada pengguna, sertakan objek remote_notification
dan payload notification yang direkomendasikan. Secara default, mutable_content
ditetapkan ke false. GMS Core akan langsung merender dan memposting notifikasi ke
area notifikasi tanpa mengeksekusi kode aplikasi latar belakang.
Contoh JSON permintaan HTTP lengkap (Notifikasi yang dirender otomatis)
POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
"message": {
"token": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification": {
"title": "FCM Message",
"body": "This is an FCM notification message!"
},
"android_v2": {
"ttl": "3600s",
"remote_notification": {
"mutable_content": false,
"notification": {
"title": "Order update",
"body": "Your order has been shipped!",
"icon": "ic_notification_custom",
"sound": "default",
"tag": "alert_tag_1",
"id": 100
}
}
}
}
}
Mengirim RemoteNotification dengan konten yang dapat diubah
Jika aplikasi Anda perlu mengubah notifikasi di perangkat sebelum ditampilkan, tetapkan mutable_content: true di dalam remote_notification. Tindakan ini
memerintahkan GMS Core untuk mengikat ke aplikasi klien Anda dan memanggil
onNotificationReceived(). Hal ini berguna saat Anda ingin mendekripsi
payload terenkripsi end-to-end, melampirkan avatar pengguna, atau
melokalkan string.
Pastikan untuk menyertakan objek notification di dalam remote_notification meskipun
mutable_content adalah true. GMS Core menggunakan objek notification ini sebagai
notifikasi penggantian jika waktu tunggu callback klien habis atau melebihi
batas penekanan.
Jika Anda bermigrasi dari pesan data v1 lama dan ingin FCM mengirimkan payload ke penginstalan klien v1 lama sebagai pesan data murni, tetapkan use_as_v1_data_message: true di dalam remote_notification.
Contoh JSON permintaan HTTP lengkap
POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
"message": {
"token": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data": {
"encrypted_content": "U2FsdGVkX19vN2m+",
"sender_id": "user_98124"
},
"android_v2": {
"ttl": "3600s",
"remote_notification": {
"mutable_content": true,
"use_as_v1_data_message": true,
"notification": {
"title": "New message",
"body": "You have a new message",
"tag": "chat_alert",
"id": 1001
}
}
}
}
}
Mengirim pesan BackgroundSync
Untuk mengirim pesan yang tidak mendesak untuk sinkronisasi data latar belakang, update status senyap, atau mengupdate badge atau widget aplikasi, gunakan objek background_sync.
Jangan gunakan pesan ini untuk memposting
notifikasi yang terlihat oleh pengguna, karena pesan ini dapat dikelompokkan atau ditunda untuk mengoptimalkan
masa pakai baterai perangkat.
Contoh JSON permintaan HTTP lengkap
POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
"message": {
"token": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data": {
"score": "FETCH_UPDATES",
"sync_action": "FETCH_UPDATES"
},
"android_v2": {
"ttl": "86400s",
"collapse_key": "app_state_sync",
"background_sync": {}
}
}
}
Mengupdate callback klien Android
Untuk menerima pesan AndroidConfigV2 di Android, upgrade aplikasi Anda agar menggunakan firebase-messaging SDK terbaru. Perbarui layanan Anda yang memperluas
FirebaseMessagingService dengan mengimplementasikan onNotificationReceived() dan
onBackgroundSyncReceived().
Menginstal SDK EAP
Selama EAP, SDK firebase-messaging v2 didistribusikan sebagai arsip repositori Maven lokal, bukan melalui repositori Maven publik Google.
Tambahkan direktori
m2repositoryyang berisifirebase-messaging:26.1.0-eap01ke direktori utama project Android Anda (<project-root>/m2repository) menggunakan salah satu opsi berikut:- Opsi A: Download arsip bawaan: Download
FirebaseMessaging_26.1.0-eap01.zip
dan ekstrak direktori
m2repositoryke direktori root project Android Anda (<project-root>/m2repository). Opsi B: Build dari GitHub dengan Gradle: Clone cabang
feature/fcm-android-config-v2-eapdarifirebase/firebase-android-sdk, build repositori Maven lokal, dan salin direktoribuild/m2repositoryyang dihasilkan ke root project Android Anda:git clone --branch feature/fcm-android-config-v2-eap --single-branch \ https://github.com/firebase/firebase-android-sdk.git cd firebase-android-sdk ./gradlew -PprojectsToPublish="firebase-messaging" firebasePublish cp -R build/m2repository /path/to/your/android-project/m2repository
- Opsi A: Download arsip bawaan: Download
FirebaseMessaging_26.1.0-eap01.zip
dan ekstrak direktori
Dalam
settings.gradle.kts(atausettings.gradle) level project, tambahkan direktorim2repositorylokal ke bagian atas blokrepositories, di atasgoogle():Kotlin
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { maven { url = uri("${rootDir}/m2repository") } google() mavenCentral() } }Groovy
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { maven { url "${rootDir}/m2repository" } google() mavenCentral() } }Di
app/build.gradle.kts(atauapp/build.gradle) level modul, update dependensifirebase-messagingke26.1.0-eap01:Kotlin
dependencies { implementation("com.google.firebase:firebase-messaging:26.1.0-eap01") }Groovy
dependencies { implementation 'com.google.firebase:firebase-messaging:26.1.0-eap01' }Sinkronkan project Anda dengan file Gradle.
Menangani RemoteNotifications dengan onNotificationReceived
Dengan AndroidConfigV2, pesan RemoteNotification akan ditampilkan
kecuali jika mutable_content ditetapkan ke benar (true) atau pesan tersebut secara eksplisit disenyapkan di
onNotificationReceived().
Saat RemoteNotification tiba dengan mutable_content: true, GMS Core akan mengikat
ke aplikasi Anda dan memanggil onNotificationReceived(). Metode Anda harus
menampilkan NotificationResponse dalam waktu 20 detik.
Menampilkan notifikasi yang diubah
Objek Notification yang Anda teruskan ke NotificationResponse.create menggantikan properti payload penggantian remote_notification.notification server yang ditentukan dalam permintaan kirim. Untuk mempertahankan nilai dari permintaan kirim, baca nilai tersebut dari
message.notification (message.getNotification() di Java) saat menerapkan
modifikasi di perangkat:
Kotlin
import androidx.core.app.NotificationCompat
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.NotificationResponse
import com.google.firebase.messaging.RemoteMessage
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onNotificationReceived(message: RemoteMessage): NotificationResponse {
val serverNotif = message.notification
val channelId = serverNotif?.channelId ?: "default_channel"
// Keep the server-defined title unchanged, or fall back to default
val title = serverNotif?.title ?: "New message"
// Modify the notification body on-device (for example, decrypting data)
val decryptedBody = decryptPayload(message.data["encrypted_content"])
val builder = NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_stat_notification)
.setContentTitle(title)
.setContentText(decryptedBody)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
// Return the response for the open-source FCM SDK to post to the Android platform
return NotificationResponse.create("optional_tag", 100, builder.build())
}
}
Java
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import com.google.firebase.messaging.NotificationResponse;
import androidx.core.app.NotificationCompat;
public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public NotificationResponse onNotificationReceived(RemoteMessage message) {
RemoteMessage.Notification serverNotif = message.getNotification();
String channelId = (serverNotif != null && serverNotif.getChannelId() != null)
? serverNotif.getChannelId()
: "default_channel";
// Keep the server-defined title unchanged, or fall back to default
String title = (serverNotif != null && serverNotif.getTitle() != null)
? serverNotif.getTitle()
: "New message";
// Modify the notification body on-device (for example, decrypting data)
String decryptedBody = decryptPayload(message.getData().get("encrypted_content"));
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_stat_notification)
.setContentTitle(title)
.setContentText(decryptedBody)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true);
// Return the response for the open-source FCM SDK to post to the Android platform
return NotificationResponse.create("optional_tag", 100, builder.build());
}
}
Menyembunyikan notifikasi
Jika pengguna sedang membuka layar atau chat yang relevan, Anda dapat menyembunyikan
notifikasi dengan menampilkan NotificationResponse.suppress():
Kotlin
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ProcessLifecycleOwner
override fun onNotificationReceived(message: RemoteMessage): NotificationResponse {
val chatId = message.data["chat_id"]
val isAppForeground = ProcessLifecycleOwner.get()
.lifecycle
.currentState
.isAtLeast(Lifecycle.State.STARTED)
if (isAppForeground && chatRepository.isConversationActive(chatId)) {
// Suppress notification display because the user is actively viewing this chat
return NotificationResponse.suppress()
}
val builder = buildNotificationForChat(message)
return NotificationResponse.create("chat_tag", 101, builder.build())
}
Java
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.ProcessLifecycleOwner;
@Override
public NotificationResponse onNotificationReceived(RemoteMessage message) {
String chatId = message.getData().get("chat_id");
boolean isAppForeground = ProcessLifecycleOwner.get()
.getLifecycle()
.getCurrentState()
.isAtLeast(Lifecycle.State.STARTED);
if (isAppForeground && chatRepository.isConversationActive(chatId)) {
// Suppress notification display because the user is actively viewing this chat
return NotificationResponse.suppress();
}
NotificationCompat.Builder builder = buildNotificationForChat(message);
return NotificationResponse.create("chat_tag", 101, builder.build());
}
Notifikasi streaming atau batalkan pemberitahuan lama (FcmNotificationManager)
Jika Anda perlu memposting beberapa notifikasi untuk satu push masuk, atau membatalkan
notifikasi yang sudah tidak berlaku sebelum menampilkan notifikasi baru, gunakan FcmNotificationManager:
Kotlin
override fun onNotificationReceived(message: RemoteMessage): NotificationResponse {
// Retrieve the scoped manager for this message execution
val manager = getFcmNotificationManager(message)
// 1. Cancel an outdated notification right away
manager.cancelNow("message_tag", 50)
// 2. Post the item notification immediately
val itemNotif = NotificationCompat.Builder(this, "chat_channel")
.setSmallIcon(R.drawable.ic_message)
.setContentTitle("Alex")
.setContentText(message.data["text"])
manager.postNow("item_tag", 51, itemNotif.build())
// 3. Post a group summary notification
val summaryNotif = NotificationCompat.Builder(this, "chat_channel")
.setSmallIcon(R.drawable.ic_message)
.setContentTitle("New Conversations")
.setGroupSummary(true)
manager.postNow("summary_tag", 52, summaryNotif.build())
// 4. Return finished() to complete the streaming workflow
return manager.finished()
}
Java
@Override
public NotificationResponse onNotificationReceived(RemoteMessage message) {
// Retrieve the scoped manager for this message execution
FcmNotificationManager manager = getFcmNotificationManager(message);
// 1. Cancel an outdated notification right away
manager.cancelNow("message_tag", 50);
// 2. Post the item notification immediately
NotificationCompat.Builder itemNotif = new NotificationCompat.Builder(this, "chat_channel")
.setSmallIcon(R.drawable.ic_message)
.setContentTitle("Alex")
.setContentText(message.getData().get("text"));
manager.postNow("item_tag", 51, itemNotif.build());
// 3. Post a group summary notification
NotificationCompat.Builder summaryNotif = new NotificationCompat.Builder(this, "chat_channel")
.setSmallIcon(R.drawable.ic_message)
.setContentTitle("New Conversations")
.setGroupSummary(true);
manager.postNow("summary_tag", 52, summaryNotif.build());
// 4. Return finished() to complete the streaming workflow
return manager.finished();
}
Menangani pesan BackgroundSync menggunakan onBackgroundSyncReceived
Untuk memproses pesan BackgroundSync di Android, gunakan
onBackgroundSyncReceived():
Kotlin
override fun onBackgroundSyncReceived(message: RemoteMessage) {
val syncCommand = message.data["sync_action"]
try {
// Perform local database synchronization or cache refresh
AppDataRepository.getInstance(applicationContext).syncWithServer(syncCommand)
} catch (e: Exception) {
Log.e("FCM", "Background sync operation failed", e)
}
// Execution completes -> GMS Core marks the message as handled and unbinds.
}
Java
@Override
public void onBackgroundSyncReceived(RemoteMessage message) {
String syncCommand = message.getData().get("sync_action");
try {
// Perform local database synchronization or cache refresh
AppDataRepository.getInstance(getApplicationContext()).syncWithServer(syncCommand);
} catch (Exception e) {
Log.e("FCM", "Background sync operation failed", e);
}
// Execution completes -> GMS Core marks the message as handled and unbinds.
}
Menangani penghapusan pesan yang tertunda menggunakan onDeletedMessages
Dalam beberapa situasi, seperti saat perangkat tidak terhubung ke FCM dalam
jangka waktu yang lama atau saat antrean server penuh, FCM dapat menghapus
pesan yang tertunda sebelum pengiriman. Dalam kasus ini, ganti
onDeletedMessages():
Kotlin
override fun onDeletedMessages() {
// Perform a full state synchronization with your app server
AppDataRepository.getInstance(applicationContext).scheduleFullSync()
}
Java
@Override
public void onDeletedMessages() {
// Perform a full state synchronization with your app server
AppDataRepository.getInstance(getApplicationContext()).scheduleFullSync();
}
Memigrasikan aplikasi tertentu
Mengirimkan notifikasi terenkripsi end-to-end (E2EE)
Saat mengirimkan notifikasi terenkripsi end-to-end menggunakan
RemoteNotification, konten notifikasi yang didekripsi
tetap berada dalam aplikasi Anda dan platform Android:
- Mengirimkan notifikasi yang dapat diubah:
Server Anda mengirimkan
RemoteNotificationdenganmutable_content: true, payload terenkripsi didata, dan cadangan generik yang tidak dienkripsinotification. GMS Core mengirimkan pesan terenkripsi ke FCM SDK open source di dalam aplikasi Anda. - Mendekripsi dan menampilkan notifikasi: FCM SDK memanggil
onNotificationReceived(). Aplikasi Anda mendekripsi payload secara lokal, mem-buildNotificationAndroid yang didekripsi akhir, dan meneruskannya kembali ke FCM SDK open source menggunakanNotificationResponseatauFcmNotificationManager. - Memposting ke platform dan melaporkan metadata: SDK FCM open source
memposting notifikasi yang didekripsi langsung ke API
NotificationManagerplatform Android dan hanya mengirim metadata notifikasi, seperti ID notifikasi dan stempel waktu, kembali ke GMS Core untuk visibilitas pengiriman. Konten yang didekripsi tidak pernah dikirim ke GMS Core. - Memposting notifikasi cadangan jika perlu: Hanya jika aplikasi Anda gagal merespons
dalam waktu tunggu 20 detik atau melebihi batas penekanan
latar belakang, GMS Core akan memposting
notificationcadangan umum langsung ke platform Android.

Memahami penonaktifan dan waktu tunggu notifikasi
Untuk mempertahankan pengiriman yang andal di seluruh ekosistem Android, GMS Core menerapkan
waktu tunggu pemrosesan dan batas penekanan notifikasi saat menangani
pesan RemoteNotification:
Waktu tunggu pemrosesan
Jika mutable_content ditetapkan ke true, metode onNotificationReceived() Anda
harus menampilkan NotificationResponse dalam waktu 20 detik. Jika
eksekusi melebihi batas ini, callback akan dibatalkan dan GMS Core
akan otomatis memposting notifikasi penggantian yang dirender dari
payload remote_notification.notification.
Rasio penekanan notifikasi
Karena pesan RemoteNotification mengabaikan batasan Istirahatkan untuk segera memberi tahu pengguna dan dikirim tanpa penundaan, aplikasi diharapkan menampilkan notifikasi untuk pesan RemoteNotification yang diterima.
Setiap aplikasi diizinkan untuk menyembunyikan hingga
25% traffic RemoteNotification-nya saat berjalan
di latar belakang. Jika tingkat penghentian aplikasi melebihi
25%, GMS Core akan otomatis merender dan memposting
notifikasi pengganti yang dirender dari payload
remote_notification.notification.
Penekanan yang dilakukan saat aplikasi aktif di latar depan tidak dihitung dalam batas ini. Aplikasi yang diberi izin penggunaan latar belakang tanpa batas juga dikecualikan dari batas penekanan latar belakang.