uni-app消息推送成功的关键在于配置全对且一致:需严格匹配厂商后台参数、使用自定义基座真机调试、云函数调用uniCloud.getPushManager、cid在onLaunch获取并缓存,否则推送失败。

uni-app 实现消息推送,核心不是写多少代码,而是配置是否“全对且一致”。uniPush 2.0 本身不提供独立 SDK,它是一套由 DCloud 云服务驱动的转发网关——客户端只负责上报 push_clientid,服务端只允许通过 uniCloud.getPushManager 调用。任何绕过这套链路的尝试(比如自己调华为 HMS 接口、直连 APNs 或用个推 REST API)都会失败,返回 401 或静默丢弃。
manifest.json 的 push 配置必须和厂商后台完全一致
填错一个字符,Android 离线推送就失效,通知栏压根不弹。这不是逻辑问题,是身份认证失败。
-
huawei下的appid必须和 AGC 控制台「项目设置 → 应用信息」里显示的 一模一样,包括大小写和前后空格;漏掉HUAWEI-前缀或写成com.xxx.hms都会返回空cid -
xiaomi的appkey不是控制台首页看到的“AppKey”,得进「推送服务 → 应用配置」页面单独找;appid和appkey必须成对,且仅适用于小米推送通道 -
oppo和vivo的appKey/appSecret要填在对应对象下,不能塞进meizu或漏掉;它们还要求手动开启系统级权限:通知栏开关 + 自启动白名单,否则即使配置正确,也收不到离线消息 - 别忘了加
"permissions": ["android.permission.POST_NOTIFICATIONS"]—— Android 12+ 强制要求,没这句,连权限弹窗都不出现,plus.push.getClientInfo()直接返回空
真机调试必须用「自定义基座」,默认基座无效
默认基座(也就是 HBuilderX 自带的调试 App)不包含任何厂商 SDK,plus.push.getClientInfo() 会返回 null 或空字符串,uni.getPushClientId() 也拿不到有效值。这不是 bug,是设计如此。
- 在 HBuilderX 中点击「运行」→「运行到手机或模拟器」→「制作自定义调试基座」,按向导完成;过程中确保登录账号与 DCloud 开发者中心一致
- 制作完成后,运行时选择该基座,而不是“使用标准基座”
- 云打包产出的 APK/IPA 也必须基于同一账号、同一 AppID 构建,否则 cid 无法被 uniPush 后台识别
服务端只能走 uniCloud 云函数,且 appId 必须来自开发者中心
你不能在自己的 Node.js 服务里调 uniCloud.getPushManager,也不能把云函数部署到非 DCloud 的云环境。这个 API 是封闭的,只认 DCloud 的 appId 绑定关系。
- 新建云函数(如
push-message),右键 →「管理公共模块」→ 勾选uni-cloud-push - 云函数中初始化必须传入开发者中心「uni-push 2.0 → 应用信息」页显示的 AppID,不是
manifest.json里的 bundleId,也不是云空间 ID - 推送目标优先用
push_clientid(即cid),别用alias或tag:alias在多设备登录场景下极易冲突;tag同步延迟高,且部分厂商通道不支持实时更新 - 若需 App 前台时也弹通知栏(默认只走 socket),推送参数里加
force_notification: true
cid 获取时机和位置有硬性限制
cid 不是随时都能取,也不是 anywhere 都能取。它依赖原生推送服务初始化完成,而初始化过程在 iOS/Android 上耗时不同,且受证书、网络、权限状态影响。
- 必须在
App.vue的onLaunch生命周期中获取,其他地方(如某个页面的onLoad)可能还没 ready - 建议加防抖和重试:先判断
uni.getPushClientId返回是否为字符串且长度 > 10,否则延时 1s 再试,最多 3 次 - iOS 设备首次安装后,需要用户手动授权通知权限;未授权前
cid为空,授权后需重启 App 才能触发回调 - 获取到
cid后应立即存入本地缓存(uni.setStorageSync),并同步到服务端做映射,避免每次启动都重新请求
最容易被忽略的是:云服务空间未绑定 uniPush 2.0 服务时,客户端一切正常,cid 也能拿到,但服务端调用 sendMessage 会静默失败,日志里只显示 push service not enabled。这个问题没有明确报错,也没有网络异常提示,只能靠排查云函数日志里的这一行判断。


















