Buka konsol

Mengirim pesan ke beberapa perangkat

Firebase Cloud Messaging menyediakan 2 cara untuk menargetkan pesan ke beberapa perangkat:

  • Pengiriman pesan topik dapat digunakan untuk mengirim pesan ke beberapa perangkat yang mengikuti topik tertentu.
  • Dengan messaging grup perangkat, Anda dapat mengirim pesan ke beberapa perangkat yang merupakan bagian dari grup yang Anda tetapkan.

Tutorial ini berfokus pada pengiriman pesan topik dari server aplikasi Anda menggunakan protokol HTTP atau XMPP untuk FCM, serta menerima dan menanganinya dalam aplikasi web. Kita akan membahas penanganan pesan untuk aplikasi yang dijalankan di background dan foreground.

Menyiapkan SDK

Bagian ini membahas langkah-langkah yang mungkin sudah diselesaikan jika Anda telah menyiapkan aplikasi klien JavaScript untuk FCM, atau telah menyelesaikan langkah-langkah untuk menerima pesan.

Menambahkan Firebase ke project JavaScript

Jika belum melakukannya, tambahkan Firebase ke project JavaScript Anda.

Mengonfigurasi browser untuk menerima pesan

Anda harus menambahkan manifes aplikasi web yang menentukan gcm_sender_id, nilai hard code yang menunjukkan bahwa FCM diizinkan untuk mengirim pesan ke aplikasi ini. Jika aplikasi telah memiliki file konfigurasi manifest.json, pastikan Anda menambahkan ID pengirim browser sama persis seperti yang terlihat (jangan ubah nilainya):

{
  "gcm_sender_id": "103953800507"
}

Mengambil objek messaging

// Retrieve Firebase Messaging object.
const messaging = firebase.messaging();

Meminta izin untuk menerima notification

Metode messaging.requestPermission() menampilkan dialog persetujuan untuk memberikan wewenang kepada pengguna untuk mengizinkan aplikasi Anda menerima notifikasi di browser. Jika izin ditolak, permintaan token pendaftaran FCM akan mengalami error.

messaging.requestPermission().then(function() {
  console.log('Notification permission granted.');
  // TODO(developer): Retrieve an Instance ID token for use with FCM.
  // ...
}).catch(function(err) {
  console.log('Unable to get permission to notify.', err);
});

Mengakses token pendaftaran

Bagian ini menjelaskan cara pengambilan token pendaftaran untuk instance aplikasi, serta cara memantau peristiwa refresh pada token. Karena token bisa diputar setelah startup awal, Anda harus memantau peristiwa refresh pada token dan selalu mengambil token pendaftaran terbaru.

Token pendaftaran dapat berubah jika:

  • Aplikasi web menghapus token pendaftaran.
  • Pengguna membersihkan data browser. Jika ini terjadi, panggil getToken untuk mengambil token baru.

Mengambil token pendaftaran saat ini

Jika Anda perlu mengambil token saat ini, panggil getToken. Jika izin tidak diberikan, metode ini menampilkan null. Jika izin diberikan, metode tersebut akan menampilkan token atau menolak promise karena terjadi error.

Layanan pengiriman pesan membutuhkan file firebase-messaging-sw.js. Kecuali Anda sudah memiliki file firebase-messaging-sw.js, buat file kosong dengan nama tersebut, lalu letakkan di root domain Anda sebelum mengambil token. Anda dapat menambahkan konten yang bermakna ke file ini nanti dalam proses penyiapan klien.

Untuk mengambil token saat ini:

// Get Instance ID token. Initially this makes a network call, once retrieved
// subsequent calls to getToken will return from cache.
messaging.getToken().then(function(currentToken) {
  if (currentToken) {
    sendTokenToServer(currentToken);
    updateUIForPushEnabled(currentToken);
  } else {
    // Show permission request.
    console.log('No Instance ID token available. Request permission to generate one.');
    // Show permission UI.
    updateUIForPushPermissionRequired();
    setTokenSentToServer(false);
  }
}).catch(function(err) {
  console.log('An error occurred while retrieving token. ', err);
  showToken('Error retrieving Instance ID token. ', err);
  setTokenSentToServer(false);
});

Memantau refresh pada token

Callback onTokenRefresh aktif setiap kali token baru dibuat, sehingga memanggil getToken sesuai konteksnya akan memastikan bahwa Anda mengakses token pendaftaran yang tersedia saat ini.

// Callback fired if Instance ID token is updated.
messaging.onTokenRefresh(function() {
  messaging.getToken().then(function(refreshedToken) {
    console.log('Token refreshed.');
    // Indicate that the new Instance ID token has not yet been sent to the
    // app server.
    setTokenSentToServer(false);
    // Send Instance ID token to app server.
    sendTokenToServer(refreshedToken);
    // ...
  }).catch(function(err) {
    console.log('Unable to retrieve refreshed token ', err);
    showToken('Unable to retrieve refreshed token ', err);
  });
});

Setelah token didapatkan, kirim token ke server aplikasi dan simpan menggunakan metode yang dipilih. Anda dapat menggunakan API server ID Instance untuk mendapatkan informasi tentang langganan

Membuat aplikasi klien berlangganan topik

Dengan token pendaftaran dan nama topik, Anda dapat menambahkan token ke topik menggunakan API server Google Instance ID. Panggil Instance ID API di endpoint ini dengan memberikan token pendaftaran dan nama topik instance aplikasi:

 https://iid.googleapis.com/iid/v1/<REGISTRATION_TOKEN>/rel/topics/<TOPIC_NAME>

Misalnya, untuk membuat instance aplikasi berlangganan ke topik berjudul "movies", kirim permintaan POST berikut ke endpoint dan tambahkan kunci API server di header autorisasi seperti berikut:

https://iid.googleapis.com/iid/v1/nKctODamlM4:CKrh_PC8kIb7O...clJONHoA/rel/topics/movies
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

Jangan pernah mengirimkan permintaan jenis ini dari klien karena kepekaan kunci server.

Permintaan yang berhasil akan menampilkan HTTP 200 OK. Untuk mengetahui informasi lebih lanjut tentang respons terhadap error dan cara mengirim sekumpulan permintaan, baca bagian Membuat peta hubungan untuk instance aplikasi

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

Node.js

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

// Subscribe the devices corresponding to the registration tokens to the
// topic.
admin.messaging().subscribeToTopic(registrationTokens, topic)
  .then(function(response) {
    // See the MessagingTopicManagementResponse reference documentation
    // for the contents of response.
    console.log('Successfully subscribed to topic:', response);
  })
  .catch(function(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")

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.
var registrationTokens = [
  'YOUR_REGISTRATION_TOKEN_1',
  // ...
  'YOUR_REGISTRATION_TOKEN_n'
];

// Unsubscribe the devices corresponding to the registration tokens from
// the topic.
admin.messaging().unsubscribeFromTopic(registrationTokens, topic)
  .then(function(response) {
    // See the MessagingTopicManagementResponse reference documentation
    // for the contents of response.
    console.log('Successfully unsubscribed from topic:', response);
  })
  .catch(function(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")

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

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-langkah penyelesaiannya, baca bagian Error pada Admin FCM API.

Menerima dan menangani pesan topik

Perilaku pesan berbeda-beda, tergantung pada apakah halaman berada di foreground (memiliki fokus), di background, tersembunyi di balik tab lain, atau tertutup sepenuhnya. Dalam semua kasus, halaman harus menangani callback onMessage. Namun saat halaman berada di background, Anda mungkin juga perlu menangani setBackgroundMessageHandler atau mengonfigurasi notifikasi tampilan untuk mengizinkan pengguna memindahkan aplikasi web Anda ke foreground.

Status Aplikasi Notification Data Keduanya
Latar depan onMessage onMessage onMessage
Latar belakang (pekerja layanan) Notifikasi yang ditampilkan oleh SDK setBackgroundMessageHandler Notifikasi yang ditampilkan oleh SDK

Menangani pesan ketika aplikasi web berada di latar depan

Untuk menerima peristiwa onMessage, aplikasi Anda harus menentukan pekerja layanan messaging Firebase dalam firebase-messaging-sw.js. Atau, Anda dapat menentukan pekerja layanan yang ada dengan useServiceWorker.

// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js');

// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
  'messagingSenderId': 'YOUR-SENDER-ID'
});

// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();

Ketika aplikasi Anda ada di latar depan (pengguna melihat halaman web), Anda dapat menerima payload data dan notification secara langsung di halaman.

// Handle incoming messages. Called when:
// - a message is received while the app has focus
// - the user clicks on an app notification created by a service worker
//   `messaging.setBackgroundMessageHandler` handler.
messaging.onMessage(function(payload) {
  console.log('Message received. ', payload);
  // ...
});

Menangani pesan saat aplikasi web ada di latar belakang

Semua pesan yang diterima saat aplikasi ada di latar belakang memicu notification tampilan di browser. Anda dapat menentukan pilihan untuk notification ini, seperti judul atau tindakan klik, baik dalam permintaan pengiriman dari server aplikasi Anda, atau menggunakan logika pekerja layanan pada klien.

Mengatur pilihan notification dalam permintaan pengiriman

Untuk pesan notifikasi yang dikirim dari server aplikasi, FCM JavaScript API mendukung kunci fcm_options.link. Biasanya hal ini diatur ke halaman dalam aplikasi web Anda:

https://fcm.googleapis.com//v1/projects/<YOUR-PROJECT-ID>/messages:send
Content-Type: application/json
Authorization: bearer <YOUR-ACCESS-TOKEN>

{
  "message": {
    "topic": "matchday"
    "notification": {
      "title": "Background Message Title",
      "body": "Background message body"
    },
    "webpush": {
      "fcm_options": {
        "link": "https://dummypage.com"
      }
    }
  }
}

Jika nilai link menunjuk ke halaman yang sudah terbuka di tab browser, klik pada notifikasi akan membawa tab tersebut ke foreground. Jika halaman belum terbuka, klik pada notifikasi akan membuka halaman di tab baru.

Karena pesan data tidak mendukung fcm_options.link, sebaiknya Anda menambahkan payload notifikasi ke semua pesan data. Atau Anda dapat menangani notification menggunakan pekerja layanan.

Penjelasan mengenai perbedaan antara pesan notifikasi dan pesan data dapat dibaca di bagian Jenis pesan.

Menetapkan opsi notifikasi dalam pekerja layanan

Untuk pesan notification dan pesan data, Anda dapat menyetel pilihan notification dalam pekerja layanan. Pertama, inisialisasikan aplikasi Anda dalam pekerja layanan:

// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js');

// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
  'messagingSenderId': 'YOUR-SENDER-ID'
});

// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();

Untuk mengatur pilihan, panggil setBackgroundMessageHandler di firebase-messaging-sw.js. Dalam contoh ini, kita menetapkan pilihan untuk judul, isi, ikon, dan tindakan klik.

messaging.setBackgroundMessageHandler(function(payload) {
  console.log('[firebase-messaging-sw.js] Received background message ', payload);
  // Customize notification here
  var notificationTitle = 'Background Message Title';
  var notificationOptions = {
    body: 'Background Message body.',
    icon: '/firebase-logo.png'
  };

  return self.registration.showNotification(notificationTitle,
    notificationOptions);
});

Membuat permintaan kirim

Dari sisi server, mengirim pesan ke topik Firebase Cloud Messaging sangat mirip dengan mengirim pesan ke setiap perangkat atau ke grup pengguna. Server aplikasi menetapkan kunci to dengan nilai seperti /topics/yourTopic. Developer bisa memilih nama topik apa pun yang cocok dengan ekspresi reguler: "/topics/[a-zA-Z0-9-_.~%]+".

Permintaan HTTP POST topik

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",
      }
   }
}

Mengirim dengan 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!",
  },
  "topic" : "foo-bar"
}' "https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1"

Respons HTTP topik

{
    "name": "projects/myproject-b5ae1/messages/5735743068807585451"
}

Pesan XMPP topik

Mengirim ke 1 topik:

<message id="">
  <gcm xmlns="google:mobile:data">
{
  "to" : /topics/foo-bar",
  "priority" : "high",
  "notification" : {
    "body" : "This is a Firebase Cloud Messaging Topic Message!",
    "title" : "FCM Message",
  }
}
  </gcm>
</message>

Respons XMPP topik

//Success example:
{
  "message_id": "1023456"
}

//failure example:
{
  "error": "TopicsMessageRateExceeded"
}