如果您的应用服务器实现了 XMPP 连接服务器协议,则可接收从用户设备发送至云端的上行消息。如需发起一条上行消息,客户端应用需要发送一个包含以下信息的请求:
- 以
SENDER_ID@fcm.googleapis.com
格式表示的接收应用服务器的地址。 - 对每个发送者 ID 唯一的消息 ID。
- 包含消息载荷键值对的消息数据。
接收到此数据时,FCM 会构建一个 XMPP Stanza 发送至应用服务器,并添加关于发送设备和应用的某些额外信息。
从 Android 客户端应用发送上行消息
Android 应用能使用 FirebaseMessaging.send 发送上行消息。
Kotlin+KTX
val fm = Firebase.messaging fm.send( remoteMessage("$SENDER_ID@fcm.googleapis.com") { setMessageId(messageId.toString()) addData("my_message", "Hello World") addData("my_action", "SAY_HELLO") }, )
Java
FirebaseMessaging fm = FirebaseMessaging.getInstance(); fm.send(new RemoteMessage.Builder(SENDER_ID + "@fcm.googleapis.com") .setMessageId(Integer.toString(messageId)) .addData("my_message", "Hello World") .addData("my_action","SAY_HELLO") .build());
处理上行消息回调
借助 FirebaseMessaging
,您可以实现 onMessageSent
和 onSendError
回调函数以检查上行消息的状态。发生错误时,onSendError
会返回一个带有错误代码的 SendException
。例如,如果客户端在达到消息上限(20 条)后尝试发送更多消息,该回调函数会返回 SendException#ERROR_TOO_MANY_MESSAGES
。
当设备处于离线状态或 FCM 服务无法将上行消息转发到您的服务器时,Android 客户端应用实例最多可累积 20 条待处理消息。如果此类消息在 FCM 将其成功发送前到期,onSendError
将返回 SendException#ERROR_TTL_EXCEEDED
。
为了优化网络使用,FCM 会批量响应 onMessageSent
和 onSendError
,因此可能不会立即确认每条消息。
在应用服务器上接收 XMPP 消息
当 FCM 从客户端应用收到上行消息调用时,会生成一个必要的 XMPP Stanza,以用于发送上行消息。FCM 会添加 category
和 from
字段,然后向应用服务器发送一个类似以下格式的 Stanza:
<message id=""> <gcm xmlns="google:mobile:data"> { "category":"com.example.yourapp", // to know which app sent it "data": { "hello":"world", }, "message_id":"m-123", "from":"REGID" } </gcm> </message>
发送 ACK 消息
为响应上述上行消息,应用服务器必须使用同一连接发送一条包含该唯一消息 ID 的 ACK 消息。如果 FCM 未接收到 ACK 消息,可能会重新尝试向应用服务器发送消息。
<message id=""> <gcm xmlns="google:mobile:data"> { "to":"REGID", "message_id":"m-123" "message_type":"ack" } </gcm> </message>
如需详细了解上行消息语法,请参阅 XMPP 连接服务器参考文档。