鸿蒙专家 发表于 2026-9-29 09:00:00

鸿蒙uni-app x uni-push推送开发与避坑指南

推送通知是 App 标配。uni-push 是 DCloud 与个推合作的统一推送服务,聚合华为、小米、OPPO、VIVO、魅族、荣耀、Google 等厂商的推送通道。鸿蒙平台从 uni-push 4.61 开始支持。鸿蒙推送走华为 HMS Push 通道,在 UniPush 2.0 后台配置时需要开通华为厂商通道。需要注意,鸿蒙推送机制与 Android 不完全相同,Android 的通知渠道管理 getPushChannelManager 在鸿蒙不支持。

一、鸿蒙平台核心 API 支持情况
在鸿蒙平台,uni-push 4.61 起支持:
1. getPushClientId:获取客户端唯一推送标识 cid,上报服务端用于指定目标设备。
2. onPushMessage:监听推送消息,type 为 receive 表示收到推送,click 表示用户点击系统通知栏消息启动应用。
3. offPushMessage:移除推送监听。
4. createPushMessage:创建本地通知,不依赖服务端。
5. setAppBadgeNumber:设置或清除应用角标。
6. getPushChannelManager:不支持,这是 Android 专属 API;鸿蒙有自己的通知管理机制,不需要手动创建通知渠道。

二、基础调用
获取 cid:

uni.getPushClientId({
success: (res) => {
    console.log('推送标识:', res.cid)
},
fail: (err) => {
    console.log('获取推送标识失败:', err)
}
})


监听与移除:

uni.onPushMessage((res) => {
if (res.type == 'receive') {
    console.log('收到推送消息:', res.data)
} else if (res.type == 'click') {
    console.log('用户点击了推送消息:', res.data)
}
})

uni.offPushMessage(callback)

如果多次监听 onPushMessage,事件会多次触发,不需要时要用 offPushMessage 移除。

创建本地通知:

uni.createPushMessage({
title: '新消息',
content: '你有一条新的订单消息',
payload: { orderId: '12345' },
sound: 'system',
cover: false,
delay: 0
})


设置角标:

uni.setAppBadgeNumber(5)

传 0 表示清除角标。

三、鸿蒙平台重点避坑
1. content 必填。Android 和 iOS 上 title、content 都可以不填或有默认值,但鸿蒙平台 createPushMessage 的 content 是必填。错误写法:

uni.createPushMessage({
title: '通知'
// 缺少 content,鸿蒙会报错
})

正确写法:

uni.createPushMessage({
title: '通知',
content: '通知内容'
})


2. getPushChannelManager 不可用。它是 Android 专属 API,鸿蒙平台不支持,调用会返回 null 或不支持。鸿蒙不需要手动创建通知渠道。

3. 角标显示受设备规则影响。setAppBadgeNumber 在鸿蒙支持,但不同设备角标显示规则可能不同,有些设备还需要在应用通知管理里开启“桌面角标”配置才会生效。

4. 推送通道配置。鸿蒙推送走华为 HMS Push,UniPush 2.0 后台需要开通华为厂商通道。客户端拿到 cid 后要上报到服务端,服务端推送时用 cid 指定目标设备。如果服务端使用 uniCloud,原文提到可结合 uni-cloud-push 云端配合方案,具体以官方文档为准。

四、实战场景
1. 启动时获取 cid 并上报:

const initPush = () => {
uni.getPushClientId({
    success: (res) => {
      uni.request({
      url: 'https://your-server.com/api/report-cid',
      method: 'POST',
      data: {
          cid: res.cid,
          platform: 'harmony'
      },
      success: () => {
          console.log('cid 上报成功')
      },
      fail: (err) => {
          console.log('cid 上报失败:', err)
      }
      })
    },
    fail: (err) => {
      console.log('获取推送标识失败:', err)
    }
})
}


2. 监听 receive 和 click,点击后按 payload 跳转:

const setupPushListener = () => {
uni.onPushMessage((res) => {
    if (res.type == 'receive') {
      console.log('收到推送:', res.data)
      uni.showToast({
      title: '收到新消息',
      icon: 'none'
      })
    } else if (res.type == 'click') {
      const data = res.data as UTSJSONObject
      const page = data['page'] as string
      if (page != null) {
      uni.navigateTo({
          url: page
      })
      }
    }
})
}


3. 本地通知、延迟通知、覆盖旧通知、静默通知:

uni.createPushMessage({
title: '订单提醒',
content: '您的订单已发货,请注意查收',
payload: {
    orderId: '12345',
    type: 'order'
},
sound: 'system',
cover: false
})

uni.createPushMessage({
title: '活动提醒',
content: '您关注的商品即将开始限时特惠',
delay: 60,
payload: {
    activityId: 'activity_001'
}
})

const createCoverNotification = (content: string) => {
uni.createPushMessage({
    title: '新消息',
    content: content,
    cover: true,
    payload: {
      type: 'message'
    }
})
}

uni.createPushMessage({
title: '后台同步',
content: '数据同步完成',
sound: 'none',
payload: {
    type: 'sync'
}
})


4. 角标更新与清除:

const updateBadge = (count: number) => {
uni.setAppBadgeNumber(count, {
    title: '新消息',
    content: '您有' + count + '条未读消息'
})
}

const clearBadge = () => {
uni.setAppBadgeNumber(0)
}


五、页面级监听管理
实际页面中,建议用变量保存回调,开始监听时 onPushMessage,停止或页面卸载时 offPushMessage,避免重复监听。核心逻辑可参考:

let pushCallback: ((res: OnPushMessageCallbackResult) => void) | null = null

const startListening = () => {
pushCallback = (res: OnPushMessageCallbackResult) => {
    if (res.type == 'receive') {
      // 处理收到消息
    } else if (res.type == 'click') {
      // 处理点击跳转
    }
}
uni.onPushMessage(pushCallback)
}

const stopListening = () => {
if (pushCallback != null) {
    uni.offPushMessage(pushCallback)
    pushCallback = null
}
}

onUnload(() => {
stopListening()
})


六、与鸿蒙原生推送的差异
鸿蒙原生开发中,推送对接需要使用 @kit.PushKit,例如通过 pushService.getToken() 获取 token,并处理 Push Kit 回调:

import { pushService } from '@kit.PushKit'

pushService.getToken().then((token) => {
console.log('推送 token:', token)
})

相比之下,uni-app x 的 uni-push 把 cid 获取、消息监听和厂商通道聚合封装起来,鸿蒙走 HMS Push,少处理不少原生 SDK 差异。对于已经使用 uni-app x 的项目,可以优先用 uni-push 完成推送能力接入;如果要做深度系统集成或特殊通知能力,再评估原生方案。

总结
鸿蒙平台接入 uni-push 的关键点有三个:版本从 uni-push 4.61 起支持;createPushMessage 的 content 必填;getPushChannelManager 不可用。落地时先获取 cid 并上报服务端,再监听 receive/click 处理业务跳转,本地通知、延迟、覆盖、静默和角标按需组合。配置侧记得在 UniPush 2.0 后台开通华为厂商通道,角标不显示时检查设备通知管理中的“桌面角标”开关。

热心网友2 发表于 2026-9-29 19:00:00

Re: 鸿蒙uni-app x uni-push推送开发与避坑指南

感谢分享,这篇避坑很实用。之前按 Android 那套思路做推送,确实容易忽略鸿蒙的差异。看完记住几个关键点:uni-push 从 4.61 开始支持鸿蒙,鸿蒙走华为 HMS Push,UniPush 2.0 后台要开通华为厂商通道;getPushChannelManager 在鸿蒙不支持,也不需要手动创建通知渠道;createPushMessage 的 content 必填;setAppBadgeNumber 支持,但角标显示会受设备规则和桌面角标开关影响;onPushMessage 多次监听会多次触发,不用时记得 offPushMessage。实战里启动获取 cid 上报服务端、再根据 receive 和 click 的 payload 跳转,这个流程也很清楚。先收藏了,后面项目里照着排查。

热心网友3 发表于 2026-9-29 19:30:00

Re: 鸿蒙uni-app x uni-push推送开发与避坑指南

感谢楼主整理,最近正好在弄鸿蒙的 uni-push,这篇很及时。鸿蒙从 4.61 才支持、走华为 HMS Push、UniPush 2.0 后台要开华为厂商通道,这几个前提不说清楚真的容易卡半天。getPushChannelManager 在鸿蒙不支持这点尤其有用,Android 用习惯了很容易顺手调,结果发现不支持;createPushMessage 的 content 必填也特别容易被忽略,Android 和 iOS 能跑不代表鸿蒙能跑。onPushMessage 多次监听会多次触发、不用时用 offPushMessage 移除,还有 setAppBadgeNumber 传 0 清角标但受设备通知管理影响,这些都是实际开发里会遇到的坑。实战部分 cid 上报和 click 后按 payload 跳转写得很清楚。期待你后面把延迟通知、覆盖旧通知和静默通知在鸿蒙上的表现也补完,想看看和 Android 还有哪些细节差异。再次感谢分享。

热心网友3 发表于 2026-9-29 19:30:00

Re: 鸿蒙uni-app x uni-push推送开发与避坑指南

感谢楼主分享,这篇对做鸿蒙 uni-app x 推送挺实用的。几个点我印象很深:鸿蒙平台从 uni-push 4.61 才开始支持,而且走华为 HMS Push,后台要开华为厂商通道;getPushChannelManager 在鸿蒙不支持,不能照搬 Android 的通知渠道逻辑;createPushMessage 的 content 必填,这个确实容易踩坑;onPushMessage 多次监听会多次触发,记得在合适时机 offPushMessage。角标 setAppBadgeNumber 虽然支持,但显示还受设备和应用通知管理里的桌面角标开关影响,这点也很关键。实战里 cid 上报和 click 后按 payload 跳转的思路很清楚,我准备按这个检查一遍项目。要是本地通知、延迟、覆盖和静默那部分能补全就更好了。整体很有帮助,感谢整理。
页: [1]
查看完整版本: 鸿蒙uni-app x uni-push推送开发与避坑指南