如何删除已发送至终端用户的FCM消息(仿Messenger功能)
如何从服务器端撤回已送达的FCM消息?
FCM本身没有原生API可以直接删除用户设备上已展示的通知,要实现类似Messenger的消息撤回效果,必须通过服务器与客户端协同的方式来完成,具体方案如下:
核心思路
给每条可撤回的消息分配唯一标识,发送时同步到客户端;触发撤回时,服务器发送撤回指令,客户端根据标识找到对应通知并删除,同时更新本地数据。
具体实现步骤
1. 发送初始消息时携带唯一标识
发送FCM消息时,不要用notification字段让FCM直接推送通知,而是用data字段传递消息内容,同时附带一个自定义的唯一message_id(比如UUID)。示例请求体:
{ "to": "目标设备的FCM Token", "data": { "message_id": "msg_20240520_1030_001", "content": "这是一条可撤回的消息", "msg_type": "normal" } }
客户端收到data消息后,自行构建本地通知,同时将message_id与该通知的本地标识(Android的Notification ID、iOS的UNNotificationRequest ID)绑定,存入本地存储(比如Android的SharedPreferences、iOS的CoreData)。
2. 服务器发送撤回指令
当需要撤回消息时,服务器向目标设备发送一条类型为revoke的FCM指令消息,携带要撤回的target_message_id:
{ "to": "目标设备的FCM Token", "data": { "msg_type": "revoke", "target_message_id": "msg_20240520_1030_001" } }
3. 客户端执行撤回操作
- Android端:收到撤回指令后,通过
target_message_id从本地存储找到对应的Notification ID,调用NotificationManager.cancel(notificationId)删除该通知;同时更新本地聊天记录,将原消息标记为「已撤回」。 - iOS端:收到撤回指令后,通过
target_message_id找到对应的UNNotificationRequest ID,调用UNUserNotificationCenter.removeDeliveredNotifications(withIdentifiers: [notificationId])删除已展示的通知;同步更新本地聊天数据。
额外注意点
- 如果用户设备离线,撤回指令会在设备上线后被接收,此时再执行删除操作。
- 若目标通知已被用户手动清除,客户端只需更新本地聊天记录,无需处理通知删除。
- 务必保证本地存储的
message_id与通知标识的映射关系准确,避免误删其他通知。
内容的提问来源于stack exchange,提问作者flutroid
相关产品推荐
相关产品推荐

