UniApp 推送服务 UniPush踩坑记录

  1.  
    ===========================================================================
    华为厂商配置,提示验证错误(Client Secret配置有错误.)
    ===========================================================================
    IOS发送通知
    如果应用使用了uniPush(发送消息通知)功能,在应用启动时会弹出“发送通知”系统授权框
     
    这是因为应用启动时会自动向系统注册要使用消息推送功能引起,如果希望在应用启动时不弹出此授权框,HBuilderX2.6.3+版本可以按以下方法配置配置应用启动时不注册。
    在用户接受隐私政策后调用异步获取客户端推送标识信息方法 plus.push.getClientInfoAsync进行注册。

    配置方法

    打开项目的manifest.json文件,切换到“源码视图”项
    • uni-app项目
    在 "app-plus" -> "distribute" -> "ios" 节点下添加 pushRegisterMode节点
    • 5+ App项目
    在 "plus" -> "distribute" -> "apple" 节点下添加 pushRegisterMode节点
    pushRegisterMode字段值设置如下:
     
    "pushRegisterMode": "manual"
    注意plus.push.getClientInfo是同步方法,不会触发向系统注册操作,必须使用异步方法 plus.push.getClientInfoAsync
    配置后提交云端打包后生效
     
    ===========================================================================
    点击消息如何实现页面跳转
    在线消息:
    由于Dcloud封装. 在线需要推送透传消息,客户端在透传receive回调中接收透传消息后,自行处理页面的跳转问题;透传消息支持json格式,即支持设置自定义参数值,客户端根据监控参数不同的值判断跳转不同的内部页面。
    离线消息:
    android:
    • 服务端push_channel.android必须内必须设置安卓跳转页面的参数intent,参数为固定格式:intent://io.dcloud.unipush/?#Intent;scheme=unipush;launchFlags=0x4000000;component=请填您的包名/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title=测试标题;S.content=测试内容;S.payload=test;end
    • 于Dcloud封装,使用固定的intent,消息点击默认只支持跳转到应用首页,不支持intent中直接给定Dcloud的插件页面路径。当用户点击通知后,会携带intent的值触发客户端click回调方法, 客户端可根据接收的参数再调用客户端跳转方法实现自定义页面跳转。
    ios:
    • 服务端push_channel.ios内必须设置ios的自定义参数payload,参数为任意值。
    • 当用户点击通知后,会携带payload的值触发客户端receive回调方法, 客户端可根据接收的参数再调用客户端跳转方法实现自定义页面跳转。
    客户端跳转方法:
    复制代码
    uni.navigateTo({
    //页面路径示例值:/pages/pushinfo/pushinfo
    url:'指定页面路径'
    })
    添加监听事件:click点击事件与receive接收事件
    在onLaunch函数中,给这个应用添加两个监听事件,一个是click监听点击事件,一个是receive监听接收事件。
    对于安卓的在线和离线消息以及IOS的离线消息都是走的click监听事件。也就是说可以直接将消息推送到手机通知栏中,然后点击消息的时候,可以触发应用监听的点击事件,继而获取到事件数据中的payload,这个参数给定的格式是 页面路径+id,例如:/pages/user/info?id=14234132,我在/pages/user/info这个页面有做处理,可以获取到optons中的值继而获取消息详情内容。
    click事件中的防抖的必要性
    之所以加了一个防抖(也就是定时器,在指定时间内只能触发一次),是因为我一开始将监听事件放在了app.vue中的onshow生命周期函数中,这样就导致页面一直在接收消息,所以才加了一个防抖,但是后来才发现应该加载onlaunch中,但是防抖还是留了下来,因为app离线的时候,点击通知栏中的消息唤醒app时,需要app启动时间,如果是直接跳转到消息页面,则app启动后会自动跳转到首页,也就是造成消息详情页面闪现的效果。
    因此,通过延时1.5秒后再进行消息页面的跳转,给1.5秒应用启动的时间,然后通过uni.navigateTo的路由跳转的方法进行跳转到消息页面,点击返回按钮还可以回到首页,这个才是正确的步骤。
    receive事件的处理
    页面中的冗余代码应该去掉,只保留else里面的代码即可。。
    plus.push.createMessage(content,payload,options)这个创建消息的方法是可以通过百度查找到的,而且有详细的参数介绍。
    第一个参数:content,必填项,也即是消息的内容部分
    第二个参数:payload,选填项,因为页面的跳转是获取的payload中的值,因此我需要这个参数
    第三个参数:options,选填项,options是其他参数,cover:false是否覆盖上次通知,默认false,title标题,也即是消息除了需要展示内容之外,还需要展示一下标题部分。
    如果不加外面的msg.type的判断,则会出现一直创建消息的效果,接收到消息(receive),然后创建成功(plus.push.createMessage)后,消息的type类型会改变,则可以通过type类型的改变来解决一直弹窗创建消息的问题。
    ===========================================================================
    1. 在App.vue文件onLaunch方法中具体代码表现为:
    plus.push.setAutoNotification(true)
     
    //【APP在线】,收到透传消息通过,不会提醒至通知栏目,需要发送本地消息,再进行点击触发的点击事件。
    //【APP离线】,收到离线透传消息,必须通过Java后台的Intent字符串携带payload,且符合格式才能触发click事件,格式不符合不会触发
    plus.push.addEventListener("click", function(msg) {
    var payload;
    console.log("addEventListener click:" + JSON.stringify(msg));
    if (isIOS) {
    //APP离线点击包含click属性,这时payload是JSON对象
    if (msg.type && msg.type == "click") {
    payload = msg.payload;
    } else {
    //APP在线,收到消息不会包含type属性,这时的payload是JSON字符串,需要转为JSON对象
    payload = JSON.parse(msg.payload);
    }
    navigateTo(payload)
    } else {
    payload = JSON.parse(msg.payload);
    if (typeof payload === "string") {
    payload = JSON.parse(payload)
    }
    navigateTo(payload)
    }
    }, false);
     
     
    plus.push.addEventListener('receive', function(msg) {
    console.log("addEventListener receive:" + JSON.stringify(msg));
    if (isIOS) {
    //【APP离线】收到消息,但没有提醒(发生在一次收到多个离线消息时,只有一个有提醒,但其他的没有提醒)
    //【APP在线】收到消息,不会触发系统消息,需要创建本地消息,但不能重复创建。必须加msg.type验证去除死循环
    if (!msg.aps && msg.type == "receive") {
    //创建本地消息,发送的本地消息也会被receive方法接收到,但没有type属性,且aps是null
    plus.push.createMessage(msg.content, JSON.stringify(msg.payload), { title: msg.title });
    }
    } else {
    //如果是Android,当APP在线时,收到透传消息不会进入系统消息,需要发送本地提醒。
    plus.push.createMessage(msg.content, JSON.stringify(msg.payload), { title: msg.title });
    }
    });
    ===========================================================================
    华为离线,厂商
    华为 unipush的推送的消息被系统视为营销通知,营销通知是静默通知
    ===========================================================================
    推送主要用到两个方法, click和receive
    click 为点击了状态栏里的提示的监听回调
    receive 为app在前台打开时,接收到后台的推送后的监听回调
    如果应用不保活,则不会接受receive , receive消息会有一定的存储期 , 存储期由后台人员编写设置, 应用下次打开,存储期的应用会挨个出发receive
    receive接受到的消息,不会显示在状态栏, 换言之不会有提示,仅仅是一个回调,客户端,需要使用5+api plus.push.createMessage() 来自己设置参数,弹出状态栏的提示框
    状态栏的图标默认是打包 客户端的logo图
    当receive接受到的消息时,可以让后台设置在线个推,离线厂商,但是本人注册了个平台的推送开发者,发现,没什么用, 而且,receive一直可以接收到,, 作者估计和手机的设置有关,,只有在手机的应用程序里强制停止了才算关掉? 我的华为,是关了后台,没有强制停止,收不到消息,,,我的一加8,关了后台,没强制停止,可以接受到, 就很魔性。
    最后一点,需要在合适的页面,调用后台接口,将最开始获取 clientid 传给后端, 一台移动设备的 clientid 是固定的, 后端用次字段,判断消息发送给谁
    ===========================================================================
    关于推送的监听问题
    推送的消息分为两种 ,1:通知消息 2:透传消息
    (1)通知消息的推送 ,会在消息中心显示,点击通知启动(激活)应用到前台运行,触发“click”事件。
    (2)透传数据的推送,可以响应click和receive。
     
    1. 发送透传数据的格式是标准格式({title:"通知标题",content:"通知内容",payload:"通知测试"}),会在消息中心展示,并且这个时候当用户点击这个消息,就会响应click事件,只能响应click事件。
     
    1. 发送的透传数据不是标准格式并且当前应用在活动,同时满足这些条件,才可以响应receive事件,并且不会在消息中心展示。
     
    总结为:
     
    • 触发click事件: 发送透传数据并且格式为标准格式,会在消息中心展示。
     
    • 触发receive事件:发送透传数据且格式为非标准格式且应用在活动,不会在消息状态栏显示。
     
    ios:
     
    • 在线:只能响应receive,不会在系统消息中心显示推送通知。
     
    • 离线:使用苹果APNS通道下发推送通知,手机接收后在系统通知栏中显示,点击消息后启动应用(如果已经启动则从后台切换到前台),同时触发“click”事件。
     
    Android:
     
    • 在线(个推推送通道可用):推送通知和透传消息都使用个推的推送通道下发推送消息。
     
    • 离线(个推推送通道不可用):如果符合厂商推送的厂商手机(配置了手机厂商推送参数并且在对应厂商的手机上),则使用厂商推送通道下发推送消息;否则使用个推的离线推送通道,离线消息会存储在消息离线库,离线时间内APP在线后下发推送消息。
    ===========================================================================
    【1】关于receive事件,只有发送的是透传数据【而且】不是标准格式【而且】当前应用在活动,这3个条件同时满足,才可以响应receive事件!!!,但是消息中心并没有消息展示!!!需要创建本地消息!!!才能在消息中心提醒,对于IOS的,一定要控制死循环!!!【重要】【重要】【重要】
    只有APP在线时,才会触发receive事件,透传消息不会触发系统消息,需要创建本地消息【重要】【重要】【重要】
    【2】关于click事件,click一定是点击通知栏的消息,才能触发!!! 下面两句话很重要
    【APP在线】收到透传消息通过,不会提醒至通知栏目,需要发送本地消息,再进行点击触发的点击事件。
    【APP离线】收到离线透传消息,必须通过Java后台的Intent字符串携带payload,且符合格式才能触发click事件,格式不符合不会触发。
    【3】厂商推送需要设置的Intent字符串格式,
    请将${packageName},${title},${content},${payload}替换为正确的内容
    ${packageName} 代表应用包名
    ${title} 通知的标题
    ${content} 通知的内容
    ${payload} 其他附加参数,请用 JSON.toJSONString(payload)进行转码。
    intent:#Intent;launchFlags=0x04000000;action=android.intent.action.oppopush;package=${packageName};component=${packageName}/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title=${title};S.content=${content};S.payload=${payload};end
    ===========================================================================
    前阵子遇到这种问题,离线的应用客户如果有需要处理的文件,收不到提醒信息。
     
    解决方案如下:
     
    1.根据你APP的用户数量在平台开通消息推送VIP账号服务。
     
    2.在各大手机厂商开放平台申请开发者 添加消息推送应用,记录应用的APPID
     
    3.将APPID配置到平台应用配置相关的参数里面。
     
    4.收集获取用户手机的设备ID和用户ID关联记录到表里面。
    ===========================================================================
    三、问题总结
    1、厂家通道中包名与uni-app云打包中的包名不一致
    2、没有在配置好后台完成后,重新进行云打包(如果遇到接收不到消息,可重新打包测试)
    3、通知类型中的应用包名填写错误
    4、IOS系统的话需要注意打包的证书和推送的证书需要是同一个环境的,不同证书同样会推送失败(已踩坑)
    我本人测试用的小米手机,也遇到了一些问题
    1、应用权限没有开启后台弹出界面权限,导致接收不到通知(检查设备是否有禁止后台弹出界面,路径>>设置-应用管理-测试应用-权限管理-后台弹出界面)
    2、没有将通知设置为重要通知(检查应用通知管理权限页面,系统推荐按设置为重要通知)
    ===========================================================================
    ===========================================================================
    在线推送的话基本是秒推,但是离线通过厂商推送,可能有延迟,目前仅配置了华为,经过多次测试,信息到达时间不确定,有时候秒到,有时候可能几分钟甚至几十分钟,由于有时候等待时间比较长,所以未统计是否都到达,大部分应该都会到达。
    ===========================================================================
posted @ 2022-05-07 12:18  YoYo/切克闹  阅读(3811)  评论(1编辑  收藏  举报