uniapp中的unipush中遇到的坑
项目用到了uniapp,而且用到了unipush,不得不说集合了很多功能在一点确实很好用,但是也有一些坑,需要一个一个的踩,而且官方文档说明不是很全,或者说说明全了,但是藏到了一些不显眼的角落,普通开发者找不到更是一头雾水。
接下来分析一下unipsuh
onLaunch: function() { this.$request.getConfigStorage() // #ifdef APP-PLUS const _self = this const _handlePush = function(message) {} plus.push.addEventListener('click', (message) => { console.log("click"); console.log(message); plus.push.clear(); plus.push.clear(); if (this.os == 1) { //ios let payload = message.payload if (message.payload && message.payload.id) { payload = message.payload } else { payload = JSON.parse(message.payload) } if (payload.id) { uni.navigateTo({ url: "/pages/chat/chat?id=" + payload.id }) } } else { //android if (message.payload.id) { uni.navigateTo({ url: "/pages/chat/chat?id=" + message.payload.id }) } } }); plus.push.addEventListener('receive', (message) => { console.log("receive"); console.log(message) if (message.payload.type == "chat") { if (this.os == 1) { //ios if (this.$request.isHide == true) { if (message.aps) { uni.navigateTo({ url: "/pages/chat/chat?id=" + message.payload.id }) } else { if (message.type == "receive") { let options = { cover: false, sound: "system", title: message.payload.title } plus.push.createMessage( message.payload.body, JSON.stringify(message.payload), options ) } } } } else { uni.navigateTo({ url: "/pages/chat/chat?id=" + message.payload.id }) } } }); // #endif this.$request.login() },
推送相关的监听肯定要放到
onLaunch: function() {}
比较靠谱。
注意看代码,我们用到了两个监听,无非就是想实现一个两个功能。
1、app离线后能正常接收到推送消息
2、用户点击通知栏的推送消息,跳转到相应的页面,具体跳那个页面,怎么跳我们这里不做研究,根据自己的项目自己设计吧。
我们这里就是把坑记录一下。
第一个坑,用到的uni.navigateTo,第一次用直接用HbuilderX代码提示,
uni.navigateTo({ url: "pages/chat/chat?id=" + message.payload.id })
就是这个效果,但是死活不跳转,很奇怪,同样的代码放到其他地方都可以,最后再pages前面加一个/ 变成
"/pages/chat/chat?id=" + message.payload.id
解决了。说实话,我也是瞎弄的,居然可以了!!!!
第二个坑,在ios中,如果app被关闭,推送消息能正常接收,但是app在前台或者app在后台,也就是没被关闭,通知栏没消息,后来发现是因为个推官方文档上面写着呢
那就想想其他办法吧,万幸的是个推通道推送还是能正常监听到receive回调的,那么就在receive回调中来创建一下通知栏通知吧
if (message.type == "receive") { let options = { cover: false, ound: "system", itle: message.payload.title } plus.push.createMessage( message.payload.body, JSON.stringify(message.payload), options ) }
注意,要把创建通知代码放到
if (message.type == "receive") {}
中,不然就是一个死循环了,至于为什么,不信邪的可以自己试一下,毕竟自己犯了错才会影响深刻。
第三个坑。在安卓中,app在前台,走个推通道时,用户点击通知栏消息,click监听中只能拿到title和body,拿到的payload自定义消息居然被个推自动编程了title和body,那么拿不到参数我咋知道该往哪个页面跳?
通过打印日志发现,虽然click事件中拿不到,但是receive事件中能拿到。
这里也有一个坑,就是app都在前台,在ios中,收到推送消息,ios可以出发receive回调,安卓不触发任何回调。。
但是点击通知,ios出发click回调,安卓click和receive都触发了。。。有点绕啊。具体自己测试一下发现吧
既然这样,那么在安卓中我们就要去在receive回调中去跳转到相应页面了,在click中就不行,所以
if (this.os == 1) { //ios if (this.$request.isHide == true) { if (message.aps) { uni.navigateTo({ url: "/pages/chat/chat?id=" + message.payload.id }) } else { if (message.type == "receive") { let options = { cover: false, sound: "system", title: message.payload.title } plus.push.createMessage( message.payload.body, JSON.stringify(message.payload), options ) } } } } else { uni.navigateTo({ url: "/pages/chat/chat?id=" + message.payload.id }) }
this.os =1时为ios,否则为安卓,好理解吧。
现在我们把app在线的坑踩完了,继续踩app离线的厂商通道。
当app离线时,用户收到推送消息,并点击,那么安卓ios都能触发click回调。
plus.push.addEventListener('click', (message) => { console.log("click"); console.log(message); plus.push.clear(); plus.push.clear(); if (this.os == 1) { //ios let payload = message.payload if (message.payload && message.payload.id) { payload = message.payload } else { payload = JSON.parse(message.payload) } if (payload.id) { uni.navigateTo({ url: "/pages/chat/chat?id=" + payload.id }) } } else { //android if (message.payload.id) { uni.navigateTo({ url: "/pages/chat/chat?id=" + message.payload.id }) } } });
那么拿到payload直接跳转就行了,
注意这里有一个坑,就是在ios中
let payload = message.payload if (message.payload && message.payload.id) { payload = message.payload } else { payload = JSON.parse(message.payload) }
有一段这个代码,为什么,因为这里有两种情况,一种是app在线和离线的区别,上面说过,ios中app在前台不是没有通知栏消息吗,需要我们自己创建
创建的通知栏消息中的payload需要用字符串,但是离线推过来的是json对象,我们要判断一下到底是json字符串还是jison对象。而安卓就没关系了,推送过来的payload都是json对象。
