要发送消息,应用服务器需发出 POST 请求。例如:
https://fcm.googleapis.com/fcm/send
某个消息请求由两部分组成:HTTP 标头和 HTTP 正文。
HTTP 标头必须包含以下标头:
Authorization
: key=YOUR_SERVER_KEY
Content-Type
:
application/json
(JSON 格式);
application/x-www-form-urlencoded;charset=UTF-8
(纯文本格式)。 如果省略
Content-Type
,即视为纯文本格式。
Content-Type:application/json Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", "data" : {HTTP 正文内容取决于您使用的是 JSON 还是纯文本。有关 JSON 或纯文本消息中可能包含的所有参数列表,请参阅服务器参考。
通俗的来讲就是调用谷歌推送地址,将相关参数传进去。
https://fcm.googleapis.com/fcm/send可以用to单个推送,也可以用 registration_ids批量发送,但是做多1000个token。 * FileName: TestFireBase.java * @Description: TODO * All rights Reserved, Designed By ifeng * @author: hlf * @version V1.0 * Createdate: 2016年10月19日 下午2:01:34 * Modification History: * Date Author Version Discription * ----------------------------------------------------------------------------------- * 2016年10月19日 hlf 1.0 1.0 package com.ifeng; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import com.alibaba.fastjson.JSONObject; import com.sun.org.apache.bcel.internal.generic.FMUL; * @ClassName: TestFireBase.java * @Description: TODO * @author hlf * @version V1.0 * @Date 2016年10月19日 下午2:01:34 public class TestFireBase { public final static String AUTH_KEY_FCM= "";//app服务密钥 public final static String API_URL_FCM = "https://fcm.googleapis.com/fcm/send";//谷歌推送地址 public static void main(String[] args) { pushFCMNotification(); public static void pushFCMNotification() { try { URL url = new URL(API_URL_FCM); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setUseCaches(false); conn.setDoInput(true); conn.setDoOutput(true); conn.setRequestMethod("POST"); conn.setRequestProperty("Authorization","key="+AUTH_KEY_FCM); conn.setRequestProperty("Content-Type","application/json");//不设置默认发送文本格式。设置就是json JSONObject json = new JSONObject();json.put("to","此处填写您的客户端app token");//推送到哪台客户端机器,方法一推一个token, //方法二,批量推送 ,最多1000个token ,此处的tokens是一个token JSONArray数组json.put("registration_ids", tokens); JSONObject info = new JSONObject(); info.put("title","Notification Tilte"); info.put("body", "Hello Test notification"); info.put("icon", "myicon"); json.put("notification", info);//json 还可以put其他你想要的参数 OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream()); wr.write(json.toString()); wr.flush(); BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line = null; while ((line = reader.readLine())!= null) { System.out.println(line); wr.close(); reader.close(); } catch (Exception e) { e.printStackTrace();
Firebase Cloud Messaging服务器端包含两个组件:
完整的 FCM 实现既需要客户端实现,也需要服务器实现。有关如何实现客户端应用的详细信息,请参阅适合您的平台(iOS、Android 或 Chrome)的客户端指南。
在您可以编写使用 Firebase Cloud Messaging的客户端应用之前,您必须拥有一个满足以下标准的应用服务器:
您需要决定使用哪个FCM连接服务器协议来让您的应用服务器与FCM连接服务器交互。请注意,如果您想从客户端应用使用上游消息传递,则必须使用 XMPP。有关更多详细讨论,请参阅选择FCM连接服务器协议。
目前,FCM提供两种连接服务器协议:HTTP 和 XMPP。您的应用服务器可以单独或以串联方式使用这些协议。XMPP 消息传递与 HTTP 消息传递具有以下差异:
本部分将介绍FCM HTTP 连接服务器。连接服务器是一种由 Google 提供的服务器,它可以从应用服务器接收消息并将其发送至设备。
有关所有消息参数以及可为其提供支持的连接服务器的列表,请参阅服务器参考。
要发送消息,应用服务器需发出 POST 请求。例如:
https://fcm.googleapis.com/fcm/send
某个消息请求由两部分组成:HTTP 标头和 HTTP 正文。
HTTP 标头必须包含以下标头:
Authorization
: key=YOUR_SERVER_KEYContent-Type
: application/json
(JSON 格式);application/x-www-form-urlencoded;charset=UTF-8
(纯文本格式)。 如果省略 Content-Type
,即视为纯文本格式。Content-Type:application/json Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", "data" : {HTTP 正文内容取决于您使用的是 JSON 还是纯文本。有关 JSON 或纯文本消息中可能包含的所有参数列表,请参阅服务器参考。
检查服务器密钥的有效性
如果您在发送消息时收到身份验证错误,请检查服务器密钥的有效性。例如,在 Android 上运行以下命令:
# api_key=YOUR_SERVER_KEY # curl --header "Authorization: key=$api_key" \ --header Content-Type:"application/json" \ https://fcm.googleapis.com/fcm/send \ -d "{\"registration_ids\":[\"ABC\"]}"如果您收到 401 HTTP 状态代码,则表示您的服务器密钥无效。或者,您应看到类似于如下内容:
{"multicast_id":6782339717028231855,"success":0,"failure":1, "canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}如果您想要确认注册令牌的有效性,可以将"ABC"替换为注册标记。
本部分介绍如何格式化 JSON 和纯文本请求。有关请求中可包含字段的完整列表,请参阅服务器参考。
发送至同步
以下是使用 JSON 格式的最小可能请求(不带有任何参数且仅有一个接收者的消息):
{ "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..." }以下是使用纯文本格式的同一个示例:
registration_id=42
以下是一个通知消息:
以下是带有数据负载的消息:
以下是设置所有可选字段的消息:
以下是使用纯文本格式的同一条消息:
尝试发送消息时可能有两种结果:
当 JSON 请求成功后(HTTP 状态代码 200),返回的 JSON 对象包含 下游 HTTP 消息响应正文 。记录所有消息的消息 ID 值,方便您通过 Google 支持或 GCM 诊断排除消息故障。
如果
failure
和
canonical_ids
的值是 0,则无需分析响应的其余部分。否则,我们建议您遍历结果字段,并对该列表中的每个对象执行以下操作:
message_id
,则检查
registration_id
:
registration_id
,则将服务器数据库中的原始 ID 替换为新值(规范 ID)。请注意,原始 ID 并非结果的一部分,因此您需要从请求中传送的
registration_ids
列表中获取该 ID(使用相同索引)。
error
的值:
Unavailable
,您应重试在另一个请求中发送。
NotRegistered
,您应从服务器数据库中删除注册 ID,因为应用已从设备中卸载,或客户端应用未配置为接收消息。
如果纯文本请求成功(HTTP 状态代码 200),响应正文将包含 1 或 2 行键值对。第一行始终存在,其内容是
id=
ID of sent message
或
Error=
GCM error code
。如果有第二行,其格式为
registration_id=
canonical ID
。第二行是可选项,仅在第一行不是错误时才能发送第二行。建议采用 JSON 响应的类似处理方式来处理纯文本响应:
id
开头,则检查第二行:
registration_id
开头,则获取其值,并替换服务器数据库中的注册令牌。
Error
的值:
NotRegistered
,则从服务器数据库中删除注册令牌。
Unavailable
,而是应返回 500 HTTP 状态)。
本部分介绍几个表示消息处理成功的响应示例。请参阅 请求格式 以了解这些响应所依据的请求。
以下是一个简单的 JSON 消息示例,该消息成功发送至一个接收者,且响应中不含规范 ID:
或者,如果请求是纯文本格式:
以下是向 6 个接收者发送 JSON 消息的结果(ID 分别是 4、8、15、16、23 和 42),其中 3 条消息处理成功,返回 1 个规范注册令牌,还有 3 个错误:
在本例中:
如果仅有上面的第三条消息是以纯文本格式发送:
如果上面的第五条消息也是以纯文本格式发送:
Cloud Connection Server (CCS) 是一个 XMPP 终点,可向 Google 服务器提供持续的异步双向连接。连接可用于在服务器与已连接FCM的用户设备之间发送和接收消息。
您可以继续使用 HTTP 请求机制向与使用 XMPP 的 CSS 并行的 Firebase Cloud Messaging服务器发送消息。CCS 的一些优点包括:
有关所有消息参数以及可为其提供支持的连接服务器的列表,请参阅 服务器参考 。
CCS 仅使用 XMPP 作为已认证传输层,因此您可使用大多数 XMPP 库来管理连接。
要优化 XMPP 连接服务器的可靠性和双向消息传递能力,需要创建长期连接,而不要频繁地断开连接和重新连接。
CCS XMPP 终点运行于
fcm-xmpp.googleapis.com:5235
。进行功能测试时(针对非生产用户),您应改为连接至
fcm-xmpp.googleapis.com:5236
(注意端口不同)。在预生产环境(运行最新 CCS 的较小型环境)中进行常规测试将有助于隔离真实用户与测试代码,以及提早检测出异常行为更改。请注意,连接将收到发往FCM
发送者 ID
的上游消息,无论其连接到哪种环境。因此,连接至
fcm-xmpp.googleapis.com:5236
的测试代码应使用不同的FCM发送者 ID,以避免通过测试连接发送来自生产通信的上游消息。
连接需要符合两个重要条件:
<your_GCM_Sender_Id>@gcm.googleapis.com
(GCM
发送者 ID
)和服务器密钥作为密码的 SASL PLAIN 身份验证机制,其中发送者 ID 和服务器密钥是您在配置客户端应用时获得的值。请参阅您的平台的客户端文档以了解关于获得这些凭据的信息。
如有任何点连接失败,您应立即重新连接。如果身份验证后连接断开,无需后退。
对于每个 发送者 ID ,FCM允许 1000 个并行连接。
以下代码段说明如何在 CCS 中进行身份验证。
<stream:stream to="gcm.googleapis.com" version="1.0" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams"><str:features xmlns:str="http://etherx.jabber.org/streams"> <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"> <mechanism>X-OAUTH2</mechanism> <mechanism>X-GOOGLE-TOKEN</mechanism> <mechanism>PLAIN</mechanism> </mechanisms> </str:features><auth mechanism="PLAIN" xmlns="urn:ietf:params:xml:ns:xmpp-sasl">MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==</auth><success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>建立 XMPP 连接后,CCS 和您的服务器即可使用标准 XMPP
<message>
节来回发送以 JSON 编码的消息。<message>
正文必须为:<gcm xmlns:google:mobile:data> JSON payload常规FCM消息的 JSON 负载类似于FCM http 终点使用的负载,不同之处在于:
registration_ids
代替 to
。message_id
,此为必填字段。此 ID 唯一标识 XMPP 连接中的消息。来自 CCS 的 ACK 或 NACK 使用message_id
标识从应用服务器发送至 CCS 的消息。因此,应注意,此 message_id
并非唯一(对于每个发送者 ID),但始终存在。 除了常规FCM消息外,还会发送控制消息,此消息由 JSON 对象中的 message_type
字段表示。该值可以是"ack"或"nack",或"control"(参见以下格式)。您的服务器可能会忽略任何带有未知 message_type
的FCM消息。
对于您的应用服务器从 CCS 收到的每条设备消息,它均需要发送一条 ACK 消息。无需发送 NACK 消息。如果您不为消息发送 ACK,CCS 将在下次建立新的 XMPP 连接时重新发送,除非该消息已过期。
CCS 还将对每一条服务器至设备消息发送一条 ACK 或 NACK 消息。如果您未收到任何一种消息,则表示 TCP 连接在运行过程中关闭,您的服务器需要重新发送消息。有关详情,请参见流控制。
有关所有消息参数以及可为其提供支持的连接服务器的列表,请参阅服务器参考。
以下是一个用于"发送至同步"消息的简单的 XMPP 节:
<message id=""> <gcm xmlns="google:mobile:data"> "to":"REGISTRATION_ID", // "to" replaces "registration_ids" </message>带有负载的消息 — 通知消息
以下是一个用于通知消息的 XMPP 节:
<message id=""> <gcm xmlns="google:mobile:data"> "to":"REGISTRATION_ID", // "to" replaces "registration_ids" "notification": { "title": "Portugal vs. Denmark”, "text”: "5 to 1” "time_to_live":"600" </message>您可以同时有通知消息和数据负载消息。请参阅 服务器参考以了解通知负载所支持的密钥。另请参阅 消息负载中的通知和数据。带有负载的消息 — 数据消息
以下是一个含有从应用服务器发送至 CCS 的 JSON 消息的 XMPP 节:
<message id=""> <gcm xmlns="google:mobile:data"> "to":"REGISTRATION_ID", // "to" replaces "registration_ids" "message_id":"m-1366082849205" // new required field "data": "hello":"world", "time_to_live":"600", "delay_while_idle": true/false, "delivery_receipt_requested": true/false </message>CCS 响应可能有三种形式。第一种是常规"ack"消息。但是,如果响应中包含错误,消息可能有两种不同形式,如下所述。
ACK 消息
以下是一个包含从 CCS 发送至应用服务器的 ACK/NACK 消息的 XMPP 节:
<message id=""> <gcm xmlns="google:mobile:data"> "from":"REGID", "message_id":"m-1366082849205" "message_type":"ack" </message>NACK 消息
NACK 错误是一种常规 XMPP 消息,其中
message_type
状态消息为"nack"。NACK 消息包含:
举例如下。
错误注册:
<message> <gcm xmlns="google:mobile:data"> "message_type":"nack", "message_id":"msgId1", "from":"SomeInvalidRegistrationId", "error":"BAD_REGISTRATION", "error_description":"Invalid token on 'to' field: SomeInvalidRegistrationId" </message>
无效 JSON:
<message> <gcm xmlns="google:mobile:data"> "message_type":"nack", "message_id":"msgId1", "from":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", "error":"INVALID_JSON", "error_description":"InvalidJson: JSON_TYPE_ERROR : Field \"time_to_live\" must be a JSON java.lang.Number: abc" </message>超出设备消息率:
<message id="..."> <gcm xmlns="google:mobile:data"> "message_type":"nack", "message_id":"msgId1", "from":"REGID", "error":"DEVICE_MESSAGE_RATE_EXCEEDED", "error_description":"Downstream message rate exceeded for this registration id" </message>有关完整的 NACK 错误代码列表,请参阅服务器参考。除非另有说明,否则不能重试 NACK 消息。异常 NACK 错误代码的处理方式应与
INTERNAL_SERVER_ERROR
相同。在某些情况下也可能会发生节错误。节错误包含:
<message id="3" type="error" to="[email protected]/ABC"> <gcm xmlns="google:mobile:data"> {"random": "text"} <error code="400" type="modify"> <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/> <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"> InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n </text> </error> </message>有时,CCS 需要关闭连接以执行负载平衡。在关闭连接之前,CCS 会发送一条
CONNECTION_DRAINING
消息,以说明连接即将被排空,很快会关闭。"排空"是指阻止消息流进入某连接,但允许已进入管道的消息继续运行。当您收到CONNECTION_DRAINING
消息时,应立即开始向另一个 CCS 连接发送消息,如有必要,可开启新的连接。但是,您应使原始连接保持开启状态,并继续接收可能来自该连接的消息(并对其进行确认 [ACK])— CCS 将在准备就绪后关闭连接。
CONNECTION_DRAINING
消息如下所示:<message> <data:gcm xmlns:data="google:mobile:data"> "message_type":"control" "control_type":"CONNECTION_DRAINING" </data:gcm> </message>
CONNECTION_DRAINING
是当前唯一支持的control_type
。接收送达回执
对于 Android 和 Chrome 客户端应用,当设备确认收到由 CCS 发送的消息后,您可获得送达回执(从 CCS 发送至您的应用服务器)。
发送至 iOS 设备的消息不支持送达回执。要启用此功能,应用服务器发送至 CCS 的消息必须包含
delivery_receipt_requested
字段。如果该字段设置为true
,则当设备确认收到某特定消息时,CCS 将发送送达回执。以下是一个含有 JSON 消息的 XMPP 节,其中
"delivery_receipt_requested"
设置为true
:<message id=""> <gcm xmlns="google:mobile:data"> "to":"REGISTRATION_ID", "message_id":"m-1366082849205" "data": "hello":"world", "time_to_live":"600", "delay_while_idle": true, "delivery_receipt_requested": true </message>以下是 CCS 发送的送达回执示例,用于告诉您的应用服务器设备已收到 CCS 向其发送的消息:
<message id=""> <gcm xmlns="google:mobile:data"> "category":"com.example.yourapp", // to know which app sent it "data": “message_status":"MESSAGE_SENT_TO_DEVICE", “original_message_id”:”m-1366082849205” “device_registration_id”: “REGISTRATION_ID” "message_id":"dr2:m-1366082849205", "message_type":"receipt", "from":"gcm.googleapis.com" </message>请注意以下事项:
"message_type"
设置为 "receipt"
。"message_status"
设置为 "MESSAGE_SENT_TO_DEVICE"
,表示设备已收到消息。请注意,在该例中,"message_status"
不是一个字段,而是数据负载的一部分。dr2:
。应用服务器发送的 ACK 消息中必须含有此 ID,在本例中为dr2:m-1366082849205
。"data"
字段中。发送至 CCS 的每一条消息都会收到 ACK 或 NACK 响应。未收到任何响应的消息被视为挂起。如果挂起消息计数达到 100,应用服务器应停止发送新消息,等待 CCS 对某些现有挂起消息进行确认,如图 1 所示:
图 1. 消息/ack 流。
相反,为避免应用服务器过载,如果有太多未确认的消息,CCS 将停止发送。因此,应用服务器应尽快"ACK"(确认)通过 CCS 从客户端应用收到的上游消息,以便尽快保持稳定的进入消息流。上述挂起消息限制不适用于这些 ACK。即使挂起消息计数达到 100,应用服务器也应继续为从 CCS 收到的消息发送 ACK,以避免阻塞新的上游消息传递。
ACK 仅在一个连接环境中有效。如果连接在消息可获确认之前关闭,应用服务器应等待 CCS 重新发送上游消息,然后再次对其进行确认。同样地,所有在连接关闭之前未从 CCS 收到 ACK/NACK 的挂起消息都应重新发送。
Firebase Cloud Messaging (FCM) 提供多种消息传递选项和功能。为帮助您了解 FCM的各种功能,本页列举和介绍了一些最常用的消息选项。
许多选项仅在通过 Firebase Cloud Messaging服务器实现时可用。 有关消息选项的完整列表,请参阅您所选连接服务器协议 HTTP 或 XMPP 的参考信息。
根据要实现的 FCM 功能的不同,您可能需要下列来自 Firebase 项目的凭据:
发送者 ID | 创建 Firebase 项目时已创建的唯一数值,您可以在 Settings 窗格中找到此值。 发送者 ID 用于标识可以向客户端应用发送消息的每个应用服务器。 |
API 密钥 | 一种保存在应用服务器上的 API 密钥,它可以授权应用服务器访问 Google 服务。 不要在客户端代码的任何位置包含 API 密钥。 您在创建 Firebase 项目时将获得 API 密钥。 可以在项目的 Settings 窗格中找到 API 密钥。 |
注册令牌 | 由 FCM SDK 为每个客户端应用实例生成的 ID。 单一设备和设备群组消息传递需要该令牌。请注意,注册令牌必须保密。 |
对于下游消息传递, FCM 提供两种负载:通知和数据。 通知是更轻量化的选项,最高限制 2KB,且拥有一个预定义的用户可见键集。 数据负载让开发者可以发送最高 4KB 的自定义键值对。 通知消息可包含一个可选数据负载,当用户点击该通知时会传递这个数据负载。
使用情景 | 发送方法 | |
---|---|---|
通知 | FCM 代表客户端应用自动向最终用户设备显示消息。 通知拥有一组预定义的用户可见键。 | 设置 notification 键。可能有可选数据负载。始终可折叠。 |
数据 | 客户端应用负责处理数据消息。数据消息仅有自定义键值对。 | 仅设置 data 键。可以为可折叠,也可以为不可折叠。 |
如果您需要 FCM 代表您的客户端应用处理显示通知时,可使用通知。 如果您想要在您的 Android 客户端应用中处理显示或消息,或者您想要在有 FCM 直接连接时向 iOS 设备发送消息,可使用数据消息。
应用服务器可以发送包含通知和数据负载的消息。 此情况下, FCM 处理显示通知负载,客户端应用处理数据负载。
当应用在后台运行时,如果您想要向 iOS 设备发送只包含自定义键值的消息,请在data
键中设置自定义键值对,并将content_available
设置为 true
。
通知旨在为开发者提供一种简单的方法以发送带有预定义键和可选自定义键值对的用户可见显示消息。 数据负载仅包括开发者的自定义键值对,客户端应用必须处理该消息。
您可以发送包含通知和数据负载的消息。
要发送通知,可设置 notification
键并针对通知消息的用户可见部分设置必要的预定义键选项集。 例如,这是 IM 应用中的 JSON 格式的通知消息。 用户可能会在设备上看到标题为"Portugal vs. Denmark"、文本为"great match!"的消息:
应用在后台运行时,通知将会传递至通知托盘。 对于在后台运行的应用,消息由下列回调处理:
didReceiveRemoteNotification:
onMessageReceived()
。数据包中的 notification
键包含通知。
使用自定义键值对设置 data
键以将数据负载发送至客户端应用。 数据消息的最大负载为 4KB。
例如,以下是上面同一 IM 应用中的一条 JSON 格式消息,在此消息中,信息封装在 data
键中,且客户端应用需要解释内容:
{
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data" : {
"Nick" : "Mario",
"body" : "great match!",
"Room" : "PortugalVSDenmark"
},
}
在 iOS 上, FCM 仅在应用位于前台且已建立 FCM连接时存储和传递消息。
在 Android 上,客户端应用在 onMessageReceived()
中接收数据消息,并相应地处理键值对。
注意下列更多平台特定的详细信息:
在 Android 上,系统可以在用于启动您的 Activity 的 Intent 中检索数据负载。
在 iOS 上,可在 didReceiveRemoteNotification:
中找到数据负载。
接收包含通知和数据负载的消息时的应用行为取决于应用是在后台还是前台运行 - 特别是在接收时应用是否处于活动状态。
<li><strong>在前台运行时</strong>,您的应用将会接收带有两种可用负载的消息对象。</li>
以下是包含 notification
键和 data
键的 JSON 格式消息:
不可折叠消息表示每一条消息都将被传递至设备。 不可折叠消息可传递一些有用内容至手机应用,从而联系服务器以获取数据,这与"ping"相反。 除了通知消息以外(始终是可折叠消息),其他全部默认为不可折叠消息。 FCM 不保证传递顺序。
聊天消息或关键消息都是典型的不可折叠消息。 例如,在 IM 应用中,您可能想要传递每一条消息,因为它们的内容各不相同。
不可折叠消息最多可存储 100 条。达到此限值后所有存储的消息都将被丢弃。 当设备重新上线后,将收到一条特殊消息,提示已达到此限值。 之后,应用可以正常处理该状况,一般情况下会请求从应用服务器完全同步。
可折叠消息是一种可替换为包含相同折叠键的新消息的消息,前提是其还未被传递至设备。
两种常见的可折叠消息是"发送至同步"消息和通知。 "发送至同步"消息是一个"ping",它会告诉移动应用从服务器同步数据。 为用户更新最新比分的运动应用就是这种消息的示例。
仅有最近的消息才会被关联。
FCM 允许每台设备的应用服务器在任意指定时间内最多使用 4 个不同的折叠键。 也就是说, FCM 连接服务器可以同时存储 4 条不同的可折叠"发送至同步"消息,每一条都含有不同的折叠键。
如果超出此限值, FCM 将仅保留 4 个折叠键,具体保留哪个不一定。
在 iOS 上,应用服务器需要发送"发送至同步"消息时设置content_available
。 非活动客户端应用将在后台执行您的逻辑,同时,前台的应用会将消息传递至 didReceiveRemoteNotification:
。
从性能的角度来看,可折叠消息是更好的选择,但前提是您的应用不需要使用不可折叠消息。 但是,如果您使用可折叠消息,须切记: FCM 仅允许每个注册令牌的 FCM 连接服务器在任意指定时间内最多使用 4 个不同的折叠键。
您不得超出此限值,否则将导致出现意外后果。
使用情景 | 发送方法 | |
---|---|---|
不可折叠 | 每一条消息对客户端应用都很重要,它们都需要进行传递。 | 除了通知消息以外,其他全部默认为不可折叠消息。 |
可折叠 | 当有更新消息呈现旧的相关消息且与客户端应用毫不相关时, FCM 将替换旧消息。 例如: "发送至同步"消息或过期通知。 | 设置 collapse_key 参数。 |
下游消息的传递优先级有两种: 普通优先级和高优先级。普通优先级和高优先级的消息传递方式如下:
例如,带有即时通讯、聊天或语音通话提醒功能的应用通常需要打开网络连接并确保 FCM 及时将消息传递给设备。
只有在消息属于时间关键型且需要用户立刻交互时才能设置为高优先级,但请注意,将消息设置为高优先级会比普通优先级耗费更多电池电量。
有效值为 normal
和 high
。如需了解更多详情,请参阅
HTTP</a> 或 <a href="/docs/cloud-messaging/xmpp-server-ref.html#priority">XMPP</a> 的服务器参考。
对于 iOS 客户端应用,普通和高优先级类似于 APNs 的 5 至 10 优先级。 有关 iOS 特定行为完整的详细说明,请参阅APNs 文档。 有关 Android 特定行为的详细说明,请参阅对打盹模式和应用待机模式进行针对性优化。
以下是一个用于通知杂志订阅者有新内容可以下载的普通优先级消息示例:
FCM 通常会在消息发出之后马上进行传递。但是,也有一些例外情况。 例如,如果在 Android 平台上,设备可能处于关闭、离线或不可用状态。
或者发件人自己可能会通过使用 delay_while_idle
标记请求不发送消息,直至设备开始处于活动状态。
最后, FCM 可能有意延迟传递消息,以防止应用消耗过多资源并对电池寿命产生不良影响。
倘若如此, FCM 将存储消息,等到可行时立即发送。 尽管大多数情况下这样做都没有什么问题,但有些应用可能永远不会传递延迟消息。 举例来说,如果消息是来电或视频聊天通知,则它将仅在电话中断之前较短的时间内有意义。
或者,如果消息是事件邀请,那么如果在事件结束后才收到消息,它将毫无用处。
您可以使用 HTTP 和 XMPP 请求中支持的 time_to_live
参数来指定消息的最长寿命。
此参数的值必须介于 0 至 2,419,200 秒之间,且符合 FCM 存储并尝试传递消息的最长时间期限。
不含有该字段的请求的最长默认期限是 4 周。
以下是此功能的一些可能用途:
指定消息寿命的另一个优势是 FCM绝不会阻挡 time_to_live
(TTL) 值为 0 秒的消息。
也就是说, FCM 将尽全力保证必须传递的"机不可失、时不再来"的消息得到传递。 切记,time_to_live
值为 0 表示倘若消息无法立即传递,将会被丢弃。 但是,由于此类消息不会被存储,因此可以为发送通知提供最佳延时。
以下是包含 TTL 的 JSON 格式的请求示例:
目前,iOS 上不支持为通知消息设置
time_to_live
。
FCM 允许多方向同一个客户端应用发送消息。例如,假设客户端应用是带有多个撰稿者的文章聚合器,且每一位撰稿者都应该能够在发布新文章时发送消息。 此消息可能包含一个 URL,供客户端应用下载文章。 利用 FCM , 您可以让每一位撰稿者都能发送自己的消息,而不必将所有发送活动集中在一个位置。
为此,需要确保每一位发送者都生成自己的发送者 ID。 请参阅您的平台的客户端文档,了解有关如何获得 FCM 发送者 ID 的信息。 当请求注册时,客户端应用将多次获得令牌,每一次在访问群体字段中都有不同的发件人 ID。
最后,与对应的应用服务器共享注册令牌(以完成 FCM 注册客户端/服务器握手),并且它们将能够通过自己的身份验证密钥向客户端应用发送消息。
请注意,最多只能有 100 个发件人。
当应用服务器向 FCM 发布消息并收到返回的消息 ID 时,并不意味着消息已传送至设备, 而是表示其获准传递。 获准传递后消息发生的行为取决于很多因素。
在最佳案例中,如果设备已连接至 FCM,屏幕处于开启状态且没有节流限制,那么消息将被立即传递。
如果设备已连接但处于空闲状态,那么消息将被立即传递,除非 delay_while_idle
标记设置为 true
。否则,该消息将被存储在 FCM 连接服务器中,直至设备唤醒。 这就是 collapse_key
标记的作用:如果已存储一条含有相同折叠键(和注册令牌)的消息,并等待传递,则旧消息将被丢弃,新消息将代替它(即,旧消息将被新消息折叠起来)。 但是,如果未设置折叠密钥,则新消息和旧消息都将被存储下来供以后传递。
如果设备未连接至 FCM,则消息将被存储,直至建立连接(再次遵循折叠键规则)。 当建立连接后, FCM 将向设备传递所有挂起消息,而不考虑 delay_while_idle
标记。 如果设备再也不会建立连接(例如恢复出厂设置),消息最终会超时,且 FCM 将从存储中丢弃该消息。 默认超时时间为 4 周,除非设置了 time_to_live
标记。
最后,当 FCM 尝试向设备传递消息,而应用已被卸载时, FCM 将立刻丢弃该消息并使注册令牌无效。 继续尝试向该设备发送消息将导致发生 NotRegistered
错误。
本文档提供通过 Firebase Cloud Messaging从您的应用服务器向客户端应用传递消息时要用到的 HTTP 语法的参考信息。参数和选项分为以下几个大类:
本部分介绍发送下游消息和从 Firebase Cloud Messaging解释 HTTP 响应所使用的语法。
下表列出了 HTTP JSON 消息的目标、选项和负载。有关下游消息传递的详细信息,请参阅简单下游消息传递
表 1. 下游 HTTP 消息 (JSON) 的目标、选项和负载。
参数 | 用法 | 说明 | |
---|---|---|---|
目标 | |||
to | 可选,字符串 | 此参数用于指定消息的接收者。 值必须为注册令牌、通知键或主题。请不要在发送至多个主题时设置此字段。请参阅 | |
registration_ids | 字符串数组 | 此参数用于指定一系列接收多播消息的设备(注册令牌或 ID)。其中必须包含至少 1 个、最多 1000 个注册令牌。 仅可以将此参数用于多播消息传递,而不可以用于单一接收者。仅允许使用 HTTP JSON 格式进行多播消息传递(发送至 1 个以上的注册令牌)。 | |
condition | 可选,字符串 | 此参数用于指定确定消息目标条件的逻辑表达式。 支持的条件:主题,采用"‘您的主题’在主题中"格式。此值不区分大小写。 支持的运算符: | |
notification_key 已弃用 | 可选,字符串 | 此参数已被弃用。应使用 | |
选项 | |||
collapse_key | 可选,字符串 | 此参数用于指定一组可折叠的消息(例如含有 请注意,消息发送顺序并不固定。 注:在任意指定时间内最多允许 4 个不同的折叠密钥。这意味着FCM连接服务器可以为每个客户端应用同时存储 4 条不同的"发送至同步"消息。如果超出此限值,FCM连接服务器将无法保证保留哪 4 个折叠密钥。 | |
priority | 可选,字符串 | 设置消息的优先级。有效值为"普通"和"高"。在 iOS 上,这些值相当于 APNs 的 5 至 10 级优先级。 默认以普通优先级发送消息。普通优先级可优化客户端应用的电池消耗,除非需要立即传递,否则应使用普通优先级。对于普通优先级消息,应用可以接收未指定延迟时间的消息。 当以高优先级发送消息时,将会立即发送消息,应用可能会唤醒睡眠中的设备并打开服务器网络连接。 如需了解详细信息,请参阅设置消息的优先级。 | |
content_available | 可选,JSON 布尔值 | 在 iOS 上,使用此字段代表 APNs 负载中的 content-available 。当发送通知或消息且此字段设置为 true 时,将会唤醒处于非活动状态的客户端应用。在 Android 上,默认由数据消息唤醒应用。Chrome 目前不支持此功能。
| |
delay_while_idle | 可选,JSON 布尔值 | 当此参数设置为 true 时,表示只能在设备变为活动状态后发送消息。
默认值为 | |
time_to_live | 可选,JSON 数值 | 此参数用于指定当设备离线时消息在FCM存储中保留的时长(单位:秒)。受支持的最长生存时间为 4 周,默认值为 4 周。如需了解详细信息,请参阅设置消息寿命。 | |
restricted_package_ | 可选,字符串 | 此参数用于指定应用的数据包名称,其注册令牌必须匹配才能接收消息。 | |
dry_run | 可选,JSON 布尔值 | 此参数设置为 默认值为 | |
负载 | |||
data | 可选,JSON 对象 | 此参数用于指定消息负载的自定义键值对。 (例如,使用 在 iOS 上,如果通过 APNs 发送消息,它代表自定义数据字段。如果通过FCM连接服务器发送,其在 在 Android 中上,这会产生一个名为 键不能是保留字("from"或以"google"或"gcm"开头的任何字)。不要使用该表中已确定的任何字(例如 推荐使用字符串类型中的值。您必须将对象中的值或其他非字符串数据类型(例如整数或布尔值)转换成字符串。 | |
notification | 可选,JSON 对象 | 此参数用于指定通知负载的用户可见预定义键值对。有关详情,请参阅通知负载支持。有关通知消息和数据消息选项的详细信息,请参阅负载。 |
下表列出了通知消息中可使用的预定义参数。
表 2. 按平台分类的通知消息传递参数
参数 | 平台 | 用法 | 说明 |
---|---|---|---|
title
| iOS (watch)、Android | 必选 (Android),可选 (iOS),字符串 | 指示通知标题。该字段在 iOS 手机和平板电脑上不可见。 |
body | iOS、Android | 可选,字符串 | 指示通知正文。 |
icon | Android | 必选,字符串 | 指示通知图标。将可绘制资源 myicon 的值设为 myicon 。 |
sound | iOS、Android | 可选,字符串 | 指示设备收到通知时要播放的声音。支持 Android 声音文件必须位于 |
badge | iOS | 可选,字符串 | 指示客户端应用首页图标上的标志。 |
tag | Android | 可选,字符串 | 指示每一条通知是否会导致在 Android 上的通知抽屉式导航栏中产生新条目。 如未设置此参数,每次请求时将创建一个新的通知。 如果已设置此参数,且已显示带有相同标记的通知,则新通知将替换通知抽屉式导航栏中的现有通知。 |
color | Android | 可选,字符串 | 指示图标颜色,以 #rrggbb 格式表示 |
click_action | iOS、Android | 可选,字符串 | 指示与用户点击通知相关的操作。 如果在 iOS 中设置此参数,则它对应于 APNs 负载中的 在 Android 上,如果设置此参数,则当用户点击通知时,将会启动带有匹配 Intent 过滤器的 Activity。 |
body_loc_key | iOS、Android | 可选,字符串 | 指示待本地化的正文字符串对应的键。 在 iOS 中,这对应于 APNs 负载中的"loc-key"。 在 Android 中,当填充此值时将使用应用字符串资源中的键。 |
body_loc_args | iOS、Android | 可选,字符串形式的 JSON 数组 | 指示要替换待本地化的正文字符串中的格式说明符的字符串值。 在 iOS 中,这对应于 APNs 负载中的"loc-args"。 在 Android 中,这些是字符串资源的格式参数。如需了解详细信息,请参阅格式化和样式设置。 |
title_loc_key | iOS、Android | 可选,字符串 | 指示待本地化的标题字符串对应的键。 在 iOS 中,这对应于 APNs 负载中的"title_loc_key"。 在 Android 中,当填充此值时将使用应用字符串资源中的键。 |
title_loc_args | iOS、Android | 可选,字符串形式的 JSON 数组 | 指示要替换待本地化的标题字符串中的格式说明符的字符串值。 在 iOS 中,这对应于 APNs 负载中的"title_loc_args"。 在 Android 中,这些是字符串资源的格式参数。如需了解详细信息,请参阅格式化字符串。 |
下表列出了纯文本下游 HTTP 消息的目标、选项和负载语法。
表 3. 下游纯文本 HTTP 消息的目标、选项和负载。
参数 | 用法 | 说明 |
---|---|---|
目标 | ||
registration_id | 必选,字符串 | 此参数用于指定接收消息的客户端应用(注册 ID)。 仅允许使用 HTTP JSON 格式进行多播消息传递(发送至一个以上注册 ID)。 |
选项 | ||
collapse_key | 可选,字符串 | 有关详情,请参阅表 1。 |
delay_while_idle | 可选,布尔值或数字 | 有关详情,请参阅表 1。 |
time_to_live | 可选,数字 | 有关详情,请参阅表 1。 |
restricted_package_name | 可选,字符串 | 有关详情,请参阅表 1。 |
dry_run | 可选,布尔值 | 有关详情,请参阅表 1。 |
负载 | ||
data. | 可选,字符串 | 此参数用于指定消息负载的键值对。键值参数没有数量限制,但是消息总大小不得超过 4kb。 例如,在 Android 中, 键不能是保留字("from"或以"google"或"gcm"开头的任何字)。不要使用该表中已确定的任何字(例如 |
应用服务器应评估消息响应标头和正文以解释通过FCM发送的消息响应。下表介绍可能的响应。
表 4. 下游 HTTP 消息响应标头。
响应 | 说明 |
---|---|
200 | 消息处理成功。响应正文包含有关消息状态的详细信息,但其格式取决于请求是 JSON 格式还是纯文本格式。有关详情,请参阅表 5。 |
400 | 仅适用于 JSON 请求。表示请求不能作为 JSON 进行分析,或其包含无效的字段(例如,传递带有预期数字的字符串)。详细的故障原因位于响应中,应先解决故障方可重试请求。 |
401 | 验证发送者帐户身份时出错。 |
5xx | 错误代码在 500-599 范围之间(例如 500 或 503)表示在尝试处理请求时,FCM连接服务器发生内部错误,或服务器暂时不可用(例如,由于超时原因)。发件人必须服从响应中的任何 Retry-After
标头,稍后重试。应用服务器必须实现指数回退。 |
下表列出了下游消息响应正文中的字段 (JSON)。
表 5. 下游 HTTP 消息响应正文 (JSON)。
参数 | 用法 | 说明 |
---|---|---|
multicast_id | 必选,数字 | 用于识别多播消息的唯一 ID(数字)。 |
success | 必选,数字 | 处理时未出错的消息数。 |
failure | 必选,数字 | 无法处理的消息数。 |
canonical_ids | 必选,数字 | 包含规范注册令牌的结果数。有关此主题的详细介绍,请参阅注册概览。 |
results | 可选,数组对象 | 代表已处理消息状态的对象数组。对象的排列顺序与请求相同(即,对于请求中的每一个注册 ID,其结果的列出顺序与响应中的索引顺序相同)。
|
表 6. 主题消息 HTTP 响应正文 (JSON)。
参数 | 用法 | 说明 |
---|---|---|
message_id | 可选,数字 | 当FCM成功接收到请求并尝试传递至所有订阅设备时的主题消息 ID。 |
error | 可选,字符串 | 处理消息时发生的错误。可能出现的值位于表 9中。 |
表 7. 下游 HTTP 消息响应正文(纯文本)的成功响应。
参数 | 用法 | 说明 |
---|---|---|
id | 必选,字符串 | 此参数用于指定FCM连接服务器成功处理的唯一消息 ID。 |
registration_id | 可选,字符串 | 此参数用于指定处理和接收消息的客户端应用的规范注册令牌。发件人应在未来请求中将注册标令牌替换为该值;否则消息可能会被拒绝。 |
表 8. 下游 HTTP 消息响应正文(纯文本)的错误响应。
参数 | 用法 | 说明 |
---|---|---|
Error | 必选,字符串 | 此参数用于指定处理接收者消息时的错误值。有关详情,请参阅表 9。 |
下表列出了下游消息的错误响应代码。
表 9. 下游消息错误响应代码。
错误 | HTTP 代码 | 推荐操作 |
---|---|---|
缺少注册令牌 | 200 + error:MissingRegistration | 检查请求中是否包含一个注册令牌(在纯文本消息中的 registration_id 中,或在 JSON 中的to 或 registration_ids 字段中)。 |
无效注册令牌 | 200 + error:InvalidRegistration | 检查您传送至服务器的注册令牌格式。确保其匹配客户端应用在注册 Firebase 通知时获得的注册令牌。不能截断或添加其他字符。 |
未注册设备 | 200 + error:NotRegistered | 现有注册令牌可能在很多情况下失效,包括:
|
无效的软件包名称 | 200 + error:InvalidPackageName | 确保消息寻址至软件包名称与请求中传递的值相匹配的注册令牌。 |
身份验证错误 | 401 | 无法对用于发送消息的发送者帐户进行身份验证。可能原因有:
|
不匹配的发送者 | 200 + error:MismatchSenderId | 注册令牌关联至某一组发送者。当客户端应用注册FCM时,必须指定允许哪些发送者发送消息。当向客户端应用发送消息时,您应使用这些发送者 ID 之一。如果您切换到不同的发送者,现有注册令牌不会起作用。 |
无效 JSON | 400 | 检查 JSON 消息格式正确,且包含有效字段(例如确保传入正确的数据类型)。 |
消息过大 | 200 + error:MessageTooBig | 确保消息中包含的负载数据的总大小不超过FCM的限制:大多数消息的上限是 4096 字节,如果是 iOS 上的标题或通知消息,上限是 2048 字节。这包括键和值。 |
无效的数据密钥 | 200 + error: InvalidDataKey | 确保负载数据不包含FCM内部使用的密钥(例如 from 、 gcm ,或任何以 google 为前缀的值)。请注意,某些字词(例如 collapse_key )也会被 FCM 使用,但允许包含在负载中,在这种情况下负载值将被 FCM 值覆盖。 |
无效的生存时间 | 200 + error:InvalidTtl | 检查 time_to_live 中使用的值是代表 0 至 2,419,200 秒(4 周)之间的一段时间(单位:秒)的整数。 |
超时 | 5xx 或 200 + error:Unavailable | 服务器无法及时处理请求。重试相同请求,但必须:
导致故障风险的发件人将被列入黑名单。 |
内部服务器错误 | 500 或 200 + error:InternalServerError | 服务器在尝试处理请求时遇到错误。您可按照"超时"中的要求重试相同请求(参见上一行)。如果错误仍然存在,请在 android-gcm group 中报告错误。 |
超出设备消息率 | 200 + error: DeviceMessageRate Exceeded | 到特定设备的消息率过高。减少发送到此设备的消息数,且不要立即重试向此设备发送消息。 |
超出主题消息率 | 200 + error: TopicsMessageRate Exceeded | 发送给某特定主题订阅者的消息率过高。减少为此主题发送的消 |