news 2026/5/12 1:37:46

java+uniapp集成unipush2实现消息推送

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
java+uniapp集成unipush2实现消息推送

一、开通uniPush2.0
1.实名认证
登录DCloud开发者中心,通过实名认证

2.进入UniPush控制台
HBuilderX中打开项目的manifest.json文件
导航在“App模块配置” → 项的“Push(消息推送)” → “UniPush”下点击配置 或者申请开通。

3.配置应用信息
在UniPush开通界面配置以下信息:
Android包名
Android应用签名
iOS Bundle Id 点击"开通"完成服务启用

详细说明请参考 UniPush开通指南
二、前端推送服务对接

  1. 配置uniCloud服务
    开通uniCloud服务(推荐阿里云)
    创建云函数,用于处理推送逻辑
    详细步骤参考官方文档

  2. 添加push模块
    设置targetSdkersion(targetSdkersion过高有些手机运行不了)

找到刚刚添加的push模块,创建云函数处理推送请求:

云函数关键,不要乱写,看不懂示例就复制我这个

'use strict';/** * 推送吃药提醒 - DCloud UniPush 2.0 云函数 */exports.main=async(event,context)=>{console.log('========== UniPush云函数被调用 ==========');console.log('请求方法:',event.httpMethod);// 解析请求体letparams;try{if(event.httpMethod==='POST'){if(typeofevent.body==='string'&&event.body){params=JSON.parse(event.body);}elseif(typeofevent.body==='object'&&event.body!==null){params=event.body;}else{return{code:-1,msg:'POST请求体为空或格式错误'};}}elseif(event.httpMethod==='GET'){return{code:0,msg:'UniPush 云函数运行正常',data:{method:'GET',time:Date.now(),tip:'请使用 POST 方法发送推送请求'}};}else{return{code:-1,msg:'不支持的请求方法: '+event.httpMethod};}}catch(e){console.error('解析请求体失败:',e);return{code:-1,msg:'请求体格式错误: '+e.message};}const{cid,title,content}=params;console.log('解析后的参数:',{cid,title,content});// 参数校验if(!cid||!title||!content){console.error('参数不完整');return{code:-1,msg:'参数不完整,需要: cid, title, content',received:params};}try{console.log('开始初始化UniPush...');// 获取 UniPush 管理器constuniPush=uniCloud.getPushManager({appId:"__UNI__xxxxxxx"// ⚠️ 替换为您的实际 AppID});console.log('UniPush初始化成功,开始发送消息...');// 构建推送参数constpushParams={"push_clientid":cid,"title":title,"content":content,"payload":{"type":"medicine_reminder","time":Date.now()},// 添加以下参数确保通知显示"force_notification":true,// 强制显示通知栏"sound":"default",// 提示音"badge":1// iOS角标};console.log('推送参数:',JSON.stringify(pushParams));// 发送推送消息constresult=awaituniPush.sendMessage(pushParams);console.log('推送结果:',result);// 检查推送结果if(result.errCode===0){// 检查具体设备的推送状态constdeviceStatus=result.data?Object.values(result.data)[0]:null;console.log('设备推送状态:',deviceStatus);return{code:0,msg:'推送成功',data:result};}else{console.error('推送失败:',result);return{code:-1,msg:'推送失败: '+(result.errMsg||'未知错误'),detail:result};}}catch(error){console.error('推送异常:',error);return{code:-1,msg:'推送异常: '+error.message};}};

传部署云函数代码
配置云函数URL化
进入uniCloud控制台
找到已上传的云函数并查看详情

配置云函数url化,设置URL的PATH部分(作用是,后端直接调接口然后进行推送)
完成后获得完整URL用于后端调用
三、后端推送服务对接

packagecom.ruoyi.app.service.impl;importcom.fasterxml.jackson.databind.ObjectMapper;importcom.ruoyi.app.service.IUniPushService;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.http.*;importorg.springframework.stereotype.Service;importorg.springframework.util.StringUtils;importorg.springframework.web.client.RestTemplate;importjava.util.*;/** * UniPush 2.0 推送服务实现(支持Android和iOS) * 使用云函数方式调用个推API * * @author ruoyi */@Slf4j@ServicepublicclassUniPushServiceImplimplementsIUniPushService{@Value("${unipush.cloud-function-url:}")privateStringcloudFunctionUrl;privatefinalRestTemplaterestTemplate=newRestTemplate();privatefinalObjectMapperobjectMapper=newObjectMapper();/** * 调用云函数发送推送 */privatebooleancallCloudFunction(Map<String,Object>requestBody){try{if(!StringUtils.hasText(cloudFunctionUrl)){log.error("❌ UniPush云函数地址未配置,请在application.yml中配置 unipush.cloud-function-url");returnfalse;}// 打印请求体用于调试StringjsonBody=objectMapper.writeValueAsString(requestBody);log.info("📤 UniPush云函数请求 - URL: {}",cloudFunctionUrl);log.info("📤 UniPush云函数请求体: {}",jsonBody);// 发送请求HttpHeadersheaders=newHttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);HttpEntity<String>entity=newHttpEntity<>(jsonBody,headers);ResponseEntity<Map>response=restTemplate.postForEntity(cloudFunctionUrl,entity,Map.class);if(response.getStatusCode()==HttpStatus.OK&&response.getBody()!=null){Map<String,Object>body=response.getBody();log.info("📥 UniPush云函数响应: {}",body);// 检查是否是echo响应(云函数未正确实现)if(body.containsKey("path")&&body.containsKey("httpMethod")){log.error("❌ 云函数返回了echo响应,说明云函数未正确实现推送逻辑");log.error("❌ 请检查云函数代码,确保实现了推送功能而不是简单返回请求");returnfalse;}// 判断是否成功 - 支持多种响应格式// 格式1: {code: 0, msg: "success"}ObjectcodeObj=body.get("code");if(codeObj!=null){Stringcode=codeObjinstanceofInteger?String.valueOf(codeObj):codeObj.toString();if("0".equals(code)||"200".equals(code)){log.info("✅ UniPush推送成功");returntrue;}else{log.error("❌ UniPush推送失败,错误码: {}, 消息: {}",code,body.get("msg"));returnfalse;}}// 格式2: {success: true}ObjectsuccessObj=body.get("success");if(successObjinstanceofBoolean&&(Boolean)successObj){log.info("✅ UniPush推送成功");returntrue;}// 格式3: {status: "success"}ObjectstatusObj=body.get("status");if(statusObj!=null&&"success".equalsIgnoreCase(statusObj.toString())){log.info("✅ UniPush推送成功");returntrue;}log.error("❌ UniPush推送失败,响应内容: {}",body);}else{log.error("❌ UniPush云函数响应异常 - 状态码: {}",response.getStatusCode());}returnfalse;}catch(org.springframework.web.client.HttpClientErrorExceptione){log.error("❌ UniPush云函数调用失败 - HTTP状态码: {}",e.getStatusCode());log.error("❌ 响应内容: {}",e.getResponseBodyAsString());log.error("❌ 请检查:");log.error(" 1. 云函数URL是否正确: {}",cloudFunctionUrl);log.error(" 2. 云函数是否已部署并启用HTTP触发器");log.error(" 3. 云函数是否正确实现了推送逻辑");returnfalse;}catch(org.springframework.web.client.ResourceAccessExceptione){log.error("❌ UniPush云函数网络访问异常: {}",e.getMessage());log.error("❌ 请检查:");log.error(" 1. 网络连接是否正常");log.error(" 2. 云函数地址是否可访问");log.error(" 3. 防火墙或代理设置");returnfalse;}catch(Exceptione){log.error("❌ UniPush云函数调用异常",e);returnfalse;}}@OverridepublicbooleanpushToSingle(Stringcid,Stringtitle,Stringcontent){try{if(!StringUtils.hasText(cid)){log.warn("推送失败:cid为空");returnfalse;}// 构建请求体 - 直接传递参数,不使用 action/data 结构Map<String,Object>requestBody=newjava.util.LinkedHashMap<>();requestBody.put("cid",cid);requestBody.put("title",title);requestBody.put("content",content);// 调用云函数booleansuccess=callCloudFunction(requestBody);if(success){log.info("单推消息成功,cid: {}, title: {}",cid,title);}else{log.error("单推消息失败,cid: {}, title: {}",cid,title);}returnsuccess;}catch(Exceptione){log.error("单推消息异常,cid: {}, title: {}",cid,title,e);returnfalse;}}@OverridepublicbooleanpushToList(List<String>cids,Stringtitle,Stringcontent){try{if(cids==null||cids.isEmpty()){log.warn("推送失败:cid列表为空");returnfalse;}// 注意:云函数只支持单个CID推送,需要循环调用log.info("批量推送:将逐个推送给 {} 个设备",cids.size());intsuccessCount=0;for(Stringcid:cids){booleanresult=pushToSingle(cid,title,content);if(result){successCount++;}// 避免频繁请求,间隔100mstry{Thread.sleep(100);}catch(InterruptedExceptione){Thread.currentThread().interrupt();}}booleanallSuccess=successCount==cids.size();if(allSuccess){log.info("批量推送消息成功,数量: {}, title: {}",cids.size(),title);}else{log.warn("批量推送部分成功,成功: {}/{}, title: {}",successCount,cids.size(),title);}returnallSuccess;}catch(Exceptione){log.error("批量推送消息异常,title: {}",title,e);returnfalse;}}@OverridepublicbooleanpushToAll(Stringtitle,Stringcontent){try{log.warn("全量推送功能未实现,云函数不支持全量推送");log.warn("如需全量推送,请先从数据库获取所有用户的CID,然后使用 pushToList 方法");returnfalse;}catch(Exceptione){log.error("全量推送消息异常,title: {}",title,e);returnfalse;}}}

重点,发消息需要cid,app获取到传给后端保存,cid可能会更新,一般登录的时候传。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/12 1:36:56

TCPA与CGRA架构对比:原理、性能与选型指南

1. TCPA与CGRA架构原理对比在可重构计算领域&#xff0c;时序控制处理器阵列&#xff08;TCPA&#xff09;和粗粒度可重构架构&#xff08;CGRA&#xff09;代表了两种截然不同的设计哲学。TCPA采用全局控制器&#xff08;GC&#xff09;统一调度所有处理单元&#xff08;PE&am…

作者头像 李华
网站建设 2026/5/12 1:36:41

用PyTorch从零实现REINFORCE算法:一个完整的离散与连续动作空间实战教程

用PyTorch从零实现REINFORCE算法&#xff1a;一个完整的离散与连续动作空间实战教程 强化学习领域近年来发展迅猛&#xff0c;其中策略梯度方法因其直接优化策略的特性备受关注。REINFORCE作为最基础的策略梯度算法&#xff0c;是理解更复杂方法的基石。本文将带你从零开始&…

作者头像 李华
网站建设 2026/5/12 1:35:34

液态硅胶注塑加工供应商推荐

随着液态硅胶&#xff08;LSR&#xff09;在医疗、母婴、电子、汽车等多个领域的广泛应用&#xff0c;选择一个可靠的液态硅胶注塑加工供应商变得至关重要。作为天沅智能制造科技有限公司&#xff08;简称TYM&#xff09;&#xff0c;我们不仅深耕于液态硅胶注射成型机械的设计…

作者头像 李华
网站建设 2026/5/12 1:32:02

从 Fork 到第一个 PR:开源新手最完整的一次实战

从 Fork 到第一个 PR&#xff1a;开源新手最完整的一次实战 很多开源新手第一次真正想“做点贡献”&#xff0c;通常会卡在两个地方。 第一是不会找入口&#xff0c;不知道从哪里改起&#xff1b;第二是不会走流程&#xff0c;不知道 Fork、Branch、Commit、Push、PR 之间到底…

作者头像 李华
网站建设 2026/5/12 1:31:33

AI代理工具化新范式:基于MCP协议的模块化连接器实践

1. 项目概述&#xff1a;一个面向AI代理的模块化连接器最近在折腾AI应用开发&#xff0c;特别是围绕AI Agent&#xff08;智能体&#xff09;的生态构建时&#xff0c;发现一个挺普遍的问题&#xff1a;如何让这些Agent高效、安全地连接和使用外部工具与服务&#xff1f;无论是…

作者头像 李华