Ionic FCM后台点击通知无法跳转指定页面及接收数据问题
嘿,我之前也踩过这个后台点击通知跳转的坑,咱们一步步来排查解决!
首先得搞清楚:当APP处于后台时,FCM通知是由系统托盘接管处理的,这时候你的onNotification订阅逻辑需要区分前台接收和后台点击唤醒两种场景,同时后端的FCM payload格式也得配对,不然系统不知道该怎么唤醒你的APP到指定页面。
第一步:检查Laravel端的FCM Payload格式
后端发送的通知必须包含两个关键部分:notification(系统托盘显示的内容)和data(自定义跳转数据),还要加上针对安卓/iOS的特殊配置:
$token = '用户的FCM Token'; // 系统托盘显示的通知内容 $notification = [ 'title' => '新通知', 'body' => '点击查看详情', 'click_action' => 'FCM_PLUGIN_ACTIVITY', // 安卓必须加这个,指定唤醒的Activity 'sound' => 'default' ]; // 自定义跳转数据,这里放你要跳转的页面路径 $data = [ 'target_route' => '/order/detail/123', 'order_id' => 123 // 额外携带的数据 ]; $fields = [ 'to' => $token, 'notification' => $notification, 'data' => $data, 'priority' => 'high', // 确保后台能收到通知 'content_available' => true // iOS必须加,允许后台唤醒APP ]; // 用Laravel FCM包发送 \Notification::send($notifiable, new \App\Notifications\FcmNotification($fields));
重点提醒:
- 安卓的
click_action必须设置为FCM_PLUGIN_ACTIVITY,这是Ionic FCM插件约定的Activity名称,不然系统点击通知后不知道要打开哪个页面。 - iOS的
content_available设为true,才能让APP在后台收到点击事件。
第二步:调整Ionic端的通知点击处理逻辑
你现在的代码没有区分wasTapped状态——这个属性是关键!当用户点击后台通知唤醒APP时,wasTapped会是true;前台收到通知时是false。
修改你的订阅代码:
import { NavController } from '@ionic/angular'; import { FCM } from '@ionic-native/fcm/ngx'; constructor(private fcm: FCM, private navCtrl: NavController) {} // 最好在app.component.ts的initializeApp里初始化 initializeApp() { this.platform.ready().then(() => { this.setupNotificationHandling(); }); } setupNotificationHandling() { this.fcm.onNotification().subscribe(data => { console.log('通知数据:', data); // 判断是后台点击唤醒,还是前台收到通知 if (data.wasTapped) { // 后台点击通知进来的场景:执行跳转 console.log('用户点击了后台通知'); // 用NavController跳转到指定页面,这里用你之前定义的target_route this.navCtrl.navigateForward(data.target_route); } else { // 前台收到通知的场景:可以显示弹窗或者直接跳转 console.log('前台收到通知'); // 可选:比如显示一个提示框,或者直接跳转 // this.navCtrl.navigateForward(data.target_route); } }); }
如果你的项目用的是Angular Router,把navCtrl.navigateForward换成router.navigate([data.target_route])就行。
第三步:安卓Manifest配置(必做)
确保你的安卓MainActivity包含FCM_PLUGIN_ACTIVITY的intent-filter,这样系统点击通知后能正确唤醒你的APP:
打开platforms/android/app/src/main/AndroidManifest.xml,找到MainActivity的标签,添加:
<intent-filter> <action android:name="FCM_PLUGIN_ACTIVITY" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter>
或者更规范的方式是在config.xml里配置,这样下次更新平台时不会被覆盖:
<platform name="android"> <edit-config file="AndroidManifest.xml" target="/manifest/application/activity[@android:name='MainActivity']/intent-filter" mode="merge"> <intent-filter> <action android:name="FCM_PLUGIN_ACTIVITY" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </edit-config> </platform>
第四步:iOS后台模式配置(必做)
打开Xcode,找到你的项目,进入Signing & Capabilities -> Background Modes,勾选Remote notifications,这样iOS才允许APP在后台处理通知点击事件。
最后测试
重新打包APP(不要用livereload,因为后台通知需要原生环境),发送测试通知,然后把APP切到后台,点击通知,应该就能跳转到指定页面啦!
内容的提问来源于stack exchange,提问作者Abhishek

