如何用PHP FCM同时处理Android和iOS的不同通知Payload?
解决FCM跨平台Payload适配:让Android从Data字段处理通知需求
我之前也踩过FCM跨平台推送的这个坑,核心就是要搞清楚FCM两种消息类型的差异,然后针对性构造Payload,既能满足iOS的推送触发要求,又能让Android完全通过Data字段处理逻辑。
先理清楚核心差异
FCM的消息分两种类型:
- 通知消息(Notification Payload):由FCM SDK自动处理,Android/iOS都会直接弹出系统通知,适合不需要自定义逻辑的场景,但你现在Android端不想用这个字段,所以得绕开它的自动处理。
- 数据消息(Data Payload):完全交给应用自己处理,FCM不会自动展示通知,所有逻辑由开发者实现——这正是你Android端需要的模式。但iOS有个限制:应用在后台/未启动时,纯Data消息不会触发系统推送,必须搭配Notification字段才能唤醒推送。
解决方案:构造混合Payload
我们可以构造一个同时包含notification和data字段的混合Payload:
- 给iOS用
notification字段:确保后台状态下能触发系统推送 - 给Android和iOS前台用
data字段:所有自定义逻辑都基于这个字段处理,Android完全忽略notification字段即可
PHP发送FCM的代码示例
<?php // FCM服务器密钥,从Firebase控制台获取 $serverKey = 'YOUR_FCM_SERVER_KEY'; // 目标设备的FCM令牌(可以是单个令牌,也可以是数组批量发送) $deviceToken = 'TARGET_DEVICE_TOKEN'; // 构造Payload $payload = [ 'to' => $deviceToken, // 给iOS后台用的通知字段,Android可以忽略 'notification' => [ 'title' => '通知标题', 'body' => '通知内容', 'sound' => 'default' // iOS需要这个字段触发声音 ], // 核心数据字段,Android和iOS前台都从这里取数据处理 'data' => [ 'custom_title' => '自定义标题', 'custom_content' => '自定义内容', 'target_screen' => 'home', // 比如跳转目标页面 'any_other_key' => '自定义数据' ] ]; // 发送请求到FCM API $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: key=' . $serverKey, 'Content-Type: application/json' ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); $response = curl_exec($ch); curl_close($ch); // 打印响应结果,方便调试 echo $response; ?>
Android端处理逻辑(忽略Notification字段,只处理Data)
在你的FirebaseMessagingService子类中,直接从remoteMessage.getData()获取数据,不管notification字段:
class MyFirebaseMessagingService : FirebaseMessagingService() { override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) // 直接获取Data字段的所有数据 val data = remoteMessage.data val customTitle = data["custom_title"] val customContent = data["custom_content"] val targetScreen = data["target_screen"] // 这里写你的自定义逻辑:比如弹出自定义通知、跳转页面等 showCustomNotification(customTitle, customContent, targetScreen) } private fun showCustomNotification(title: String?, content: String?, targetScreen: String?) { // 实现你自己的通知构建逻辑,比如用NotificationCompat.Builder // 示例代码省略,根据你的需求实现即可 } }
注意:如果Android应用在后台收到混合消息,FCM会自动展示
notification字段的通知,但点击通知时,data字段的数据会通过Intent传递到启动的Activity,你可以在Activity的onCreate或onNewIntent中获取这些数据:val data = intent.extras val customTitle = data?.getString("custom_title")
iOS端适配说明
iOS端需要根据应用状态处理:
- 前台状态:在
AppDelegate的didReceiveRemoteNotification方法中获取userInfo里的data字段处理 - 后台/点击通知:在
didReceiveNotificationResponse方法中获取notification.request.content.userInfo里的data字段处理
这样一套下来,Android端完全基于Data字段处理逻辑,iOS端也能正常接收推送并处理自定义数据,完美解决你的需求。
内容的提问来源于stack exchange,提问作者ken
相关产品推荐
相关产品推荐

