Pesan topik di Android

Berdasarkan model publikasi/langganan, pesan topik FCM dapat digunakan untuk mengirim pesan ke beberapa perangkat yang mengikuti topik tertentu. Anda cukup menulis pesan topik sesuai kebutuhan dan FCM akan secara andal menangani perutean serta pengiriman pesan ke perangkat yang tepat.

Misalnya, pengguna suatu aplikasi perkiraan pasang surut laut setempat dapat memilih untuk menerima topik "pemberitahuan arus pasang surut" dan menerima notifikasi kondisi laut yang optimal untuk menangkap ikan di area tertentu. Pengguna suatu aplikasi olahraga dapat berlangganan untuk menerima update terbaru secara otomatis terkait skor pertandingan langsung tim favoritnya.

Beberapa hal yang perlu diingat tentang topik:

  • Pesan topik paling cocok untuk konten seperti cuaca, atau informasi lainnya yang tersedia untuk umum.
  • Pesan topik dioptimalkan untuk throughput, bukan latensi. Untuk mengirim dengan cepat dan aman ke satu perangkat atau sekelompok kecil perangkat, targetkan pesan ke token pendaftaran, bukan topik.
  • Jika Anda perlu mengirimkan pesan ke beberapa perangkat per pengguna, sebaiknya gunakan pesan grup perangkat untuk kasus penggunaan tersebut.
  • Pesan topik mendukung langganan tak terbatas untuk setiap topik. Namun, FCM memberlakukan batasan untuk hal-hal berikut:
    • Satu instance aplikasi hanya dapat berlangganan maksimal 2.000 topik.
    • Jika Anda menggunakan impor batch untuk membuat instance aplikasi berlangganan topik, setiap permintaan dibatasi hingga 1.000 instance aplikasi.
    • Frekuensi langganan baru dibatasi kapasitasnya per project. Jika Anda mengirim terlalu banyak permintaan langganan dalam waktu singkat, server FCM akan memberikan respons 429 RESOURCE_EXHAUSTED ("kuota terlampaui"). Coba lagi dengan backoff eksponensial.

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.

Mengelola langganan topik di server

Firebase Admin SDK dapat Anda gunakan untuk menjalankan tugas dasar pengelolaan topik dari sisi server. Dengan token pendaftaran instance, Anda dapat membuat instance aplikasi klien berlangganan dan berhenti berlangganan secara massal menggunakan logika server.

Anda dapat membuat instance aplikasi klien berlangganan topik yang ada, atau Anda dapat membuat topik baru. Jika Anda menggunakan API untuk membuat aplikasi klien berlangganan topik baru (topik yang belum ada untuk project Firebase Anda), topik baru dengan nama tersebut akan dibuat di FCM sehingga semua klien dapat berlangganan topik tersebut.

Anda dapat meneruskan daftar token pendaftaran ini ke metode langganan Firebase Admin SDK agar perangkat terkait ikut berlangganan topik:

Node.js

// These registration tokens come from the client FCM SDKs.
const registrationTokens = [
  'YOUR_REGISTRATION_TOKEN_1',
  // ...
  'YOUR_REGISTRATION_TOKEN_n'
];

// Subscribe the devices corresponding to the registration tokens to the
// topic.
getMessaging().subscribeToTopic(registrationTokens, topic)
  .then((response) => {
    // See the MessagingTopicManagementResponse reference documentation
    // for the contents of response.
    console.log('Successfully subscribed to topic:', response);
  })
  .catch((error) => {
    console.log('Error subscribing to topic:', error);
  });

Java

// These registration tokens come from the client FCM SDKs.
List<String> registrationTokens = Arrays.asList(
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n"
);

// Subscribe the devices corresponding to the registration tokens to the
// topic.
TopicManagementResponse response = FirebaseMessaging.getInstance().subscribeToTopic(
    registrationTokens, topic);
// See the TopicManagementResponse reference documentation
// for the contents of response.
System.out.println(response.getSuccessCount() + " tokens were subscribed successfully");

Python

# These registration tokens come from the client FCM SDKs.
registration_tokens = [
    'YOUR_REGISTRATION_TOKEN_1',
    # ...
    'YOUR_REGISTRATION_TOKEN_n',
]

# Subscribe the devices corresponding to the registration tokens to the
# topic.
response = messaging.subscribe_to_topic(registration_tokens, topic)
# See the TopicManagementResponse reference documentation
# for the contents of response.
print(response.success_count, 'tokens were subscribed successfully')

Go

// These registration tokens come from the client FCM SDKs.
registrationTokens := []string{
	"YOUR_REGISTRATION_TOKEN_1",
	// ...
	"YOUR_REGISTRATION_TOKEN_n",
}

// Subscribe the devices corresponding to the registration tokens to the
// topic.
response, err := client.SubscribeToTopic(ctx, registrationTokens, topic)
if err != nil {
	log.Fatalln(err)
}
// See the TopicManagementResponse reference documentation
// for the contents of response.
fmt.Println(response.SuccessCount, "tokens were subscribed successfully")

C#

// These registration tokens come from the client FCM SDKs.
var registrationTokens = new List<string>()
{
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n",
};

// Subscribe the devices corresponding to the registration tokens to the
// topic
var response = await FirebaseMessaging.DefaultInstance.SubscribeToTopicAsync(
    registrationTokens, topic);
// See the TopicManagementResponse reference documentation
// for the contents of response.
Console.WriteLine($"{response.SuccessCount} tokens were subscribed successfully");

Dengan Admin FCM API, Anda juga dapat menghentikan langganan perangkat dari sebuah topik dengan meneruskan token pendaftaran ke metode yang sesuai:

Node.js

// These registration tokens come from the client FCM SDKs.
const registrationTokens = [
  'YOUR_REGISTRATION_TOKEN_1',
  // ...
  'YOUR_REGISTRATION_TOKEN_n'
];

// Unsubscribe the devices corresponding to the registration tokens from
// the topic.
getMessaging().unsubscribeFromTopic(registrationTokens, topic)
  .then((response) => {
    // See the MessagingTopicManagementResponse reference documentation
    // for the contents of response.
    console.log('Successfully unsubscribed from topic:', response);
  })
  .catch((error) => {
    console.log('Error unsubscribing from topic:', error);
  });

Java

// These registration tokens come from the client FCM SDKs.
List<String> registrationTokens = Arrays.asList(
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n"
);

// Unsubscribe the devices corresponding to the registration tokens from
// the topic.
TopicManagementResponse response = FirebaseMessaging.getInstance().unsubscribeFromTopic(
    registrationTokens, topic);
// See the TopicManagementResponse reference documentation
// for the contents of response.
System.out.println(response.getSuccessCount() + " tokens were unsubscribed successfully");

Python

# These registration tokens come from the client FCM SDKs.
registration_tokens = [
    'YOUR_REGISTRATION_TOKEN_1',
    # ...
    'YOUR_REGISTRATION_TOKEN_n',
]

# Unubscribe the devices corresponding to the registration tokens from the
# topic.
response = messaging.unsubscribe_from_topic(registration_tokens, topic)
# See the TopicManagementResponse reference documentation
# for the contents of response.
print(response.success_count, 'tokens were unsubscribed successfully')

Go

// These registration tokens come from the client FCM SDKs.
registrationTokens := []string{
	"YOUR_REGISTRATION_TOKEN_1",
	// ...
	"YOUR_REGISTRATION_TOKEN_n",
}

// Unsubscribe the devices corresponding to the registration tokens from
// the topic.
response, err := client.UnsubscribeFromTopic(ctx, registrationTokens, topic)
if err != nil {
	log.Fatalln(err)
}
// See the TopicManagementResponse reference documentation
// for the contents of response.
fmt.Println(response.SuccessCount, "tokens were unsubscribed successfully")

C#

// These registration tokens come from the client FCM SDKs.
var registrationTokens = new List<string>()
{
    "YOUR_REGISTRATION_TOKEN_1",
    // ...
    "YOUR_REGISTRATION_TOKEN_n",
};

// Unsubscribe the devices corresponding to the registration tokens from the
// topic
var response = await FirebaseMessaging.DefaultInstance.UnsubscribeFromTopicAsync(
    registrationTokens, topic);
// See the TopicManagementResponse reference documentation
// for the contents of response.
Console.WriteLine($"{response.SuccessCount} tokens were unsubscribed successfully");

Metode subscribeToTopic() dan unsubscribeFromTopic() menghasilkan objek yang berisi respons dari FCM. Jenis nilai yang ditampilkan memiliki format yang sama berapa pun jumlah token pendaftaran yang ditentukan dalam permintaan.

Jika terjadi error (kegagalan autentikasi, token atau topik tidak valid, dll.), metode ini akan mengakibatkan error. Untuk mengetahui daftar lengkap kode error, termasuk deskripsi dan langkah penyelesaian, baca bagian Error Admin FCM API.

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 baki sistem 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 baki sistem 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: baki sistem
Data: di bagian tambahan intent.
Untuk mendapatkan informasi lebih lanjut tentang jenis pesan, lihat Notifikasi dan pesan data.

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 baki sistem. 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 baki sistem 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 dan TopicB
  • TopicA dan TopicC

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