必须在App.vue的onLaunch中注册plus.push.addEventListener("click", handler),因冷启动时仅此时机能确保监听器挂载;msg.payload为字符串需JSON.parse且判空,冷启动时应结合本地缓存或服务端记录兜底跳转。

plus.push.addEventListener("click") 必须在 onLaunch 里注册
应用冷启动时,onLaunch 是唯一能确保监听器被及时挂载的时机。如果放在某个页面的 onLoad 或 mounted 中,用户点击通知时 App 尚未加载该页面,事件就彻底丢失了。
常见错误现象:console.log 看不到点击日志,或只在热启动时生效,冷启动点击无反应。
- 必须在
App.vue的onLaunch生命周期中调用plus.push.addEventListener("click", handler) - 不要在
onShow或其他页面钩子中重复注册,否则可能触发多次回调 - HBuilderX 3.5.1+(UniPush 2.0)仍沿用此机制,兼容性无变化
透传消息的 payload 在 click 事件里直接可用
厂商通道或个推下发的透传消息,其业务数据都封装在 msg.payload 中,无需额外解析。但要注意:这个 payload 是字符串,不是自动 JSON 解析后的对象。
典型错误写法:if (msg.payload.type === 'order') —— 会报 Cannot read property 'type' of undefined,因为 msg.payload 还是原始字符串。
- 正确做法:先
JSON.parse(msg.payload),并加try/catch - 华为通道下发的透传内容,
msg.payload可能是空字符串或"{}",需判空 - 小米/OPPO 厂商通道有时会把 payload 打包进
msg.extra字段,此时应优先检查msg.extra
冷启动时 msg 来源不可靠,需结合 cid + 后端记录做兜底
Android 冷启动点击后,msg 对象可能为空、字段缺失,或 payload 丢失(尤其在华为 EMUI 12+ 和小米 HyperOS 上)。不能只依赖前端拿到的 msg 跳转。
真实场景下,用户点击通知后进入首页,但你根本不知道他点的是哪条订单提醒——因为 msg 没传过来。
- 方案一:App 启动时立即查本地缓存(如
uni.getStorageSync('last_push')),该缓存由receive事件写入 - 方案二:服务端在推送时同步写一条「待处理跳转记录」,含
cid和payload,App 冷启动后主动拉取一次 - 避免把跳转逻辑全押在
click回调里,这是多数线上崩溃和跳转失败的根源
华为手机要额外处理自启动和通知权限
即使 click 监听注册成功,华为设备仍大概率收不到点击事件——因为系统杀死了 push 进程。这不是代码 bug,而是权限链断裂。
表现就是:通知栏有消息,点击后黑屏或直接回到桌面,click 回调完全不触发。
- manifest.json 中必须显式声明自启动权限:
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"></uses-permission> - 首次启动时,需调用
plus.android.requestPermissions主动申请「受保护的权限」,包括REQUEST_IGNORE_BATTERY_OPTIMIZATIONS和MANAGE_NOTIFICATIONS - 部分新机型(如 Pura X Max)还需在设置 → 应用管理 → 自启动管理 中手动打开开关,无法纯代码绕过
click 回调里。payload 解析、路由判断、参数校验、异常 fallback,这些都要拆成可单独测试的函数。很多人卡在“点了没反应”,最后发现只是 JSON.parse 少了个 try,或者华为手机根本没弹自启动授权框。


















