推送与通知(uni.push)
uni.push 简介
uni.push 是 uni-app 提供的跨平台推送服务,支持 iOS、Android 和 Web 平台。它封装了各平台的原生推送能力,开发者只需调用统一 API 即可实现推送功能。uni.push 支持离线推送、本地通知、消息透传等多种场景,适用于消息提醒、营销推送、系统通知等需求。
推送服务配置
申请推送服务权限
使用 uni.push 前需要先在各个平台申请推送权限:
- iOS:在苹果开发者中心配置推送证书(开发和生产环境)
- Android:在各大厂商推送平台(华为、小米、OPPO、vivo等)申请应用密钥
- Web:使用浏览器通知 API(需用户授权)
// manifest.json 配置示例
{
"app-plus": {
"distribute": {
"ios": {
"push": {
"production": true,
"devCert": "dev.p12",
"prodCert": "prod.p12"
}
},
"android": {
"push": {
"HW": {
"appid": "你的华为应用ID"
},
"XM": {
"appid": "你的小米应用ID",
"appkey": "你的小米应用密钥"
}
}
}
}
}
}
客户端初始化
在应用启动时初始化推送服务:
// App.vue
export default {
onLaunch() {
uni.getPushClientId({
success: (res) => {
console.log('客户端推送标识:', res.cid)
// 将 cid 发送到服务器保存
},
fail: (err) => {
console.error('获取推送标识失败:', err)
}
})
// 监听推送消息
uni.onPushMessage((res) => {
console.log('收到推送消息:', res)
if (res.type === 'click') {
// 用户点击通知栏消息
this.handlePushClick(res)
} else if (res.type === 'receive') {
// 收到透传消息
this.handlePushReceive(res)
}
})
}
}
推送消息类型
通知栏消息
通知栏消息会显示在系统通知中心,用户点击后可以打开应用:
// 服务端推送示例(Node.js)
const push = require('uni-push')
push.send({
platform: ['ios', 'android'],
notification: {
title: '新消息提醒',
body: '您有3条未读消息',
sound: 'default',
badge: 3,
extras: {
path: '/pages/message/list',
type: 'message'
}
},
cid: ['客户端推送标识1', '客户端推送标识2']
})
透传消息
透传消息不会显示通知,直接传递给应用处理:
push.send({
platform: ['ios', 'android'],
message: {
title: '静默消息',
content: '{"action":"update","data":{"version":"1.2.0"}}',
extras: {
silent: true
}
},
cid: ['客户端推送标识']
})
本地通知
应用内触发本地通知,无需服务器参与:
uni.createPushMessage({
title: '本地通知',
content: '这是一条本地生成的通知',
delay: 5, // 5秒后显示
sound: 'default',
extras: {
path: '/pages/home/index'
},
success: () => {
console.log('本地通知创建成功')
}
})
消息处理与跳转
处理推送点击
methods: {
handlePushClick(res) {
const extras = res.data.extras || {}
if (extras.path) {
// 跳转到指定页面
uni.navigateTo({
url: extras.path
})
}
// 根据消息类型处理业务逻辑
switch(extras.type) {
case 'message':
this.updateUnreadCount()
break
case 'order':
this.fetchLatestOrder()
break
}
}
}
消息到达统计
// 统计消息到达率
uni.reportPushMsgArrival({
msgid: res.data.msgid,
success: () => {
console.log('消息到达上报成功')
}
})
高级功能
标签与别名管理
// 设置用户别名(替代CID)
uni.setPushAlias({
alias: 'user123',
success: () => {
console.log('别名设置成功')
}
})
// 添加标签
uni.addPushTag({
tags: ['vip', 'shanghai'],
success: () => {
console.log('标签添加成功')
}
})
定时推送
// 服务端设置定时推送
push.send({
notification: {
title: '每日提醒',
body: '记得完成今日任务'
},
cid: ['客户端推送标识'],
time: '2023-12-31 20:00:00' // 指定发送时间
})
富媒体通知
// Android 大图通知
push.send({
platform: ['android'],
notification: {
title: '新品上市',
body: '点击查看详情',
style: {
type: 1, // 大图样式
bigText: '...',
bigPicPath: 'https://example.com/banner.jpg'
}
}
})
常见问题处理
推送权限检查
uni.checkPushPermission({
success: (res) => {
if (!res.result) {
// 引导用户开启通知权限
this.showPermissionDialog()
}
}
})
厂商通道适配
// 处理不同厂商的兼容性问题
if (uni.getSystemInfoSync().platform === 'android') {
// 华为设备特殊处理
if (uni.getSystemInfoSync().brand === 'HUAWEI') {
this.adjustForHuawei()
}
// 小米设备特殊处理
else if (uni.getSystemInfoSync().brand === 'Xiaomi') {
this.adjustForXiaomi()
}
}
推送性能优化
// 合并同类消息
let lastMessageTime = 0
uni.onPushMessage((res) => {
const now = Date.now()
if (now - lastMessageTime < 1000) {
// 1秒内收到多条消息,合并处理
this.batchUpdate()
return
}
lastMessageTime = now
// 正常处理
})
推送策略设计
用户分群推送
// 根据用户行为推送不同内容
function getUserGroup(user) {
if (user.lastLogin < Date.now() - 30*24*60*60*1000) {
return 'inactive'
} else if (user.orderCount > 5) {
return 'vip'
} else {
return 'normal'
}
}
const group = getUserGroup(currentUser)
push.send({
notification: {
title: group === 'inactive' ? '好久不见' : '专属优惠',
body: group === 'vip' ? '会员专属折扣' : '新用户福利'
},
cid: [currentUser.cid]
})
A/B 测试实现
// 随机分组推送
const variant = Math.random() > 0.5 ? 'A' : 'B'
const message = {
A: {
title: '限时折扣',
body: '全场5折起'
},
B: {
title: '新品上市',
body: '立即抢购'
}
}
push.send({
notification: message[variant],
extras: {
variant: variant
},
cid: [user.cid]
})
数据统计与分析
推送效果追踪
// 跟踪用户行为
uni.onPushMessage((res) => {
if (res.type === 'click') {
const extras = res.data.extras || {}
reportAnalytics('push_click', {
msgid: res.data.msgid,
type: extras.type,
variant: extras.variant
})
}
})
推送报表生成
// 服务端统计代码示例
async function generatePushReport(startDate, endDate) {
const stats = await PushLog.aggregate([
{
$match: {
createdAt: { $gte: startDate, $lte: endDate }
}
},
{
$group: {
_id: '$campaign',
sent: { $sum: 1 },
arrived: { $sum: { $cond: [{ $eq: ['$arrived', true] }, 1, 0] } },
clicked: { $sum: { $cond: [{ $eq: ['$clicked', true] }, 1, 0] } }
}
}
])
return stats.map(item => ({
campaign: item._id,
arrivalRate: (item.arrived / item.sent * 100).toFixed(2) + '%',
clickThroughRate: (item.clicked / item.arrived * 100).toFixed(2) + '%'
}))
}
安全与权限控制
推送内容审核
// 服务端内容过滤
function filterPushContent(content) {
const bannedWords = ['敏感词1', '敏感词2']
for (const word of bannedWords) {
if (content.includes(word)) {
throw new Error('推送内容包含敏感词')
}
}
return content
}
用户退订处理
// 退订管理
uni.getPushSetting({
success: (res) => {
if (!res.notificationEnabled) {
// 用户关闭了通知
this.showReEnableDialog()
}
}
})
// 退订特定类型消息
uni.subscribePush({
topic: 'promotion',
subscribe: false, // 取消订阅
success: () => {
console.log('已取消订阅营销消息')
}
})
多平台差异处理
iOS 特殊配置
// 处理 iOS 推送限制
if (uni.getSystemInfoSync().platform === 'ios') {
// 请求通知权限
uni.requestPushPermission({
success: (res) => {
if (res.result) {
console.log('已获得推送权限')
}
}
})
// 处理角标清零
uni.setPushBadge({
badge: 0
})
}
Web 平台适配
// Web 平台通知处理
if (process.env.VUE_APP_PLATFORM === 'h5') {
// 检查浏览器通知支持
if (!('Notification' in window)) {
console.log('该浏览器不支持通知')
} else if (Notification.permission === 'granted') {
// 已授权
} else if (Notification.permission !== 'denied') {
// 请求权限
Notification.requestPermission().then(permission => {
if (permission === 'granted') {
new Notification('欢迎回来')
}
})
}
}
调试与问题排查
推送日志记录
// 客户端日志记录
uni.onPushMessage((res) => {
console.log('推送消息详情:', JSON.stringify(res))
this.savePushLog(res)
})
// 保存推送记录
savePushLog(pushData) {
const logs = uni.getStorageSync('push_logs') || []
logs.unshift({
time: new Date().toISOString(),
data: pushData
})
uni.setStorageSync('push_logs', logs.slice(0, 100)) // 保留最近100条
}
常见错误处理
// 错误处理示例
uni.getPushClientId({
fail: (err) => {
switch(err.code) {
case 10001:
console.error('推送服务未初始化')
break
case 10002:
console.error('设备不支持推送')
break
default:
console.error('未知错误', err)
}
}
})
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
下一篇:uni-ui 官方组件库介绍