核心是确保push_clientid持久化获取、云函数动态调用getPushManager、客户端稳定监听;需在App.vue onLaunch中await获取并uni.setStorageSync缓存cid,真机调试必用自定义基座,云函数参数须校验cid非空且长度合规,manifest与厂商配置必须字符级一致。

uni-app 实现 uniCloud 实时消息通知系统,核心不是“写推送逻辑”,而是让 push_clientid 正确上报、云函数能精准调用 uniCloud.getPushManager、客户端能稳定监听并响应。任何一环断开,通知就静默失败。
如何确保 push_clientid 真实有效且可复用
cid 不是每次启动都刷新的临时值,它必须被持久化并全局可用,否则服务端无法定向推送。
-
uni.getPushClientId()返回的是异步 Promise,不能直接赋值给变量;必须用await或.then()拿到结果后再存入本地缓存 - 推荐在
App.vue的onLaunch中获取并缓存:uni.setStorageSync('cid', cid),后续所有推送都从这里读取 - 别在
onShow或页面onLoad里重复调用getPushClientId——它可能返回空或旧值,尤其在 Android 后台唤醒时 - 真机调试必须用「自定义基座」,否则
plus.push.getClientInfo()返回null,getPushClientId()永远 resolve 不了
云函数 sendMessage 必须绕过硬编码 cid
把 push_clientid 写死在云函数里等于放弃用户级推送能力,实际业务中 cid 来源必须动态、可验证。
- 云函数参数应通过 HTTP Query 或 Body 传入
cid,例如:event.queryStringParameters.cid或event.body.cid - 务必校验
cid长度(Android 通常 64+ 字符,iOS 更短)和非空,避免sendMessage报错400 Invalid client id - 不要用
uni.getStorageSync('cid')在云函数里读取——云函数运行在服务端,本地存储不可见 - 如果要做广播推送,改用
uniPush.sendAll,但注意它不触发离线推送,仅限在线设备
manifest.json 和厂商配置必须字符级一致
填错一个字母、多一个空格、大小写不符,Android 离线推送就彻底失效,连日志都不报错,只安静丢弃。
-
huawei下的appid必须和 AGC 控制台「项目设置 → 应用信息」里显示的**完全一致**,包括HUAWEI-前缀、大小写、无前后空格 -
xiaomi的appkey不是首页看到的 Key,得进「推送服务 → 应用配置」单独找;appid和appkey必须成对,且只对小米通道生效 -
oppo/vivo要填appKey和appSecret到对应字段,不能塞进meizu;还必须手动打开系统级权限:通知栏开关 + 自启动白名单 - Android 12+ 必须加
"permissions": ["android.permission.POST_NOTIFICATIONS"],否则连权限弹窗都不出现,getPushClientId()直接卡住
客户端监听与点击跳转不能依赖默认行为
uni-app 的 uni.onPush 和 uni.onNotificationClick 在不同平台表现差异极大,尤其是后台状态下的行为。
-
uni.onPush只在 App 前台生效;后台收到推送时,Android 会走系统通知栏,iOS 仅触发onLaunch的options参数 - 点击通知后不会自动跳转页面,必须手动监听:
plus.notification.addEventListener('click', () => uni.navigateTo({ url: '/pages/msg/list' })) - iOS 上
plus.notification.create完全无效,只能用uni.showLocalNotification,且需提前申请scope.notification权限 - 别用
uni.showLocalNotification替代服务端推送——它只在前台有效,且无法穿透后台,纯属调试辅助手段
真正难的不是写几行代码,而是让 cid 在真机上稳定生成、让厂商配置和 manifest.json 字符级对齐、让云函数参数校验不漏掉空值——这些细节一旦出错,整个链路就哑火,连错误提示都没有。


















