根本原因是uni.onPushMessage仅监听在线消息,对厂商离线推送无感;需用plus.push.addEventListener捕获系统级推送,并确保manifest.json中modulePermissions和sdkConfigs配置完整且同级。

uni.onPushMessage 为什么收不到消息?
根本原因往往不是代码写错了,而是推送通道压根没通——uni.onPushMessage 只监听「在线」状态下的消息(即 App 在前台或后台但进程未被杀),它对厂商通道的离线推送完全无感。如果你测试时把 App 杀掉再发推送,这条回调永远不会触发。
实操建议:
- 先用
plus.push.addEventListener("receive", ...)和plus.push.addEventListener("click", ...)替代,这是 5+ API 的底层监听,能捕获所有系统级推送(包括离线到达后点击/静默接收) - 确保在
App.vue的onLaunch和onShow中都注册监听,避免冷启动时漏掉首次推送 - 不要在页面级组件里写监听逻辑,生命周期不可靠,容易被销毁后失联
- 安卓真机测试必须用「自定义调试基座」或「云打包 APK」,HBuilderX 默认基座的包名和证书与你 DCloud 后台配置不匹配,必然收不到
manifest.json 推送配置错在哪?
最常被忽略的是 modulePermissions 和 sdkConfigs 两个字段缺一不可,只填 appid 是无效的。DCloud 2026 年起已强制校验完整结构,否则打包时不会注入推送模块,运行时 plus.push 为 undefined。
正确写法示例(注意缩进和层级):
{
"name": "MyApp",
"appid": "__UNI__XXXXXXX",
"description": "",
"versionName": "1.0.0",
"versionCode": "100",
"transformPx": false,
"app-plus": {
"usingComponents": true,
"nvueStyleCompiler": "uni-app",
"splashscreen": {
"alwaysShowBeforeRender": true,
"waiting": true,
"autoclose": true,
"delay": 0
}
},
"mp-weixin": {},
"h5": {},
"quickapp": {},
"modulePermissions": ["Push"],
"sdkConfigs": {
"push": {
"unipush": {
"appid": "__UNI__XXXXXXX",
"appkey": "your-appkey-from-dcloud-console"
}
}
}
}
常见错误:
-
appid填了,但appkey空着或填错 —— 它不是 AppID,而是在 DCloud 开发者中心「uni-push → uni-push 2.0」页生成的独立密钥 - 把配置写在
app-plus下面,而不是根级 —— manifest.json 是扁平结构,modulePermissions和sdkConfigs必须与name、appid同级 - 云打包时勾选了「使用自定义 SDK」但没上传对应厂商的证书或密钥 —— 导致华为/小米等通道初始化失败,降级为个推,送达率暴跌
uniPush2 服务端怎么触发推送?
不需要自己搭后端、不用调第三方 API,uniPush2 的核心优势就是和 uniCloud 深度绑定。你只要在云函数里调用 uniCloud.callFunction 就能发,连 token 都不用管。
实操路径:
- 确保项目是「uni-app(内置 uniCloud)」模板创建的,否则云函数无法访问
uni-push服务 - 在云函数中使用
uniCloud.registerService('push', {...})初始化(官方 SDK 已内置,一般无需手动注册) - 真正发推送只用一行:
await uniCloud.getProvider('push').send({ title: '通知标题', content: '正文', payload: '{"page":"/pages/msg/detail"}' }) - payload 是字符串,不是对象;必须 JSON 序列化,且 key 名要小写(如
page而非Page),否则 H5+ 跳转会失败
注意:web 端和小程序端推送走的是 socket 在线通道,App 端才走厂商通道。所以测试时务必用真机装云打包后的 APK/iPA,否则永远看不到“通知栏弹窗”效果。
为什么厂商通道配置总失败?
不是你操作错了,是厂商平台规则变了。2026 年起,华为 HMS Core 要求应用签名 SHA-256 证书指纹必须和 DCloud 后台填写的一致;小米推送强制开启「应用内消息」开关才能下发;OPPO 则要求包名、应用名称、签名三者与 OPPO 开放平台完全一致,差一个字符都不行。
避坑清单:
- 别信网上旧教程说的「随便填个测试密钥就行」—— 华为、小米现在全部 require 正式上架前的签名信息,开发阶段就得用最终发布签名打包,再提取指纹填入 DCloud 后台
- 每个厂商的「AppID/AppKey/Secret」必须单独申请,不能复用其他项目的,DCloud 后台会校验绑定关系
- 荣耀设备归入华为通道,但需额外在华为后台开通「荣耀生态」权限,否则荣耀手机收不到
- 测试时优先用华为/小米真机,vivo 和 OPPO 对调试包限制更严,经常出现「已配置但收不到」的假阴性
最麻烦但绕不开的点:厂商通道不是配完就完事,它们有审核周期(尤其华为要 1–3 个工作日),别卡在上线前两天才去配。









