网页/JavaScript 上的主题消息传递

在发布/订阅模式下,利用 FCM 主题消息传递功能,可以将消息发送至已经选择加入特定主题的多台设备。您根据需要撰写主题消息,FCM 将处理消息路由并将消息可靠地传送至正确的设备。

例如,某个本地天气预报应用的用户可选择加入“恶劣天气警报”主题,并接收威胁特定区域的风暴的通知。体育应用的用户可以订阅他们心仪球队的实时比分自动更新。

关于主题,请注意以下事项:

  • 主题消息传递不限制每个应用拥有的主题和订阅数。
  • 主题消息传递最适合传递新闻、天气或其他可通过公开途径获得的信息等内容。
  • 主题消息针对吞吐量(而非延迟)进行了优化。要将消息快速安全地传送到单台设备或小规模设备组,应将消息定位至注册令牌,而非主题。
  • 如果您需要向一位用户的多台设备发送消息,可考虑针对这些使用情形进行设备组消息传递

为客户端应用订阅主题

有了注册令牌和主题名称,您就可以使用 Google Instance ID server API 向相应主题添加相应令牌。请在以下端点调用 Instance ID API,并提供应用实例的注册令牌和主题名称:

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

例如,要为某个应用实例订阅名为“movies”的主题,请从您的服务器将以下 POST 请求发送到端点,然后在授权标头中添加如下所示的服务器 API 密钥:

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

鉴于服务器密钥的敏感性,切勿从客户端发送这种类型的请求。

请求成功则返回 HTTP 200 OK。如需详细了解错误响应及如何发送批量请求,请参阅为应用实例创建关系映射

接收和处理主题消息

FCM 传送主题消息的方式与处理其他下行消息的方式相同。如何处理客户端上的消息,取决于网页的前台/后台状态以及本节介绍的其他因素。

消息的行为取决于相应页面的状态:页面位于前台(获得焦点)、位于后台、隐藏在其他标签页后,还是完全关闭。无论哪种情况,页面都必须处理 onMessage 回调函数;但当页面位于后台时,您可能还需要处理 setBackgroundMessageHandler 或进行配置以显示通知,让用户能够将您的网页应用放到前台。

应用状态 通知 数据 两者
前台 onMessage onMessage onMessage
后台 (Service Worker) SDK 显示的通知 setBackgroundMessageHandler SDK 显示的通知

在网页应用位于前台时处理消息

为接收 onMessage 事件,您的应用必须在 firebase-messaging-sw.js 中定义 Firebase 消息传递 Service Worker。或者,您也可以使用 useServiceWorker 指定一个现有的 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/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();

当您的应用位于前台时(用户当前正在查看您的网页),您可以直接在页面中接收数据和通知有效负载。

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

在网页应用位于后台时处理消息

当应用位于后台时,收到的所有消息都会导致在浏览器中显示通知。您可以在从应用服务器发送请求时指定用于此通知的选项(如标题或点击操作),也可以在客户端中使用 Service Worker 进行指定。

在发送请求中设置通知选项

对于从应用服务器发送的通知消息,FCM JavaScript API 支持 click_action 键。通常情况下,此键会被设置在网页应用的某一页面中,以便在用户点击通知时将应用带到前台。

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"

}

由于数据消息不支持 click_action,因此我们建议您在所有数据消息中添加通知有效负载。或者,您也可以使用 Service Worker 处理通知。

如需详细了解通知消息与数据消息之间的区别,请参阅消息类型

在 Service Worker 中设置通知选项

不管是通知消息还是数据消息,您都可以在 Service Worker 中设置通知选项。首先,在 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/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();

要设置选项,请调用 firebase-messaging-sw.js 中的 setBackgroundMessageHandler。在本示例中,我们设置了针对标题、正文、图标和点击操作的选项。

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

构建发送请求

从服务器端向 Firebase 云消息传递主题发送消息,与将消息发送到单台设备或用户组非常相似。应用服务器会将 to 键设置为诸如 /topics/yourTopic 的值。开发者可以选择符合以下正则表达式的任何主题名称:"/topics/[a-zA-Z0-9-_.~%]+"

主题 HTTP POST 请求

发送至一个主题:

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

主题 HTTP 响应

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

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

主题 XMPP 消息

发送至一个主题:

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

主题 XMPP 响应

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

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

后续步骤

发送以下问题的反馈:

此网页
需要帮助?请访问我们的支持页面