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_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
带有负载的消息 — 通知消息
以下是一个通知消息:
{ "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
,则从服务器数据库中删除注册令牌。 - 否则,可能会发生不可恢复的错误(注意:纯文本请求永远不会返回错误代码
Unavaila
- 如果值为