谷歌fireBase推送
2016-10-20 10:31
337 查看
之前做的一个推送是针对国外用户的,用的是google GCM ,这阵子又研究了下fireBase。通过查看firebse文档说明,摘取了部分最有用的内容:
要发送消息,应用服务器需发出 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。
用HttpURLConnection写了个简单
demo。
/** * 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服务器端包含两个组件:GCM 连接服务器,由 Google 提供。这些服务器从一个应用服务器获取消息,并将其发送至在设备上运行的客户端应用。Google
为 HTTP 和 XMPP 提供连接服务器。
一台应用服务器,您必须在您的环境中实现它。此应用服务器通过选定的FCM连接服务器,使用合适的 XMPP 或 HTTP 协议向客户端应用发送数据。
完整的 FCM 实现既需要客户端实现,也需要服务器实现。有关如何实现客户端应用的详细信息,请参阅适合您的平台(iOS、Android 或 Chrome)的客户端指南。
应用服务器的作用
在您可以编写使用 Firebase Cloud Messaging的客户端应用之前,您必须拥有一个满足以下标准的应用服务器:能够与您的客户端通信。
能够向FCM连接服务器发送格式正确的请求。
能够使用指数回退方式处理请求和重新发送请求。
能够存储服务器密钥和客户端注册令牌。注:绝对不要在任何客户端代码中包含服务器密钥。
对于 XMPP,服务器必须能够生成消息 ID 来唯一地标识它发送的每条消息(GCM HTTP 服务器生成消息 ID 并在响应中返回相应 ID)。XMPP 消息 ID 对于每个发送者 ID 应唯一。
您需要决定使用哪个FCM连接服务器协议来让您的应用服务器与FCM连接服务器交互。请注意,如果您想从客户端应用使用上游消息传递,则必须使用 XMPP。有关更多详细讨论,请参阅选择FCM连接服务器协议。
选择FCM连接服务器协议
目前,FCM提供两种连接服务器协议:HTTP 和 XMPP。您的应用服务器可以单独或以串联方式使用这些协议。XMPP消息传递与 HTTP 消息传递具有以下差异:
上游/下游消息
HTTP:仅适用于云端至设备、最多 4KB 数据的下游消息。
XMPP:适用于上游和下游(设备至云端、云端至设备)、最多 4 KB 数据的消息。
消息传递(同步或异步)
HTTP:同步。应用服务器以 HTTP POST 请求的形式发送消息,并等待响应。此机制是同步的,并阻止了发件人在收到响应前发送其他消息。
XMPP:异步。应用服务器通过持续型 XMPP 连接,以全线速向/从所有设备发送/接收消息。XMPP 连接服务器异步发送确认或失败通知(以 ACK 和 NACK JSON 编码的特殊 XMPP 消息形式)。
JSON
HTTP:JSON 消息以 HTTP POST 的形式发送。
XMPP:JSON 消息封装在 XMPP 消息中。
纯文本
HTTP:纯文本消息以 HTTP POST 的形式发送。
XMPP:不支持。
向多个注册令牌发送多播下游消息。
HTTP:支持 JSON 格式的消息。
XMPP:不支持。
实现 HTTP 连接服务器协议
本部分将介绍FCM HTTP 连接服务器。连接服务器是一种由 Google 提供的服务器,它可以从应用服务器接收消息并将其发送至设备。有关所有消息参数以及可为其提供支持的连接服务器的列表,请参阅服务器参考。
身份验证
要发送消息,应用服务器需发出 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 或纯文本消息中可能包含的所有参数列表,请参阅服务器参考。
检查服务器密钥的有效性
如果您在发送消息时收到身份验证错误,请检查服务器密钥的有效性。例如,在 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
带有负载的消息 — 通知消息
以下是一个通知消息:{ "notification": { "title": "Portugal vs. Denmark", "text": "5 to 1" }, "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..." }
您可以同时有通知消息和数据负载消息。请参阅服务器参考以了解通知负载所支持的密钥。有关通知消息和数据消息选项的详细信息,请参阅消息负载中的通知和数据。
带有负载的消息 — 数据消息
以下是带有数据负载的消息:{ "data": { "score": "5x1", "time": "15:10" }, "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..." }
以下是设置所有可选字段的消息:
{ "collapse_key": "score_update", "time_to_live": 108, "delay_while_idle": true, "data": { "score": "4x8", "time": "15:16.2342" }, "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..." }
以下是使用纯文本格式的同一条消息:
collapse_key=score_update&time_to_live=108&delay_while_idle=1&data.score=4x8&data.time=15:16.2342®istration_id=42
如果您的企业设有防火墙以限制向互联网发送或从其接收的流量,则需要将其配置为允许连接FCM才能让您的 Firebase Cloud Messaging客户端应用接收消息。要打开的端口为:5228、5229 和 5230。FCM通常仅使用 5228,但有时也会使用 5229 和 5230。FCM不提供具体的 IP,所以您的防火墙应设置为允许外部连接至 Google 15169 ASN 的封锁 IP 列表中包含的所有 IP 地址。
响应格式
尝试发送消息时可能有两种结果:消息处理成功。HTTP 响应有一个 200 状态,正文包含消息状态的详细信息。
FCM服务器拒绝请求。HTTP 响应包含一个非 200 状态代码(例如 400、401 或 5xx)。
当 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:
{ "multicast_id": 108, "success": 1, "failure": 0, "canonical_ids": 0, "results": [ { "message_id": "1:08" } ] }
或者,如果请求是纯文本格式:
id=1:08
以下是向 6 个接收者发送 JSON 消息的结果(ID 分别是 4、8、15、16、23 和 42),其中 3 条消息处理成功,返回 1 个规范注册令牌,还有 3 个错误:
{ "multicast_id": 216, "success": 3, "failure": 3, "canonical_ids": 1, "results": [ { "message_id": "1:0408" }, { "error": "Unavailable" }, { "error": "InvalidRegistration" }, { "message_id": "1:1516" }, { "message_id": "1:2342", "registration_id": "32" }, { "error": "NotRegistered"} ] }
在本例中:
第一条消息:成功,不需要。
第二条消息:应重新发送(至注册令牌 8)。
第三条消息:发生不可恢复错误(可能是数据库中的值已损坏)。
第四条消息:成功,不需做任何处理。
第五条消息:成功,但应更新服务器数据库中的注册令牌(从 23 更新为 32)。
第六条消息:应从服务器数据库中删除注册令牌 (42),因为应用已从设备中卸载。
如果仅有上面的第三条消息是以纯文本格式发送:
Error=InvalidRegistration
如果上面的第五条消息也是以纯文本格式发送:
id=1:2342 registration_id=32
实现 XMPP 连接服务器协议
Cloud Connection Server (CCS) 是一个 XMPP 终点,可向 Google 服务器提供持续的异步双向连接。连接可用于在服务器与已连接FCM的用户设备之间发送和接收消息。您可以继续使用 HTTP 请求机制向与使用 XMPP 的 CSS 并行的 Firebase Cloud Messaging服务器发送消息。CCS 的一些优点包括:
XMPP 的异步特性让您能够用更少的资源发送更多消息。
通信是双向的—不仅能让您的服务器向设备发送消息,还能让设备将消息返回您的服务器。
设备可利用接收消息所使用的相同连接返回消息,从而延长电池寿命。
有关所有消息参数以及可为其提供支持的连接服务器的列表,请参阅服务器参考。
建立连接
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,以避免通过测试连接发送来自生产通信的上游消息。
连接需要符合两个重要条件:
您必须启用传输层安全 (TLS) 连接。请注意,CCS 目前不支持 STARTTLS 扩展。
CCS 需要一个使用
<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 </gcm>
常规FCM消息的 JSON 负载类似于FCM http 终点使用的负载,不同之处在于:
不支持多个接收者。
使用
registration_ids代替
to。
CCS 添加字段
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" } </gcm> </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" } } </gcm> </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 } </gcm> </message>
响应格式
CCS 响应可能有三种形式。第一种是常规"ack"消息。但是,如果响应中包含错误,消息可能有两种不同形式,如下所述。
ACK 消息
以下是一个包含从 CCS 发送至应用服务器的 ACK/NACK 消息的 XMPP 节:<message id=""> <gcm xmlns="google:mobile:data"> { "from":"REGID", "message_id":"m-1366082849205" "message_type":"ack" } </gcm> </message>
NACK 消息
NACK 错误是一种常规 XMPP 消息,其中 message_type状态消息为"nack"。NACK 消息包含:
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" } </gcm> </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" } </gcm> </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" } </gcm> </message>
有关完整的 NACK 错误代码列表,请参阅服务器参考。除非另有说明,否则不能重试 NACK 消息。异常 NACK 错误代码的处理方式应与
INTERNAL_SERVER_ERROR相同。
节错误
在某些情况下也可能会发生节错误。节错误包含:节错误代码。
节错误描述(自由文本)。
例如:
<message id="3" type="error" to="123456789@gcm.googleapis.com/ABC"> <gcm xmlns="google:mobile:data"> {"random": "text"} </gcm> <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 } </gcm> </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" } </gcm> </message>
请注意以下事项:
将
"message_type"设置为
"receipt"。
将
"message_status"设置为
"MESSAGE_SENT_TO_DEVICE",表示设备已收到消息。请注意,在该例中,
"message_status"不是一个字段,而是数据负载的一部分。
回执消息 ID 包含原始消息 ID,但带有一个前缀
dr2:。应用服务器发送的
ACK 消息中必须含有此 ID,在本例中为
dr2:m-1366082849205。
原始消息 ID、设备注册令牌以及状态均包含在
"data"字段中。
如果 CCS 和设备之间的连接不稳定,Firebase Cloud Messaging可能会发送多个重复的送达回执。您可以安全地忽略这些重复回执。
流控制
发送至 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 处理显示通知负载,客户端应用处理数据负载。
注:当应用在后台运行时,如果您想要向 iOS 设备发送只包含自定义键值的消息,请在
data键中设置自定义键值对,并将
content_available设置为
true。
通知旨在为开发者提供一种简单的方法以发送带有预定义键和可选自定义键值对的用户可见显示消息。 数据负载仅包括开发者的自定义键值对,客户端应用必须处理该消息。
您可以发送包含通知和数据负载的消息。
通知
要发送通知,可设置 notification键并针对通知消息的用户可见部分设置必要的预定义键选项集。 例如,这是 IM 应用中的 JSON 格式的通知消息。
用户可能会在设备上看到标题为"Portugal vs. Denmark"、文本为"great match!"的消息:
{ "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", "notification" : { "body" : "great match!", "title" : "Portugal vs. Denmark", "icon" : "myicon" } }
应用在后台运行时,通知将会传递至通知托盘。 对于在后台运行的应用,消息由下列回调处理:
iOS 上的
didReceiveRemoteNotification:
Android 上的
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 格式消息:
{ "to" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...", "notification" : { "body" : "great match!", "title" : "Portugal vs. Denmark", "icon" : "myicon" }, "data" : { "Nick" : "Mario", "Room" : "PortugalVSDenmark" } }
不可折叠和可折叠消息
不可折叠消息表示每一条消息都将被传递至设备。 不可折叠消息可传递一些有用内容至手机应用,从而联系服务器以获取数据,这与"ping"相反。 除了通知消息以外(始终是可折叠消息),其他全部默认为不可折叠消息。 FCM 不保证传递顺序。聊天消息或关键消息都是典型的不可折叠消息。 例如,在 IM 应用中,您可能想要传递每一条消息,因为它们的内容各不相同。
不可折叠消息最多可存储 100 条。达到此限值后所有存储的消息都将被丢弃。 当设备重新上线后,将收到一条特殊消息,提示已达到此限值。 之后,应用可以正常处理该状况,一般情况下会请求从应用服务器完全同步。
可折叠消息是一种可替换为包含相同折叠键的新消息的消息,前提是其还未被传递至设备。
两种常见的可折叠消息是"发送至同步"消息和通知。 "发送至同步"消息是一个"ping",它会告诉移动应用从服务器同步数据。 为用户更新最新比分的运动应用就是这种消息的示例。
仅有最近的消息才会被关联。
FCM 允许每台设备的应用服务器在任意指定时间内最多使用 4 个不同的折叠键。 也就是说, FCM 连接服务器可以同时存储 4 条不同的可折叠"发送至同步"消息,每一条都含有不同的折叠键。
如果超出此限值, FCM 将仅保留 4 个折叠键,具体保留哪个不一定。
注: 在 iOS 上,应用服务器需要发送"发送至同步"消息时设置
content_available。
非活动客户端应用将在后台执行您的逻辑,同时,前台的应用会将消息传递至
didReceiveRemoteNotification:。
我应使用哪一种?
从性能的角度来看,可折叠消息是更好的选择,但前提是您的应用不需要使用不可折叠消息。 但是,如果您使用可折叠消息,须切记: FCM 仅允许每个注册令牌的 FCM 连接服务器在任意指定时间内最多使用 4 个不同的折叠键。您不得超出此限值,否则将导致出现意外后果。
使用情景 | 发送方法 | |
---|---|---|
不可折叠 | 每一条消息对客户端应用都很重要,它们都需要进行传递。 | 除了通知消息以外,其他全部默认为不可折叠消息。 |
可折叠 | 当有更新消息呈现旧的相关消息且与客户端应用毫不相关时, FCM 将替换旧消息。 例如: "发送至同步"消息或过期通知。 | 设置 collapse_key参数。 |
设置消息优先级
下游消息的传递优先级有两种: 普通优先级和高优先级。普通优先级和高优先级的消息传递方式如下:普通优先级。消息传递默认为普通优先级。 普通优先级消息不会让睡眠中的设备打开网络连接,为了省电,它们可能会被延迟传递。 对于时间不太敏感的消息,例如新电子邮件通知或其他要同步的数据,可选择普通传递优先级。
高优先级。FCM 会立即尝试传递高优先级消息,以允许 FCM 服务在可能的情况下唤醒睡眠中的设备并打开与应用服务器的网络连接。
例如,带有即时通讯、聊天或语音通话提醒功能的应用通常需要打开网络连接并确保 FCM 及时将消息传递给设备。
只有在消息属于时间关键型且需要用户立刻交互时才能设置为高优先级,但请注意,将消息设置为高优先级会比普通优先级耗费更多电池电量。
有效值为
normal和
high。如需了解更多详情,请参阅
HTTP</a> 或 <a href="/docs/cloud-messaging/xmpp-server-ref.html#priority">XMPP</a> 的服务器参考。
对于 iOS 客户端应用,普通和高优先级类似于 APNs 的 5 至 10 优先级。 有关 iOS 特定行为完整的详细说明,请参阅APNs
文档。 有关 Android 特定行为的详细说明,请参阅对打盹模式和应用待机模式进行针对性优化。
以下是一个用于通知杂志订阅者有新内容可以下载的普通优先级消息示例:
{ "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", "priority" : "normal", "notification" : { "body" : "This week's edition is now available.", "title" : "NewsMagazine.com", "icon" : "new", }, "data" : { "volume" : "3.21.15", "contents" : "http://www.news-magazine.com/world-week/21659772" } }
设置消息寿命
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 格式的请求示例:
{ "collapse_key" : "demo", "delay_while_idle" : true, "to" : "xyz", "data" : { "key1" : "value1", "key2" : "value2", }, "time_to_live" : 3 },
目前,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 语法的参考信息。参数和选项分为以下几个大类:下游消息语法
下游消息错误响应代码
下游消息语法
本部分介绍发送下游消息和从 Firebase Cloud Messaging解释 HTTP 响应所使用的语法。
下游 HTTP 消息 (JSON)
下表列出了 HTTP JSON 消息的目标、选项和负载。有关下游消息传递的详细信息,请参阅简单下游消息传递表 1. 下游 HTTP 消息 (JSON) 的目标、选项和负载。
参数 | 用法 | 说明 |
---|---|---|
目标 | ||
to | 可选,字符串 | 此参数用于指定消息的接收者。 值必须为注册令牌、通知键或主题。请不要在发送至多个主题时设置此字段。请参阅 condition。 |
registration_ids | 字符串数组 | 此参数用于指定一系列接收多播消息的设备(注册令牌或 ID)。其中必须包含至少 1 个、最多 1000 个注册令牌。 仅可以将此参数用于多播消息传递,而不可以用于单一接收者。仅允许使用 HTTP JSON 格式进行多播消息传递(发送至 1 个以上的注册令牌)。 |
condition | 可选,字符串 | 此参数用于指定确定消息目标条件的逻辑表达式。 支持的条件:主题,采用"‘您的主题’在主题中"格式。此值不区分大小写。 支持的运算符: &&、 ||。每个主题消息最多支持两个运算符。 |
notification_key 已弃用 | 可选,字符串 | 此参数已被弃用。应使用 to指定消息的收件人。有关如何使用 to向多个设备发送消息的详细信息,请参阅设备群组消息传递。 |
选项 | ||
collapse_key | 可选,字符串 | 此参数用于指定一组可折叠的消息(例如含有 collapse_key: "Updates Available"),因此当恢复传递时只有最后一条消息被送出。这是为了避免当设备重新上线或活动时重复发送过多相同的消息(请参阅 delay_while_idle)。 请注意,消息发送顺序并不固定。 注:在任意指定时间内最多允许 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时,表示只能在设备变为活动状态后发送消息。 默认值为 false。 |
time_to_live | 可选,JSON 数值 | 此参数用于指定当设备离线时消息在FCM存储中保留的时长(单位:秒)。受支持的最长生存时间为 4 周,默认值为 4 周。如需了解详细信息,请参阅设置消息寿命。 |
restricted_package_ name | 可选,字符串 | 此参数用于指定应用的数据包名称,其注册令牌必须匹配才能接收消息。 |
dry_run | 可选,JSON 布尔值 | 此参数设置为 true时,允许开发者测试请求,无需实际发送消息。 默认值为 false。 |
负载 | ||
data | 可选,JSON 对象 | 此参数用于指定消息负载的自定义键值对。 (例如,使用 data:{"score":"3x1"}:) 在 iOS 上,如果通过 APNs 发送消息,它代表自定义数据字段。如果通过FCM连接服务器发送,其在 AppDelegate application:didReceiveRemoteNotification:中将表示为键值字典。 在 Android 中上,这会产生一个名为 score、字符串值为 3x1的 Intent extra。 键不能是保留字("from"或以"google"或"gcm"开头的任何字)。不要使用该表中已确定的任何字(例如 collapse_key)。 推荐使用字符串类型中的值。您必须将对象中的值或其他非字符串数据类型(例如整数或布尔值)转换成字符串。 |
notification | 可选,JSON 对象 | 此参数用于指定通知负载的用户可见预定义键值对。有关详情,请参阅通知负载支持。有关通知消息和数据消息选项的详细信息,请参阅负载。 |
通知负载支持
下表列出了通知消息中可使用的预定义参数。表 2. 按平台分类的通知消息传递参数
参数 | 平台 | 用法 | 说明 |
---|---|---|---|
title | iOS (watch)、Android | 必选 (Android),可选 (iOS),字符串 | 指示通知标题。该字段在 iOS 手机和平板电脑上不可见。 |
body | iOS、Android | 可选,字符串 | 指示通知正文。 |
icon | Android | 必选,字符串 | 指示通知图标。将可绘制资源 myicon的值设为 myicon。 |
sound | iOS、Android | 可选,字符串 | 指示设备收到通知时要播放的声音。支持 default或应用中捆绑的声音资源的文件名。 Android 声音文件必须位于 /res/raw/中,而 iOS 声音文件既可以位于客户端应用的主捆绑包中,也可以位于应用数据容器的 Library/Sounds文件夹中。如需了解详细信息,请参阅 iOS 开发者内容库。 |
badge | iOS | 可选,字符串 | 指示客户端应用首页图标上的标志。 |
tag | Android | 可选,字符串 | 指示每一条通知是否会导致在 Android 上的通知抽屉式导航栏中产生新条目。 如未设置此参数,每次请求时将创建一个新的通知。 如果已设置此参数,且已显示带有相同标记的通知,则新通知将替换通知抽屉式导航栏中的现有通知。 |
color | Android | 可选,字符串 | 指示图标颜色,以 #rrggbb 格式表示 |
click_action | iOS、Android | 可选,字符串 | 指示与用户点击通知相关的操作。 如果在 iOS 中设置此参数,则它对应于 APNs 负载中的 category。 在 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 消息(纯文本)
下表列出了纯文本下游 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.<key> | 可选,字符串 | 此参数用于指定消息负载的键值对。键值参数没有数量限制,但是消息总大小不得超过 4kb。 例如,在 Android 中, "data.score"."3x1"会产生一个名为 score、字符串值为 3x1的 Intent extra。 键不能是保留字("from"或以"google"或"gcm"开头的任何字)。不要使用该表中已确定的任何字(例如 collapse_key)。 |
解释下游消息响应
应用服务器应评估消息响应标头和正文以解释通过FCM发送的消息响应。下表介绍可能的响应。表 4. 下游 HTTP 消息响应标头。
响应 | 说明 |
---|---|
200 | 消息处理成功。响应正文包含有关消息状态的详细信息,但其格式取决于请求是 JSON 格式还是纯文本格式。有关详情,请参阅表 5。 |
400 | 仅适用于 JSON 请求。表示请求不能作为 JSON 进行分析,或其包含无效的字段(例如,传递带有预期数字的字符串)。详细的故障原因位于响应中,应先解决故障方可重试请求。 |
401 | 验证发送者帐户身份时出错。 |
5xx | 错误代码在 500-599 范围之间(例如 500 或 503)表示在尝试处理请求时,FCM连接服务器发生内部错误,或服务器暂时不可用(例如,由于超时原因)。发件人必须服从响应中的任何 Retry-After标头,稍后重试。应用服务器必须实现指数回退。 |
表 5. 下游 HTTP 消息响应正文 (JSON)。
参数 | 用法 | 说明 |
---|---|---|
multicast_id | 必选,数字 | 用于识别多播消息的唯一 ID(数字)。 |
success | 必选,数字 | 处理时未出错的消息数。 |
failure | 必选,数字 | 无法处理的消息数。 |
canonical_ids | 必选,数字 | 包含规范注册令牌的结果数。有关此主题的详细介绍,请参阅注册概览。 |
results | 可选,数组对象 | 代表已处理消息状态的对象数组。对象的排列顺序与请求相同(即,对于请求中的每一个注册 ID,其结果的列出顺序与响应中的索引顺序相同)。message_id:字符串,用于指定每个成功处理的消息的唯一 ID。 registration_id:可选字符串,用于指定处理和接收消息的客户端应用的规范注册令牌。发件人应使用此值作为未来请求的注册令牌。否则,消息可能被拒绝。 error:字符串,用于指定处理收件人的消息时发生的错误。可能出现的值位于表 9中。 |
参数 | 用法 | 说明 |
---|---|---|
message_id | 可选,数字 | 当FCM成功接收到请求并尝试传递至所有订阅设备时的主题消息 ID。 |
error | 可选,字符串 | 处理消息时发生的错误。可能出现的值位于表 9中。 |
参数 | 用法 | 说明 |
---|---|---|
id | 必选,字符串 | 此参数用于指定FCM连接服务器成功处理的唯一消息 ID。 |
registration_id | 可选,字符串 | 此参数用于指定处理和接收消息的客户端应用的规范注册令牌。发件人应在未来请求中将注册标令牌替换为该值;否则消息可能会被拒绝。 |
参数 | 用法 | 说明 |
---|---|---|
Error | 必选,字符串 | 此参数用于指定处理接收者消息时的错误值。有关详情,请参阅表 9。 |
下游消息错误响应代码
下表列出了下游消息的错误响应代码。表 9. 下游消息错误响应代码。
错误 | HTTP 代码 | 推荐操作 |
---|---|---|
缺少注册令牌 | 200 + error:MissingRegistration | 检查请求中是否包含一个注册令牌(在纯文本消息中的 registration_id中,或在 JSON 中的 to或 registration_ids字段中)。 |
无效注册令牌 | 200 + error:InvalidRegistration | 检查您传送至服务器的注册令牌格式。确保其匹配客户端应用在注册 Firebase 通知时获得的注册令牌。不能截断或添加其他字符。 |
未注册设备 | 200 + error:NotRegistered | 现有注册令牌可能在很多情况下失效,包括: 如果客户端应用未注册FCM。 如果客户端应用自动撤销注册,这可能在用户卸载应用时发生。例如,在 iOS 上,APNs Feedback Service 报告 APNs 令牌为无效。 如果注册令牌过期(例如 Google 可能决定更新注册令牌,或 iOS 设备的 APNs 令牌过期)。 如果客户端应用更新,但新版本未配置为接收消息。 对于所有这些情况,从应用服务器中删除此注册令牌,停止用其发送消息。 |
无效的软件包名称 | 200 + error:InvalidPackageName | 确保消息寻址至软件包名称与请求中传递的值相匹配的注册令牌。 |
身份验证错误 | 401 | 无法对用于发送消息的发送者帐户进行身份验证。可能原因有: 身份验证标头丢失或 HTTP 请求中使用了无效的语法。 发送作为密钥的项目编号无效。 密钥有效,但禁用了FCM服务。 从服务器发出的请求不在服务器 API 密钥 IP 白名单中。 检查您在身份验证标头内部发送的令牌是与您的项目关联的正确的服务器密钥。有关详情,请参阅检查服务器密钥的有效性。 |
不匹配的发送者 | 200 + error:MismatchSenderId | 注册令牌关联至某一组发送者。当客户端应用注册FCM时,必须指定允许哪些发送者发送消息。当向客户端应用发送消息时,您应使用这些发送者 ID 之一。如果您切换到不同的发送者,现有注册令牌不会起作用。 |
无效 JSON | 400 | 检查 JSON 消息格式正确,且包含有效字段(例如确保传入正确的数据类型)。 |
消息过大 | 200 + error:MessageTooBig | 确保消息中包含的负载数据的总大小不超过FCM的限制:大多数消息的上限是 4096 字节,如果是 iOS 上的标题或通知消息,上限是 2048 字节。这包括键和值。 |
无效的数据密钥 | 200 + error: InvalidDataKey | 确保负载数据不包含FCM内部使用的密钥(例如 from、 gcm,或任何以 collapse_key)也会被 FCM 使用,但允许包含在负载中,在这种情况下负载值将被 FCM 值覆盖。 |
无效的生存时间 | 200 + error:InvalidTtl | 检查 time_to_live中使用的值是代表 0 至 2,419,200 秒(4 周)之间的一段时间(单位:秒)的整数。 |
超时 | 5xx 或 200 + error:Unavailable | 服务器无法及时处理请求。重试相同请求,但必须: 服从 Retry-After标头,如果其包含在FCM连接服务器发出的响应中。 在您的重试机制中实现指数后退。(例如,如果等待一秒钟后进行第一次重试,则至少要等待两秒钟再进行下一次重试,然后等待 4 秒钟,依此类推)。如果您要发送多条消息,以额外随机数量独立延迟每个消息,从而避免同时对所有消息发布新的请求。 导致故障风险的发件人将被列入黑名单。 |
内部服务器错误 | 500 或 200 + error:InternalServerError | 服务器在尝试处理请求时遇到错误。您可按照"超时"中的要求重试相同请求(参见上一行)。如果错误仍然存在,请在 android-gcm group中报告错误。 |
超出设备消息率 | 200 + error: DeviceMessageRate Exceeded | 到特定设备的消息率过高。减少发送到此设备的消息数,且不要立即重试向此设备发送消息。 |
超出主题消息率 | 200 + error: TopicsMessageRate Exceeded | 发送给某特定主题订阅者的消息率过高。减少为此主题发送的消 |
相关文章推荐
- firebase推送 修改系统默认notification样式(稀有)
- 接入谷歌Admob,Firebase所踩的坑
- Progressive Web Apps(PWA)核心技术-使用Firebase Cloud Messaging实现推送通知
- Unity3D-使用Firebase中的云消息推送
- Google FireBase - fcm 推送 (Cloud Messaging)
- firebase基础(一)<推送服务调研>
- Unity3D-接入谷歌的Firebase(iOS,Mac端)
- Google FCM推送(Firebase Cloud Messaging)
- google firebase推送之大坑记录
- 使用 FCM 关于推送无法接收的问题(Firebase 推送)
- Firebase介绍(只管写代码,后台交给Firebase)
- firebase database limit
- GoogleAnalytics与FirebaseCloudMessage同时使用
- [转载+翻译]实时数据服务,firebase介绍
- 使用Firebase介绍,附带聊天实现的功能code地址
- Error:(25, 13) Failed to resolve: com.google.firebase:firebase-core:9.0.2
- 使用Firebase前的基础设置
- firebase messaging - Register for remote notification