UniPush 2.0 实战指南:工单提醒与多厂商通道配置

1. 方案选型与架构策略

1.1 云服务商选择:推荐腾讯云

在 uniCloud 的服务商选择上,针对企业级项目(尤其是涉及到工单、预警等需要稳定推送的场景),推荐选择 腾讯云

  • 核心优势 :开启"云函数 URL 化"时,腾讯云不需要重新进行域名备案(ICP备案),可以直接使用腾讯云提供的默认域名。
  • 成本考量:虽然单价略高于阿里云,但省去了繁琐的行政备案流程,对于项目快速上线和维护极为有利。

1.2 核心业务流程

我们需要实现的是"点对点"的工单通知,核心逻辑如下:

  1. 前端(APP端) :用户登录后,获取设备的 push_clientid
  2. 绑定关系 :前端调用云函数或接口,将 user_idpush_clientid 存入 uni-id-device 表中(建立用户与设备的映射)。
  3. 后端触发 :由于工单状态变更通常发生在后台(Java/Python/Go等),后端通过 HTTP 请求调用 云函数 URL 化接口
  4. 云函数执行 :云函数根据传入的 user_id 查库找到 CID,调用 uniPush 下发消息。

2. 云函数实现(Core Code)

此云函数作为统一的推送入口,处理了设备查找和多厂商参数适配。

JavaScript

javascript 复制代码
'use strict';
const uniPush = uniCloud.getPushManager({ appId: "__UNI__XXXXXX" }) // 替换你的 appId
const db = uniCloud.database();
const dbCmd = db.command;

exports.main = async (event, context) => {
    // 假设后端通过 POST 请求传入 JSON body
    let body = event.body;
    if(event.isBase64Encoded){
        body = Buffer.from(body, 'base64').toString('utf8');
    }
    const { userIds, title, content } = JSON.parse(body);

    try {
        // --- 3. 查库:获取目标用户的 Push Client ID ---
        const deviceRes = await db.collection('uni-id-device')
            .where({
                user_id: dbCmd.in(userIds)
            })
            .field({ 'push_clientid': true })
            .get();

        if (deviceRes.data.length === 0) {
            return { code: 404, msg: '指定的用户均未绑定任何设备' };
        }

        // 去重,防止同一设备收到多条(如果用户多端登录)
        const cids = [...new Set(deviceRes.data.map(item => item.push_clientid))];

        // --- 4. 执行推送:配置多厂商通道 ---
        const pushRes = await uniPush.sendMessage({
            "push_clientid": cids,
            "title": title,
            "content": content,
            "force_notification": true, // 强制显示通知栏
            "request_id": context.requestId,
            "options": {
                "android": {
                    // --- 小米 (XM) 配置 ---
                    "XM": {
                        // 必须在小米后台申请 Channel ID,否则可能被折叠或静音
                        "/extra.channel_id": "你的小米ChannelID", 
                    },
                    // --- 华为 (HW) 配置 ---
                    "HW": {
                        // 必须配置自分类权益,"SERVICE" 为服务提醒,权重高于默认
                        "/message/android/category": "WORK", // 或 SERVICE
                    },
                    // --- OPPO (OP) 配置 ---
                    "OP": {
                        "/channel_id": "你的OPPO通道ID",
                        "/category": "MARKETING", // 注意:OPPO 营销类消息限制较多,重要通知建议申请私信通道
                        "/notify_level": 16
                    },
                    // --- VIVO (VV) 配置 ---
                    "VV": {
                        "/classification": 1, // 1: 系统类消息 (需要申请),0: 运营类
                    }
                }
            }
        });

        // --- 5. 返回结果 ---
        return {
            code: 0,
            msg: '推送请求已下发',
            target_user_count: userIds.length,
            target_device_count: cids.length,
            uni_push_result: pushRes
        };

    } catch (e) {
        console.error(e);
        return {
            code: 500,
            msg: '服务端内部错误',
            error: e.message
        };
    }
};

3. 安卓厂商特殊配置(必读)

随着 Android 8.0+ 通知渠道(Notification Channels)的引入,如果不进行额外配置,工单提醒很可能会被归类为"营销广告"从而静音折叠

3.1 小米 (Xiaomi) 配置

小米需要创建自定义 Channel 才能让消息正常响铃或震动。

  1. 操作路径:小米开放平台 -> 消息推送 -> 配置管理 -> 通知类别(Channel)管理。

  2. 申请:新建一个类别,例如"工单提醒"或"事务通知"。

  3. 获取 ID :申请通过后,会获得一个 Channel ID(如 Channel_A)。

  4. 代码映射

    JavaScript

    json 复制代码
    "XM": {
        "/extra.channel_id": "你申请的Channel_ID" 
    }

    注意:如果不填,默认走"普通消息"通道,限制较多。

3.2 华为 (Huawei) 配置

华为引入了"自分类权益",需要将消息分类为"服务与通讯"类,否则会被当做"资讯营销"处理。

  1. 操作路径 :华为开发者联盟 -> 我的项目 -> 推送服务 -> 配置 -> 自分类权益

  2. 申请权益:点击申请,按照指引填写(通常需要上传APP截图证明场景)。

  3. 参数设置

    • 在代码中设置 category 字段。
    • WORK:工作事项提醒(适合工单)。
    • IM:即时聊天。
    • 如果不传,默认为 MARKETING(营销),极易被拦截。

    JavaScript

    json 复制代码
    "HW":{
        "/message/android/category": "WORK" 
    }

3.3 OPPO & VIVO 注意事项

  • OPPO :同样有 Channel 概念。私信通道(高权重)需要单独申请邮件报备,且门槛较高。代码中演示的 MARKETING 仅供测试,正式上线建议申请 IM 或业务相关通道。
  • VIVOclassification 为 1 代表系统消息,0 代表运营消息。系统消息配额更高,提醒更明显。

4. 故障排查流程 (Troubleshooting)

当消息没有送达时,请按以下步骤排查:

📌 阶段一:基础环境检查

  1. CID 是否获取成功 :前端 uni.getPushClientId 是否拿到了 ID?如果是在模拟器运行,通常无法获取有效的厂商 CID。

  2. 云函数报错 :查看 uniCloud Web 控制台的云函数日志,检查是否有 appId 不匹配或数据库查询为空的情况。

  3. 打包检查

    • UniPush 2.0 严重依赖应用签名。
    • 必须使用正式签名打包的自定义基座进行调试,标准基座无法测试厂商通道。
    • 确保 manifest.json 中勾选了 UniPush 2.0 并正确填写了各厂商的 AppID/AppKey。

📌 阶段二:离线推送检查(厂商通道)

如果 APP 打开时能收到(走的是个推在线通道),但杀掉进程后收不到(走的是厂商通道),则是厂商配置问题

  1. 检查厂商后台开关:确保在华为/小米等后台,推送服务已"启用"。

  2. 包名与签名 SHA1

    • 华为/小米后台填写的 SHA256SHA1 必须与你打包证书的指纹完全一致
    • 这是最常见的错误原因。
  3. 参数映射

    • 检查云函数代码中 options 里的参数键值对是否按照厂商最新文档编写(如华为的 category 拼写)。
  4. 限流与配额

    • 如果是测试阶段,某些厂商(如 VIVO/OPPO)对未上架应用的推送数量有限制(如一天只能推几条)。

参考文档

相关推荐
快手技术6 小时前
入围AA总榜Top 10,Non-Reasoning Model榜单第一!KAT-Coder-Pro V1 新版本踏浪归来!
前端·后端·前端框架
wangpq6 小时前
记录曾经打开半屏小程序遇到的事
前端·微信小程序
king王一帅6 小时前
告别 AI 输出的重复解析:正常 markdown 解析渲染也能提速 2-10 倍以上
前端·javascript·ai编程
dudke6 小时前
js的reduce详解
开发语言·javascript·ecmascript
huangql5206 小时前
网络体系结构在Web前端性能优化中的应用完全指南
前端·性能优化
代码or搬砖6 小时前
ES6新增的新特性以及用法
前端·javascript·es6
LYFlied6 小时前
【一句话概述】前端性能优化从页面加载到展示
前端·性能优化
小番茄夫斯基6 小时前
Monorepo 架构:现代软件开发的代码管理革命
前端·javascript·架构
一只秋刀鱼6 小时前
从 0 到 1 构建 React + TypeScript 车辆租赁后台管理系统
前端·typescript