Ionic 3应用完全重启后无法接收Push Notification问题求解
问题产生原因
本地通知由iOS系统本地调度触发,完全不依赖APNs(苹果推送通知服务)链路,由独立插件维护初始化逻辑,因此不会受远程推送注册故障影响。重启后Push Notification失效、重开权限才恢复的问题,根源集中在3个常见实现缺陷:
- 推送初始化逻辑位置错误:多数实现会把远程推送注册、token上报逻辑写在「用户首次同意推送权限」的回调分支里。iOS的推送权限弹窗只会在应用安装后第一次触发,*冷启动(完全杀掉应用后重新打开)*时不会再次触发该回调,直接导致推送实例根本没有完成初始化,自然无法接收消息。手动开关一次推送权限,会强制触发系统的推送注册回调,让遗漏的初始化逻辑跑通,功能暂时恢复,直到下次冷启动再次失效。
- 插件版本兼容bug:Ionic 3生态默认配套的
phonegap-plugin-push(对应@ionic-native/pushv4版本)在2.2.0及更早版本存在已知缺陷:应用冷启动时,如果检测到用户已经授予推送权限,不会主动向APNs服务发起注册请求,既无法和APNs建立推送长连接,也拿不到当前会话有效的设备token。 - token上报逻辑缺失:不少实现只会在用户首次授权时把APNs设备token上报给业务推送后端,实际上iOS在系统升级、应用重装、冷启动后APNs刷新会话等场景下会更新设备token,如果冷启动后没有触发上报,后端持有的是失效旧token,推送消息无法下发到设备。
对应修复方案
- 调整推送初始化触发时机:把推送实例初始化逻辑从权限申请回调中移到根组件的
platform.ready()生命周期内,保证每次应用冷启动都会执行推送初始化,不依赖权限弹窗回调。参考代码片段:
// app.component.ts 内 import { Push, PushObject, PushOptions } from '@ionic-native/push'; constructor(private platform: Platform, private push: Push) { this.platform.ready().then(() => { this.initPushNotification(); // 平台准备完成后立刻初始化,不做权限状态前置判断 }); } initPushNotification() { const options: PushOptions = { ios: { alert: 'true', badge: true, sound: 'false' } }; const pushObject: PushObject = this.push.init(options); // 监听注册事件,冷启动、重新授权时只要拿到有效token就立刻上报后端,不要依赖本地缓存判断 pushObject.on('registration').subscribe((data: any) => { // 此处写token上报到业务后端的逻辑,每次触发都覆盖后端存储的旧token console.log('Got valid APNs token:', data.registrationId); }); pushObject.on('notification').subscribe((notification: any) => { // 推送消息接收、展示逻辑 }); pushObject.on('error').subscribe(error => console.error('Push Error:', error)); }
- 升级修复了兼容bug的插件版本:移除存在冷启动注册缺陷的旧版本推送插件,安装稳定适配版本,在项目根目录执行以下命令:
ionic cordova plugin remove phonegap-plugin-push ionic cordova plugin add phonegap-plugin-push@2.3.0 --variable SENDER_ID="local-test" npm install @ionic-native/push@4.20.0 # 安装Ionic 3兼容的native封装版本
- 补全iOS项目配置:在Xcode中打开项目,开启
Background Modes能力下的Remote notifications选项;同时在项目根目录的config.xml中添加以下配置,保证应用冷启动时可以在后台完成APNs注册流程:
<platform name="ios"> <preference name="PushNotifications" value="true" /> <config-file parent="UIBackgroundModes" target="*-Info.plist"> <array> <string>remote-notification</string> </array> </config-file> </platform>
- 增加冷启动权限校验逻辑:初始化推送前主动查询当前权限状态,如果已经获得授权,主动触发一次注册校验,避免插件状态异常:
// 放在initPushNotification方法开头即可 this.push.hasPermission().then((res: any) => { if (res.isEnabled) { console.log('Push permission valid, start APNs registration'); } });
内容的提问来源于stack exchange,提问作者Terry Windwalker
相关产品推荐
相关产品推荐

