Untuk menargetkan pesan ke beberapa perangkat, gunakan Pesan topik. Dengan fitur ini, Anda dapat mengirim pesan ke beberapa perangkat yang memilih untuk ikut serta dalam topik tertentu.
Tutorial ini berfokus pada pengiriman pesan topik dari server aplikasi Anda menggunakan Admin SDK atau REST API untuk FCM, serta penerimaan dan penanganan pesan tersebut di aplikasi Android. Kami akan membahas penanganan pesan untuk aplikasi yang dijalankan di latar belakang dan latar depan. Semua langkah untuk mencapai hal ini akan dibahas, mulai dari penyiapan sampai verifikasi.
Menyiapkan SDK
Bagian ini membahas langkah-langkah yang mungkin telah diselesaikan ketika Anda menyiapkan aplikasi klien Android untuk FCM atau ketika bersiap Mengirim Pesan Pertama.
Sebelum memulai
Instal atau update Android Studio ke versi terbaru.
Pastikan project Anda memenuhi persyaratan berikut (perhatikan bahwa beberapa produk mungkin memiliki persyaratan yang lebih ketat):
- Level API target 21 (Lollipop) atau yang lebih baru
- Menggunakan Android 5.0 atau yang lebih baru
- Menggunakan
Jetpack (AndroidX),
termasuk memenuhi persyaratan versi berikut ini:
com.android.tools.build:gradle
v7.3.0 atau yang lebih barucompileSdkVersion
28 atau yang lebih baru
Siapkan perangkat fisik atau gunakan emulator untuk menjalankan aplikasi Anda.
Perhatikan bahwa Firebase SDK yang memiliki dependensi pada layanan Google Play mengharuskan layanan Google Play diinstal di perangkat atau emulator.Login ke Firebase menggunakan akun Google Anda.
Jika belum memiliki project Android dan hanya ingin mencoba produk Firebase, download salah satu contoh panduan memulai.
Membuat project Firebase
Agar dapat menambahkan Firebase ke aplikasi Android, Anda perlu membuat project Firebase yang akan dihubungkan ke aplikasi Android. Buka bagian Memahami Project Firebase untuk mempelajari project Firebase lebih lanjut.
Mendaftarkan aplikasi ke Firebase
Untuk menggunakan Firebase di aplikasi Android, Anda perlu mendaftarkan aplikasi ke project Firebase. Mendaftarkan aplikasi sering kali disebut sebagai "menambahkan" aplikasi ke project Anda.
Buka Firebase console.
Di bagian tengah halaman ringkasan project, klik ikon Android (
) atau Add app untuk meluncurkan alur kerja penyiapan.Masukkan nama paket aplikasi Anda di kolom Android package name.
(Opsional) Masukkan informasi aplikasi yang lain: App nickname dan Debug signing certificate SHA-1.
Klik Register app.
Menambahkan file konfigurasi Firebase
Download, lalu tambahkan file konfigurasi Android Firebase (
) ke aplikasi Anda:google-services.json Klik Download google-services.json untuk mendapatkan file konfigurasi Android Firebase Anda.
Pindahkan file konfigurasi ke direktori root modul (level aplikasi) aplikasi Anda.
Agar nilai dalam file konfigurasi
Anda dapat diakses oleh Firebase SDK, Anda memerlukan plugin Gradle layanan Google (google-services.json google-services
).Dalam file Gradle level root (level project) (
<project>/build.gradle.kts
atau<project>/build.gradle
), tambahkan plugin layanan Google sebagai dependensi:Kotlin
plugins { id("com.android.application") version "7.3.0" apply false // ... // Add the dependency for the Google services Gradle plugin id("com.google.gms.google-services") version "4.4.2" apply false }
Groovy
plugins { id 'com.android.application' version '7.3.0' apply false // ... // Add the dependency for the Google services Gradle plugin id 'com.google.gms.google-services' version '4.4.2' apply false }
Dalam file Gradle modul (level aplikasi) (biasanya
<project>/<app-module>/build.gradle.kts
atau<project>/<app-module>/build.gradle
), tambahkan plugin layanan Google:Kotlin
plugins { id("com.android.application") // Add the Google services Gradle plugin id("com.google.gms.google-services") // ... }
Groovy
plugins { id 'com.android.application' // Add the Google services Gradle plugin id 'com.google.gms.google-services' // ... }
Menambahkan Firebase SDK ke aplikasi Anda
Dalam file Gradle modul (level aplikasi) (biasanya
<project>/<app-module>/build.gradle.kts
atau<project>/<app-module>/build.gradle
), tambahkan dependensi untuk library Firebase Cloud Messaging untuk Android. Sebaiknya gunakan Firebase Android BoM untuk mengontrol pembuatan versi library.Untuk mengoptimalkan penggunaan Firebase Cloud Messaging, sebaiknya aktifkan Google Analytics di project Firebase dan tambahkan Firebase SDK untuk Google Analytics ke aplikasi Anda.
dependencies { // Import the BoM for the Firebase platform implementation(platform("com.google.firebase:firebase-bom:33.7.0")) // Add the dependencies for the Firebase Cloud Messaging and Analytics libraries // When using the BoM, you don't specify versions in Firebase library dependencies implementation("com.google.firebase:firebase-messaging") implementation("com.google.firebase:firebase-analytics") }
Dengan menggunakan Firebase Android BoM, aplikasi Anda akan selalu menggunakan versi library Android Firebase yang kompatibel.
(Alternatif) Tambahkan dependensi library Firebase tanpa menggunakan BoM
Jika memilih untuk tidak menggunakan Firebase BoM, Anda harus menentukan setiap versi library Firebase di baris dependensinya.
Perlu diperhatikan bahwa jika Anda menggunakan beberapa library Firebase di aplikasi, sebaiknya gunakan BoM untuk mengelola versi library, yang memastikan bahwa semua versi kompatibel.
dependencies { // Add the dependencies for the Firebase Cloud Messaging and Analytics libraries // When NOT using the BoM, you must specify versions in Firebase library dependencies implementation("com.google.firebase:firebase-messaging:24.1.0") implementation("com.google.firebase:firebase-analytics:22.1.2") }
Sinkronkan project Android Anda dengan file Gradle.
Membuat aplikasi klien berlangganan topik
Aplikasi klien dapat berlangganan topik yang ada atau membuat topik baru. Jika aplikasi klien berlangganan nama topik baru (nama yang belum ada untuk project Firebase Anda), topik baru dengan nama tersebut akan dibuat di FCM sehingga semua klien dapat berlangganan topik tersebut.
Untuk berlangganan topik, aplikasi klien akan memanggil Firebase Cloud Messaging
subscribeToTopic()
dengan nama topik FCM. Metode ini menampilkan Task
, yang dapat digunakan oleh pemroses penyelesaian untuk menentukan apakah langganan berhasil atau tidak:
Kotlin
Firebase.messaging.subscribeToTopic("weather") .addOnCompleteListener { task -> var msg = "Subscribed" if (!task.isSuccessful) { msg = "Subscribe failed" } Log.d(TAG, msg) Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show() }
Java
FirebaseMessaging.getInstance().subscribeToTopic("weather") .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { String msg = "Subscribed"; if (!task.isSuccessful()) { msg = "Subscribe failed"; } Log.d(TAG, msg); Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show(); } });
Untuk berhenti berlangganan, aplikasi klien akan memanggil Firebase Cloud Messaging unsubscribeFromTopic()
dengan nama topik.
Menerima dan menangani pesan topik
FCM mengirim pesan topik dengan cara yang sama seperti pesan downstream lainnya.
Untuk menerima pesan, gunakan layanan yang menyediakan
FirebaseMessagingService
.
Layanan Anda harus mengganti callback onMessageReceived
dan onDeletedMessages
.
Rentang waktu untuk menangani pesan mungkin kurang dari 20 detik, bergantung pada penundaan yang terjadi sebelum panggilan onMessageReceived
, termasuk penundaan OS, waktu aplikasi dimulai, thread utama yang diblokir oleh operasi lain, atau sebelumnya panggilan onMessageReceived
memerlukan waktu terlalu lama. Setelah itu, berbagai perilaku OS seperti penghentian proses Android atau batas eksekusi latar belakang Android O dapat mengganggu kemampuan Anda untuk menyelesaikan pekerjaan.
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 | Area notifikasi | onMessageReceived |
Notifikasi: area notifikasi Data: di bagian tambahan intent. |
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. }
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.
Mem-build permintaan kirim
Setelah membuat topik, baik dengan membuat instance aplikasi klien berlangganan topik di sisi klien maupun melalui API server, Anda dapat mengirim pesan ke topik tersebut. Jika ini adalah pertama kalinya Anda mem-build permintaan kirim untuk FCM, baca panduan lingkungan server dan FCM untuk mengetahui informasi penting tentang penyiapan dan latar belakang.
Dalam logika pengiriman Anda di backend, tentukan nama topik yang diinginkan seperti yang ditunjukkan di bawah:
Node.js
// The topic name can be optionally prefixed with "/topics/".
const topic = 'highScores';
const message = {
data: {
score: '850',
time: '2:45'
},
topic: topic
};
// Send a message to devices subscribed to the provided topic.
getMessaging().send(message)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
Java
// The topic name can be optionally prefixed with "/topics/".
String topic = "highScores";
// See documentation on defining a message payload.
Message message = Message.builder()
.putData("score", "850")
.putData("time", "2:45")
.setTopic(topic)
.build();
// Send a message to the devices subscribed to the provided topic.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
System.out.println("Successfully sent message: " + response);
Python
# The topic name can be optionally prefixed with "/topics/".
topic = 'highScores'
# See documentation on defining a message payload.
message = messaging.Message(
data={
'score': '850',
'time': '2:45',
},
topic=topic,
)
# Send a message to the devices subscribed to the provided topic.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)
Go
// The topic name can be optionally prefixed with "/topics/".
topic := "highScores"
// See documentation on defining a message payload.
message := &messaging.Message{
Data: map[string]string{
"score": "850",
"time": "2:45",
},
Topic: topic,
}
// Send a message to the devices subscribed to the provided topic.
response, err := client.Send(ctx, message)
if err != nil {
log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)
C#
// The topic name can be optionally prefixed with "/topics/".
var topic = "highScores";
// See documentation on defining a message payload.
var message = new Message()
{
Data = new Dictionary<string, string>()
{
{ "score", "850" },
{ "time", "2:45" },
},
Topic = topic,
};
// Send a message to the devices subscribed to the provided topic.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);
REST
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":{
"topic" : "foo-bar",
"notification" : {
"body" : "This is a Firebase Cloud Messaging Topic Message!",
"title" : "FCM Message"
}
}
}
Perintah cURL:
curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
"message": {
"topic" : "foo-bar",
"notification": {
"body": "This is a Firebase Cloud Messaging Topic Message!",
"title": "FCM Message"
}
}
}' https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Untuk mengirim pesan ke kombinasi topik,
tentukan kondisi, yang merupakan ekspresi boolean yang menentukan
topik target. Misalnya, kondisi berikut akan mengirim pesan ke perangkat yang
berlangganan TopicA
dan juga TopicB
atau TopicC
:
"'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"
FCM mengevaluasi terlebih dahulu setiap kondisi di dalam tanda kurung, lalu mengevaluasi ekspresi dari kiri ke kanan. Pada ekspresi di atas, pengguna yang hanya berlangganan satu topik apa pun tidak akan menerima pesan. Demikian pula, pengguna yang tidak berlangganan TopicA
tidak akan menerima pesan. Namun, pengguna dengan kombinasi berikut akan menerimanya:
TopicA
danTopicB
TopicA
danTopicC
Anda dapat menyertakan hingga lima topik dalam ekspresi kondisional.
Untuk mengirim ke sebuah kondisi:
Node.js
// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
const condition = '\'stock-GOOG\' in topics || \'industry-tech\' in topics';
// See documentation on defining a message payload.
const message = {
notification: {
title: '$FooCorp up 1.43% on the day',
body: '$FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.'
},
condition: condition
};
// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
getMessaging().send(message)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
Java
// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
String condition = "'stock-GOOG' in topics || 'industry-tech' in topics";
// See documentation on defining a message payload.
Message message = Message.builder()
.setNotification(Notification.builder()
.setTitle("$GOOG up 1.43% on the day")
.setBody("$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.")
.build())
.setCondition(condition)
.build();
// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
System.out.println("Successfully sent message: " + response);
Python
# Define a condition which will send to devices which are subscribed
# to either the Google stock or the tech industry topics.
condition = "'stock-GOOG' in topics || 'industry-tech' in topics"
# See documentation on defining a message payload.
message = messaging.Message(
notification=messaging.Notification(
title='$GOOG up 1.43% on the day',
body='$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.',
),
condition=condition,
)
# Send a message to devices subscribed to the combination of topics
# specified by the provided condition.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)
Go
// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
condition := "'stock-GOOG' in topics || 'industry-tech' in topics"
// See documentation on defining a message payload.
message := &messaging.Message{
Data: map[string]string{
"score": "850",
"time": "2:45",
},
Condition: condition,
}
// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
response, err := client.Send(ctx, message)
if err != nil {
log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)
C#
// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
var condition = "'stock-GOOG' in topics || 'industry-tech' in topics";
// See documentation on defining a message payload.
var message = new Message()
{
Notification = new Notification()
{
Title = "$GOOG up 1.43% on the day",
Body = "$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.",
},
Condition = condition,
};
// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);
REST
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":{
"condition": "'dogs' in topics || 'cats' in topics",
"notification" : {
"body" : "This is a Firebase Cloud Messaging Topic Message!",
"title" : "FCM Message",
}
}
}
Perintah cURL:
curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
"notification": {
"title": "FCM Message",
"body": "This is a Firebase Cloud Messaging Topic Message!",
},
"condition": "'dogs' in topics || 'cats' in topics"
}' https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Langkah berikutnya
- Anda dapat menggunakan server untuk membuat instance aplikasi klien berlangganan suatu topik dan melakukan tugas pengelolaan lainnya. Lihat Mengelola langganan topik di server