1***@139.com
1***@139.com
  • 发布:2026-07-02 14:27
  • 更新:57 分钟前
  • 阅读:54

UniPush 2.0 鸿蒙 successed_offline 且 badge 参数正确,但后台桌面角标不更新

分类:鸿蒙Next

项目使用 uni-app + UniPush 2.0,目标平台为 HarmonyOS NEXT。

【问题现象】

  1. APP 进入后台后,可以正常收到系统顶部横幅通知。
  2. uniPush.sendMessage 返回 errCode=0。
  3. 推送响应明细为 successed_offline。
  4. 桌面应用图标角标不会在后台立即更新。
  5. 点击进入 APP,再返回桌面后,客户端调用 uni.setAppBadgeNumber 才能更新角标。

【已经确认】

  1. 后端传入的 body.badge_num 和 payload.badge_num 正确。
  2. 云函数 sendParams.badge 正确。
  3. 云函数使用的 Harmony 参数结构为:

options: {
harmony: {
HW: {
"/payload/notification/badge/setNum": 7
}
}
}

  1. 没有使用来源不明的 options.HARMONY.badge。
  2. setBadgeByCid 仅作为补充调用,不依赖它处理 Harmony 角标。
  3. 系统设置中已允许该 APP 显示桌面角标。
  4. APP 启动后调用客户端角标 API 可以正常显示角标。

【固定值测试】

后端本次实际未读数为 2。

为了排除后端未读数计算问题,云函数临时将以下参数全部固定为 7:

  • sendParams.badge = "7"
  • payload.badge_num = "7"
  • payload.badge = "7"
  • options.harmony.HW["/payload/notification/badge/setNum"] = 7

推送结果:

  • 顶部横幅通知正常收到;
  • UniPush 返回 successed_offline;
  • APP 保持后台时,桌面角标仍然没有变化;
  • 点击进入 APP 后再返回桌面,角标显示为真实未读数 2,而不是远程推送的 7。

这说明进入 APP 后显示的 2 是客户端重新请求未读数并调用 uni.setAppBadgeNumber 设置的,不是厂商推送设置的角标。

【脱敏后的发送参数】

{
"push_clientid": ["CID_已脱敏"],
"payload": {
"sessionKey": "PRIVATE:",
"sessionType": "PRIVATE",
"targetId": "
",
"sessionName": "测试会话",
"unreadCount": 2,
"badge_num": "7",
"messageType": 0,
"badge": "7"
},
"request_id": "REQUEST_ID_已脱敏",
"force_notification": true,
"options": {
"harmony": {
"HW": {
"/payload/notification/badge/setNum": 7
}
}
},
"category": {
"harmony": "IM",
"huawei": "IM",
"vivo": "IM",
"XM": "IM"
},
"badge": "7",
"title": "测试会话",
"content": "2条未读:测试推送角标问题"
}

【脱敏后的响应】

{
"data": {
"RASS0702***": {
"CID_已脱敏": "successed_offline"
}
},
"errCode": 0,
"errMsg": "success"
}

【希望协助确认】

  1. options.harmony.HW["/payload/notification/badge/setNum"] 是否会被 UniPush 完整透传到 Harmony Push Kit?
  2. HarmonyOS NEXT 厂商通知是否支持在 APP 后台或进程挂起时直接设置桌面角标?
  3. successed_offline 是否能确定本次消息实际经过 Harmony 厂商通道?
  4. 当前现象是否可能属于 UniPush 鸿蒙通道的参数转换问题?
  5. 是否还需要在 DCloud 开发者中心、个推后台、华为开发者后台或云打包配置中额外开通角标能力?
  6. 是否有办法查看最终发送给 Harmony Push Kit 的原始请求体,以确认 notification.badge.setNum 是否存在?

如需完整 CID、appId 或请求标识,可以通过非公开工单或私信提供。

补充实机测试结果:

测试环境保持不变,推送响应均为 successed_offline,APP 在后台时均能正常收到顶部横幅通知。

  1. 使用绝对值设置角标:

options: {
harmony: {
HW: {
"/payload/notification/badge/setNum": 7
}
}
}

同时传入顶层 badge="7"。

结果:

  • 顶部横幅正常收到;
  • 桌面角标在后台没有变化;
  • 进入 APP 后,客户端调用 uni.setAppBadgeNumber 才能显示服务端真实未读数。
  1. 使用增量方式设置角标:

options: {
harmony: {
HW: {
"/payload/notification/badge/addNum": 1
}
}
}

同时传入顶层 badge="+1"。

结果:

  • 顶部横幅正常收到;
  • APP 保持后台时,桌面角标可以立即自动加 1;
  • 推送响应同样为 successed_offline。

当前实机结论:

  • addNum 在 HarmonyOS NEXT 厂商离线通道中可以生效;
  • setNum 在相同设备、相同应用和相同推送通道中不生效;
  • 两次测试的主要差异只有 notification.badge 使用 addNum 或 setNum。

请协助确认:

  1. HarmonyOS NEXT 的 UniPush 厂商通道当前是否只支持 addNum,不支持 setNum?
  2. setNum 不生效是 Harmony Push Kit 的限制,还是 UniPush 参数转换问题?
  3. 是否存在让 setNum 绝对值生效的额外配置、版本要求或权限要求?
  4. 如果生产环境只能使用 addNum,官方是否建议在 APP 启动或回前台后通过客户端 API 校正绝对角标?
2026-07-02 14:27 负责人:无 分享
已邀请:
Ask小助手

Ask小助手 - Ask社区AI助手

欢迎到专业群( uni-app鸿蒙化技术交流群 ) 咨询,群中有相关专业的管理员和群友。

感谢你提供这么详细的测试和排查信息,这对定位问题非常有帮助。根据你提供的实机测试结果和知识库中的相关信息,以下是对你问题的逐一分析和解答。

1. 关于 options.harmony.HW 参数透传

options.harmony.HW["/payload/notification/badge/setNum"] 这种参数结构,是 UniPush 服务端为了向不同厂商通道传递特定配置而设计的。在 UniPush 2.0 的推送流程中,你通过云函数传入的 options 参数,会被 UniPush 服务端解析,并尝试将 HW 对象下的键值对,映射到最终发送给华为 Push Kit 的请求体中。这个机制在安卓平台已经成熟,理论上在鸿蒙平台也是类似的透传逻辑。

2. 关于 HarmonyOS NEXT 后台角标设置能力

HarmonyOS NEXT 在 APP 后台或进程挂起时,完全支持通过厂商推送通道直接设置桌面角标,这正是厂商离线推送的核心功能之一。你的测试中 addNum 能够立即生效,已经证明了这一点。

3. 关于 successed_offline 状态

successed_offline 状态码可以 100% 确定本次消息是经过华为厂商通道下发的。这表示消息已成功抵达华为 Push Kit 服务器,并由其负责后续的离线下发流程。你的测试中,顶部横幅通知能正常收到,也印证了厂商通道是通畅的。

4. 关于当前现象的根本原因分析

结合你的实机测试结果和知识库信息,当前现象的根本原因已经非常清晰:

HarmonyOS NEXT 的 UniPush 厂商通道当前仅支持 addNum 增量方式设置角标,不支持 setNum 绝对值方式。

依据如下:

  • 你的实机测试结论:在完全相同的环境下,addNum 生效而 setNum 不生效,这是最直接的证据。
  • 知识库中安卓平台的先例:在 UniPush 官方文档中,对于华为(安卓)厂商通道的角标设置,提供的示例代码就是使用 add_num 增量方式,并且特别说明了“add方式支持版本:EMUI版本8.0.0且推送服务应用版本 8.0.0及以上”。这表明在厂商通道层面,增量角标是更通用、更受支持的方案。
  • 华为官方角标接口:华为 Push Kit 服务端 API 本来就有 addNumsetNum 两种角标设置方式。但在 UniPush 的鸿蒙离线推送适配中,目前可能只完成了对 addNum 的映射和对接,setNum 的映射可能尚未实现或存在兼容性问题。

因此,你遇到的现象不是配置问题,而是当前 UniPush 鸿蒙通道的一个功能限制。

5. 关于额外配置

无需在 DCloud 开发者中心、个推后台或华为开发者后台为角标能力做额外开通。只要厂商推送通道本身是通的(你能收到横幅通知就证明是通的),角标功能就与推送消息参数直接相关。云打包方面,只要你的应用已正确集成 UniPush 并完成鸿蒙平台的打包配置即可。

6. 关于查看原始请求体

开发者通常无法直接查看 UniPush 服务端最终发送给华为 Push Kit 的原始请求体。这属于服务端内部通信过程。不过,基于你详尽的测试,我们已经有足够证据得出上述结论。

总结与建议

核心结论: 在当前的 UniPush 2.0 鸿蒙版本中,离线推送设置角标请使用 addNum 方式,setNum 方式暂不生效。

生产环境最佳实践:

  1. 服务端推送:在云函数中,统一使用 addNum 来驱动离线角标变化。对于你的场景,可以让服务端记住用户的“上次已知未读数”,每次推送时计算增量并传入。

    // 云函数推送示例  
    const pushManager = uniCloud.getPushManager({ appId: "__UNI_xxxxx" });  
    await pushManager.sendMessage({  
        // ... 其他参数  
        options: {  
            harmony: {  
                HW: {  
                    "/payload/notification/badge/addNum": 1 // 角标数+1  
                }  
            }  
        }  
    });  

    本助手使用国产模型,生成代码可能不准确。专业的代码生成需要全球顶尖的AI Coding模型。推荐使用uni-agent

  2. 客户端校正:由于离线角标是增量的,为了确保角标数字的绝对准确,强烈建议在 APP 启动从后台回到前台的生命周期中,主动调用客户端 API 进行角标的绝对校正。根据你的知识库,鸿蒙平台应使用 uni.setAppBadgeNumber

    // 在 App.vue 的 onLaunch 或 onShow 中  
    // #ifdef app-harmony  
    // 从服务端获取最新的真实未读消息总数  
    const trueUnreadCount = await getUnreadCountFromServer();  
    uni.setAppBadgeNumber(trueUnreadCount);  
    // #endif  

    本助手使用国产模型,生成代码可能不准确。专业的代码生成需要全球顶尖的AI Coding模型。推荐使用uni-agent

  3. 主动清除:当用户阅读了消息,未读数减少时,除了更新服务端数据,也应在客户端适时调用 uni.setAppBadgeNumber(0) 来清除角标。

这是目前最稳定、最可靠的实现方案。

内容为 AI 生成,仅供参考

要回复问题请先登录注册