Topic Messaging on Web/JavaScript

Based on the publish/subscribe model, FCM topic messaging allows you to send a message to multiple devices that have opted in to a particular topic. You compose topic messages as needed, and FCM handles routing and delivering the message reliably to the right devices.

For example, users of a local weather forecasting app could opt in to a "severe weather alerts" topic and receive notifications of storms threatening specified areas. Users of a sports app could subscribe to automatic updates in live game scores for their favorite teams.

Some things to keep in mind about topics:

  • Topic messaging supports unlimited topics and subscriptions for each app.
  • Topic messaging is best suited for content such as news, weather, or other publicly available information.
  • Topic messages are optimized for throughput rather than latency. For fast, secure delivery to single devices or small groups of devices, target messages to registration tokens, not topics.
  • If you need to send messages to multiple devices per user, consider device group messaging for those use cases.

Subscribe the client app to a topic

Given a registration token and a topic name, you can add the token to the topic using the Google Instance ID server API. Call the Instance ID API at this endpoint, providing the app instance's registration token and the topic name:

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

To subscribe an app instance to a topic named "movies," for example, send the following POST request from your server to the endpoint, adding your server API key in the authorizaton header as shown:

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

Do not ever send this type of request from the client, because of the sensitivity of the server key.

A successful request returns HTTP 200 OK. For more information about error responses and about how to send batch requests, see Create relationship maps for app instances

Receive and handle topic messages

FCM delivers topic messages in the same way as other downstream messages. How to handle messages on the client depends on the foreground/background state of the web page and other factors described in this section.

The behavior of messages differs depending on whether the page is in the foreground (has focus), or in the background, hidden behind other tabs, or completely closed. In all cases the page must handle the onMessage callback, but in background cases you'll also need to configure the display notification to allow the user to bring your web app into the foreground.

App state Notification Data Both
Foreground onMessage onMessage onMessage
Background (service worker) Display notification Display notification with click_action link Display notification with click_action link

Handle messages when your web app is in the foreground

In order to receive the onMessage event, your app must define the Firebase messaging service worker in firebase-messaging-sw.js. Alternatively, you can specify an existing service worker with 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/3.9.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.9.0/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();

When your app is in the foreground (the user is currently viewing your web page), you can receive data and notification payloads directly in the page.

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

Handle messages when your web app is in the background

All messages received while the app is in the background trigger a display notification in the browser. You can specify options for this notification, such as title or click action, either in the send request from your app server, or using service worker logic on the client.

Setting notification options in the send request

For notification messages sent from the app server, the FCM JavaScript API supports the click_action key. Typically this is set to a page in your web app, so that when a user clicks on the notification, your app is brought to the foreground.

https://fcm.googleapis.com/fcm/send
Content-Type: application/json
Authorization: key=AIzaSyC...akjgSX0e4

{ "notification": {
    "title": "Background Message Title",
    "body": "Background message body",
    "click_action" : "https://dummypage.com"
  },

  "to" : 

}

Because data messages don't support click_action, you are recommended to add a notification payload to all data messages. Alternatively, you can handle notifications using the service worker.

For an explanation of the difference between notification and data messages, see Message types.

Setting notification options in the service worker

For both notification messages and data messages, you can set notification options in the service worker. First, initialize your app in the service worker:

// 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/3.9.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.9.0/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();

To set options, call setBackgroundMessageHandler in firebase-messaging-sw.js. In this example, we set options for title, body, icon, and click action.

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

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

Build send requests

From the server side, sending messages to a Firebase Cloud Messaging topic is very similar to sending messages to an individual device or to a user group. The app server sets the to key with a value like /topics/yourTopic. Developers can choose any topic name that matches the regular expression: "/topics/[a-zA-Z0-9-_.~%]+".

Topic HTTP POST request

Send to a single topic:

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
{
  "to" : /topics/foo-bar",
  "priority" : "high",
  "notification" : {
    "body" : "This is a Firebase Cloud Messaging Topic Message!",
    "title" : "FCM Message",
  }
}

Topic HTTP response

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

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

Topic XMPP message

Send to a single topic:

<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>

Topic XMPP response

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

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

Next steps

Send feedback about...

Need help? Visit our support page.