Send Messages to Multiple Devices

Firebase Cloud Messaging provides these two ways to target a message to multiple devices:

  • Topic messaging, which allows you to send a message to multiple devices that have opted in to a particular topic.
  • Device group messaging, which allows you to send a message to multiple devices that belong to a group you define.

This tutorial focuses on sending topic messages from your app server using the HTTP or XMPP protocols for FCM, and receiving and handling them in a web app. We'll cover message handling for both backgrounded and foregrounded apps.

Set up the SDK

This section may cover steps you already completed if you have set up a JavaScript client app for FCM or worked through the steps to receive messages.

Add Firebase to your JavaScript project

If you haven't already, add Firebase to your JavaScript project.

Configure the browser to receive messages

You'll need to add a web app manifest that specifies the gcm_sender_id, a hard-coded value indicating that FCM is authorized to send messages to this app. If your app already has a manifest.json configuration file, make sure to add the browser sender ID exactly as shown (do not change the value):

{
  "gcm_sender_id": "103953800507"
}

Retrieve a messaging object

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

Request permission to receive notifications

The method messaging.requestPermission() displays a consent dialog to let users grant your app permission to receive notifications in the browser. If permission is denied, FCM registration token requests result in an 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);
});

Access the registration token

This section describes how to retrieve the registration token for an app instance, and how to monitor token refresh events. Because the token could be rotated after initial startup, you should monitor token refresh and always retrieve the latest updated registration token.

The registration token may change when:

  • The web app deletes the registration token.
  • The user clears browser data. In this case, call getToken to retrieve the new token.

Retrieve the current registration token

When you need to retrieve the current token, call getToken. This method returns null when permission has not been granted. Otherwise, it returns a token or rejects the promise due to an error.

  // 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);
  });
}

Monitor token refresh

The onTokenRefreshcallback fires whenever a new token is generated, so calling getToken in its context ensures that you are accessing a current, available registration token.

// 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);
  });
});

After you've obtained the token, send it to your app server and store it using your preferred method. You can use the Instance ID server API to get information about subscriptions

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

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 may also need to handle setBackgroundMessageHandler or 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) Notification displayed by SDK setBackgroundMessageHandler Notification displayed by SDK

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" : "/topics/matchday"

}

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

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

Send with 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"

Topic HTTP response

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

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

Şunun hakkında geri bildirim gönderin...

Yardım mı gerekiyor? Destek sayfamızı ziyaret edin.