- 发布:2026-04-16 17:40
- 更新:2026-04-20 14:47
- 阅读:203
鸿蒙next 手机推送消息通知通过unipush2.0 云函数推送。为啥鸿蒙next手机上收不到消息弹窗呢
根据知识库中的信息,关于鸿蒙Next手机使用uniPush 2.0云函数推送收不到消息弹窗的问题,暂未找到针对该特定场景的详细排查文档。
不过,知识库中uniPush的uniCloud版【V2】插件的平台兼容性明确标注:鸿蒙(-)、鸿蒙元服务(-),即该插件不支持鸿蒙平台。该插件仅支持uni-push 1.0,且文档提示"新项目推荐使用更强大的新版uni-push 2.0"。
另外,在uniPush的推送通道选择逻辑文档中,仅详细说明了Android和iOS平台的推送机制,未包含鸿蒙Next平台的相关内容。
建议您:
- 确认当前使用的uniPush 2.0版本是否已正式支持鸿蒙Next平台(知识库中暂未检索到相关支持文档)
- 检查鸿蒙Next是否需要单独配置厂商推送通道(类似Android的厂商离线推送配置)
- 前往插件市场搜索是否有专门针对鸿蒙Next的推送插件:https://ext.dcloud.net.cn/search
抱歉暂未在知识库中找到鸿蒙Next平台推送问题的具体解决方案。
q***@outlook.com (作者)
<script setup>
import config from './config'
import {
getToken
} from '@/utils/auth'
import { bindCid, reportPushStatus } from '@/api/system/user'
import { useConfigStore } from '@/store'
import { getCurrentInstance } from "vue"
import { onLaunch, onShow } from '@dcloudio/uni-app'
import { getPushClientId, onPushMessage, isHarmony, requestNotificationPermission } from '@/utils/push'
import { bindCID, unbindCID, checkCID } from '@/utils/cid-manager'
const { proxy } = getCurrentInstance()
// 记录是否正在绑定中,防止并发请求
let isBindingCid = false
// #ifdef APP-HARMONY
// 鸿蒙Next需要在应用启动时申请通知权限
requestNotificationPermission().catch(err => {
console.log('通知权限申请失败:', err)
})
// #endif
onLaunch(async () => {
initApp()
loadFontFace()
initPush()
// 监听登录成功事件,登录成功后主动绑定一次 CID
uni.$on('loginSuccess', async () => {
await bindCurrentCid()
})
})
onShow(() => {
// 每次回到前台时,如果已登录但尚未绑定过 CID,则尝试绑定
if (getToken() && !checkCID()) {
bindCurrentCid()
}
})
// 初始化应用
function initApp() {
// 初始化应用配置
initConfig()
// 检查用户登录状态
checkLogin()
}
function initConfig() {
useConfigStore().setConfig(config)
}
function checkLogin() {
if (!getToken()) {
uni.reLaunch({ url: '/pages/login' })
}
}
// 初始化 UniPush 2.0
function initPush() {
// 1. 获取客户端推送标识 (CID),如果已经登录则尝试绑定
if (getToken() && !checkCID()) {
bindCurrentCid()
}
// 2. 监听推送消息
onPushMessage((res) => {
console.log("收到推送消息:", res)
if (res.type === 'receive') {
// 收到在线消息,可在此处做一些 UI 提醒,或通过 uni.createPushMessage 创建本地通知(如果需要)
// 注意:在个推平台或后端发送消息时,如果不带通知栏标题内容(即透传消息),则走 receive
// 如果是需要通知栏展示的,建议后端发送包含 notification 的标准推送,系统会自动展示通知
const payload = res.data && res.data.payload ? res.data.payload : res.data
console.log("payload的内容",payload)
// ===== 向后端上报:已接收 =====
if (getToken()) {
reportPushStatus({
messageId: res.data.msgId || payload.msgId || '', // 需要后端发消息时带上唯一消息ID
status: 'received', // 状态:已接收
timestamp: new Date().getTime()
}).catch(err => console.log('上报接收状态失败', err))
}
// 比如收到新询盘,创建本地通知(通知栏消息)
if (payload && payload.type === 'enquiry') {
// 创建本地通知栏消息,系统将自动弹出通知提醒,用户点击后会触发 res.type === 'click'
uni.createPushMessage({
title: '新询盘提醒',
content: '您有一条新的询盘消息,点击立即查看',
payload: payload,
success: (resMsg) => {
console.log('创建本地通知成功', resMsg)
}
})
}
} else if (res.type === 'click') {
// 点击通知栏消息触发
const payload = res.data && res.data.payload ? res.data.payload : res.data
// ===== 向后端上报:已点击 =====
if (getToken()) {
reportPushStatus({
messageId: res.data.msgId || payload.msgId || '', // 需要后端发消息时带上唯一消息ID
status: 'clicked', // 状态:已点击
timestamp: new Date().getTime()
}).catch(err => console.log('上报点击状态失败', err))
}
handlePushClick(payload)
}
})
}
// 绑定当前设备的 CID 到后端
async function bindCurrentCid() {
// 如果已经绑定过或者正在绑定中,则直接返回
if (checkCID() || isBindingCid) return;
isBindingCid = true;
try {
// 使用统一的CID管理工具绑定
const cid = await bindCID({ force: true })
if (cid) {
console.log('==== CID 绑定后端成功 ====', cid)
} else {
console.log('==== CID 绑定失败 ====')
}
} catch (err) {
console.log('==== CID 绑定异常 ====', err)
} finally {
isBindingCid = false;
}
}
// 处理推送点击事件
function handlePushClick(payload) {
// 判断消息类型,若是新增询盘信息,则跳转到相应的询盘列表或详情页面
if (payload && payload.type === 'enquiry') {
// 跳转到询盘相关页面
uni.navigateTo({
url: '/pages/enquiry/index'
})
}
}
function loadFontFace() {
uni.loadFontFace({
family: 'YouSheBiaoTiHei',
source: 'url("/static/font/YouSheBiaoTiHei.ttf")',
global: true,
success: () => {},
fail: () => {}
})
}
</script>
<style lang="scss">
@import "@/uni_modules/uview-plus/index.scss";
@font-face {
font-family: 'YouSheBiaoTiHei';
src: url('/static/font/YouSheBiaoTiHei.ttf') format('truetype');
font-display: swap;
}
@import '@/static/scss/index.scss';
</style>
上面的是App.vue,下面是云函数支付宝云index.js代码
'use strict';
exports.main = async (event, context) => {
// 如果是云函数 URL 化被后端调用,参数可能会包裹在 body 中
let params = event;
if (event.body) {
try {
params = typeof event.body === 'string' ? JSON.parse(event.body) : event.body;
} catch (e) {
console.error("解析 body 失败", e);
}
}
const { cid, title = "新询盘提醒", content = "您有一条新的询盘消息,请及时处理", payload = { type: 'enquiry' }, isTest = false } = params;
if (!cid) {
return { code: 400, message: '客户端标识(cid)不能为空' };
}
// 根据是否为测试环境动态设置 target_user_type
const targetUserType = isTest ? 1 : 0;
// 初始化 uni-push
const uniPush = uniCloud.getPushManager({
appId: '__UNI__24651AF' // 注意:必须与你 manifest.json 里的 appid 保持完全一致
});
try {
const pushResult = await uniPush.sendMessage({
"push_clientid": cid, // 必填,单推填字符串,多推填数组
"title": title, // 通知栏展示的标题
"content": content, // 通知栏展示的内容
"payload": payload, // 点击通知后传递给 App 的自定义数据
"force_notification": true, // 强制展示通知(即使 App 在前台运行)
"request_id": Date.now().toString() + Math.random().toString(36).substr(2, 5), // 请求唯一标识
"category": {
//HarmonyOS NEXT系统(纯血鸿蒙、非安卓鸿蒙)的消息分类,要给鸿蒙设备推送时才必传
"harmony": "WORK"
},
// options 用于配置各大厂商离线推送的特殊参数(声明为系统消息以突破频次限制)
"options": {
"HW": {
"/message/android/notification/importance": "NORMAL",
"/message/android/category": "WORK", // 华为:声明为系统消息分类
"/message/android/target_user_type": targetUserType
},
"HO": {
"/android/notification/importance": "NORMAL"
},
"XM": {
"/extra.channel_id": "你的小米系统消息Channel_ID"
},
"OP": {
"/channel_id": "你的OPPO系统消息Channel_ID"
},
"VV": {
"/category": "SYSTEM"
},
"HM": {
"/message/harmony/category": "WORK", // 鸿蒙NEXT:纯血鸿蒙的消息分类
"/message/harmony/target_user_type": targetUserType
}
}
});
console.log('推送结果888888888:', pushResult);
// 判断是否包含无效 CID 的信息(如个推返回 invalid_clientid 或错误提示中包含 target)
let isInvalidCid = false;
if (pushResult && pushResult.data) {
const dataStr = JSON.stringify(pushResult.data).toLowerCase();
console.log("获取到的推送data99999",dataStr);
if (dataStr.includes('invalid') || dataStr.includes('notfound') || dataStr.includes('unregistered')) {
isInvalidCid = true;
}
}
return {
code: 200,
message: '推送请求成功',
isInvalidCid: isInvalidCid, // 明确告知后端该 CID 是否已失效
data: pushResult
};
} catch (error) {
console.error('推送失败:', error);
// 错误对象中也可能包含 CID 失效的明确标志 (如 target error)
let isInvalidCid = false;
const errStr = (error.message || JSON.stringify(error)).toLowerCase();
if (errStr.includes('invalid') || errStr.includes('target') || errStr.includes('not found') || errStr.includes('unregistered')) {
isInvalidCid = true;
}
return {
code: 500,
message: '推送异常',
isInvalidCid: isInvalidCid, // 明确告知后端该 CID 是否已失效
data: error
};
}
};