uniapp消息推送云函数

消息推送属于敏感操作,只能直接或间接由服务端触发。传统的三方push服务,需要开发者在服务端配置密钥或证书,根据服务器端文档签名获取token,再向相关URL接口发起网络请求......
而UniPush2.0,开发者无需关心证书、签名、服务器端文档,使用简单。云函数通过 uni-push服务端sdk,即uni-cloud-push的API即可直接执行uniPush所有操作。
uni-push的服务端sdk的体积不小,没有内置在云函数中。在需要操作uni-push的云函数里,开发者需手动配置uni-cloud-push扩展库。 (uniCloud扩展库,是uniCloud自带API中不常用且包体积较大的部分,被独立为扩展库,可以由开发者自行选择是否使用该扩展库)。

一、云函数的创建

在项目文件最外层右键创建unicloud云开发环境

右键创建好的目录选择要关联的云服务空间或项目

打开uniCloud 在云函数目录下右键新建一个云函数,添加推送公共模块

二、云函数的执行

在云函数文件目录右键(或按快捷键ctrl + r)-> 上传并运行云函数,此时你的客户端将收到推送消息(应用关闭时为通知栏消息,在线时代码监听到推送消息)。

云函数中调用uni-cloud-push扩展库的sendMessage方法,向客户端推送消息

javascript 复制代码
// 简单的使用示例  
'use strict';  
const uniPush = uniCloud.getPushManager({appId:"__UNI__XXXXXX"}) //注意这里需要传入你的应用appId  
exports.main = async (event, context) => {  
    return await uniPush.sendMessage({  
        "push_clientid": "xxx",     //填写上一步在uni-app客户端获取到的客户端推送标识push_clientid  
        "force_notification":true,  //填写true,客户端就会对在线消息自动创建"通知栏消息"。  
        "title": "推送标题",      
        "content": "推送内容哈哈哈哈",  
        "payload": {  
            "text":"体验一下uni-push2.0"  
        }  
        "options":{  
            "HW": {  
                 // 1 表示华为测试消息,华为每个应用每日可发送该测试消息500条,此target_user_type 参数请勿发布至线上。  
                  "/message/android/target_user_type":1  
              }  
        }  
    })  
};

在线消息无额度限制。离线推送各厂商的限额,详见: 厂商通道限额

如果你希望当应用在线时,也通过"通知栏消息"来提醒用户;可以通过以下两种方式实现:

  1. 监听到消息内容后,根据业务需要自己判断是否要创建"通知栏消息",需要就调用创建本地消息API uni.createPushMessage手动创建通知栏消息。
  1. 服务端执行推送时,传递参数force_notification:true,客户端就会自动创建"通知栏消息"(此时你监听不到消息内容),当用户点击通知栏消息后,APP才能监听到消息内容。

检查确认当前 app 的通知栏权限开启后,则可以开始进行推送测试。

运行结果

云函数代码示例

javascript 复制代码
// 简单的使用示例  
'use strict';
const uniPush = uniCloud.getPushManager({
  appId: ""
}) //注意这里需要传入你的应用appId  
exports.main = async (event) => {
  console.log("入参", event.body);
  let obj = event.body ? JSON.parse(event.body) : {};
  try {
    const res = await uniPush.sendMessage({
      "push_clientid": obj.cids.split(","), // 设备id,支持多个以数组的形式指定多个设备,如["cid-1","cid-2"],数组长度不大于1000  
      "title": obj.title, // 标题  
      "content": obj.content, // 内容  
      "payload": obj.data, // 数据  
      "force_notification": true, // 服务端推送 需要加这一句  
      "request_id": obj.request_id, //请求唯一标识号,10-32位之间;如果request_id重复,会导致消息丢失  
      // "options":obj.options, //消息分类,没申请可以不传这个参数  
    })
    return {
      msg:"消息发送成功"
    }
  } catch (e) {
    //TODO handle the exception
    return {
      errCode: 1,
      errMsg: e.toString()
    }
  }

};

三、云函数URL化

在 uniCloud 的云函数中,加载扩展库 uni-cloud-push,直接调用相关 API,无需额外的服务端配置。

传统服务器开发者(例如:Java、php、python等)需要把这个 云函数URL化 后变成 http 接口,再由代码调用这个 http 接口。

在unicloud控制台中点击查看已经上传的云函数配置url

api 工具测试请求

结果

四、客户端监听消息

客户端监听推送消息的代码,需要在收到推送消息之前被执行。所以应当写在应用一启动就会触发的 应用生命周期 onLaunch中。

示例代码:

ini 复制代码
    onLaunch: function() {
      uni.onPushMessage((res) => {
        console.log("收到推送消息:", res); //监听推送消息
        if (res.data.payload) {
          let id = res.data.payload.ids;
          let role = uni.getStorageSync("role");
          if (id) {
            if (role == 1) {
              if (res.data.payload.orderStatus == 1) {
                uni.switchTab({
                  url: '/pages/home/driver',
                })
              } else {
                uni.navigateTo({
                  url: `/pages/driverOrder/detail?id=${id}&type=push`,
                });
              }
              return;
            }
            uni.navigateTo({
              url: `/pages/home/order?id=${id}&type=push`,
            });
          }
        }
      });
    },

由于使用了uniPush(发送消息通知)功能,在应用首次启动时ios会弹出"发送通知"系统授权框,安卓并不弹,所以我们需要自己写一个检测消息通知是否打开,这也方便了我们以后随时提醒用户打开消息通知

ini 复制代码
// 判断消息通知是否打开
//监听 是否开启权限
export const getNotificationEnabled = () => {
  // #ifdef APP-PLUS
  if (plus.os.name == 'Android') { // 判断是Android
  	var main = plus.android.runtimeMainActivity();
  	var pkName = main.getPackageName();
  	var uid = main.getApplicationInfo().plusGetAttribute("uid");
  	var NotificationManagerCompat = plus.android.importClass("android.support.v4.app.NotificationManagerCompat");
  	//android.support.v4升级为androidx
  	if (NotificationManagerCompat == null) {
  		NotificationManagerCompat = plus.android.importClass("androidx.core.app.NotificationManagerCompat");
  	}
  	var areNotificationsEnabled = NotificationManagerCompat.from(main).areNotificationsEnabled();
  	// 未开通'允许通知'权限,则弹窗提醒开通,并点击确认后,跳转到系统设置页面进行设置  
  	if (!areNotificationsEnabled) {
  		uni.showModal({
  			title: '通知权限开启提醒',
  			content: '您还没有开启通知权限,无法接受到消息通知,请前往设置!',
  			showCancel: false,
  			confirmText: '去设置',
  			success: function(res) {
  				if (res.confirm) {
  					var Intent = plus.android.importClass('android.content.Intent');
  					var Build = plus.android.importClass("android.os.Build");
  					//android 8.0引导  
  					if (Build.VERSION.SDK_INT >= 26) {
  						var intent = new Intent('android.settings.APP_NOTIFICATION_SETTINGS');
  						intent.putExtra('android.provider.extra.APP_PACKAGE', pkName);
  					} else if (Build.VERSION.SDK_INT >= 21) { //android 5.0-7.0  
  						var intent = new Intent('android.settings.APP_NOTIFICATION_SETTINGS');
  						intent.putExtra("app_package", pkName);
  						intent.putExtra("app_uid", uid);
  					} else { //(<21)其他--跳转到该应用管理的详情页  
  						intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
  						var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
  						intent.setData(uri);
  					}
  					// 跳转到该应用的系统通知设置页  
  					main.startActivity(intent);
  				}
  			}
  		});
  	}
  } else if (plus.os.name == 'iOS') { // 判断是ISO
  	var isOn = undefined;
  	var types = 0;
  	var app = plus.ios.invoke('UIApplication', 'sharedApplication');
  	var settings = plus.ios.invoke(app, 'currentUserNotificationSettings');
  	if (settings) {
  		types = settings.plusGetAttribute('types');
  		plus.ios.deleteObject(settings);
  	} else {
  		types = plus.ios.invoke(app, 'enabledRemoteNotificationTypes');
  	}
  	plus.ios.deleteObject(app);
  	isOn = (0 != types);
    console.log("消息通知是否打开", isOn)
  	if (isOn === false) {
  		uni.showModal({
  			title: '通知权限开启提醒',
  			content: '您还没有开启通知权限,无法接受到消息通知,请前往设置!',
  			showCancel: false,
  			confirmText: '去设置',
  			success: function(res) {
  				if (res.confirm) {
  					var app = plus.ios.invoke('UIApplication', 'sharedApplication');
  					var setting = plus.ios.invoke('NSURL', 'URLWithString:', 'app-settings:');
  					plus.ios.invoke(app, 'openURL:', setting);
  					plus.ios.deleteObject(setting);
  					plus.ios.deleteObject(app);
  				}
  			}
  		});
  	}
  }
  // #endif  
};
相关推荐
i听风逝夜24 分钟前
Web 3D地球实时统计访问来源
前端·后端
iMonster28 分钟前
React 组件的组合模式之道 (Composition Pattern)
前端
呐呐呐呐呢36 分钟前
antd渐变色边框按钮
前端
元直数字电路验证1 小时前
Jakarta EE Web 聊天室技术梳理
前端
wadesir1 小时前
Nginx配置文件CPU优化(从零开始提升Web服务器性能)
服务器·前端·nginx
牧码岛1 小时前
Web前端之canvas实现图片融合与清晰度介绍、合并
前端·javascript·css·html·web·canvas·web前端
灵犀坠1 小时前
前端面试八股复习心得
开发语言·前端·javascript
9***Y481 小时前
前端动画性能优化
前端
网络点点滴1 小时前
Vue3嵌套路由
前端·javascript·vue.js
牧码岛1 小时前
Web前端之Vue+Element打印时输入值没有及时更新dom的问题
前端·javascript·html·web·web前端