
UniCloud实战留言板功能遇到的“未能获取当前用户信息:当前用户为匿名身份”问题及解决方法
跟着下面链接的教程做留言板功能
https://www.bilibili.com/video/BV17p4y1a71x/?p=20&vd_source=3db6d6011850c9ac1e496b824b883bee
问题:
匿名状态(未登录时)访问留言板时,会触发下面错误提示
“TOKEN_INVALID_ANONYMOUS_USER 未能获取当前用户信息:当前用户为匿名身份”
并且界面会跳转到登录界面,而不是正常浏览留言板
原因:
未登录状态下访问$cloudEnv_uid引起的
解决方法:在onLoad()中获取缓存中(getStorageSync部分)的登录信息,
如果获取不到则说明未正常登录,未正常登录情况下只确定审核过的留言可显示,不判断是否显示登录者发表的未审核留言
正常登录情况下则两个条件都判断
当然了解决方法应该有很多种,希望高人不吝赐教,uni-app小白先谢谢了!
视频教程里的能正常也许是因为较老版本的uni-starter可以正常吧!
guestbook.vue 源码如下
源码还解决了没有添加头像读取不到avatar_file.url出错的问题
添加了审核过的留言取消审核功能
<template>
<view>
<unicloud-db ref="udb" :where="where" v-slot:default="{data, loading, error, options}"
collection="guestbook, uni-id-users" field="_id,text,state,user_id.nickname,
user_id.avatar_file,user_id._id">
<view v-if="error">{{error.message}}</view>
<view v-else>
<view v-for="(item,index) in data" :key="index" class="item">
<view class="main">
<cloud-image v-if="item.user_id[0].avatar_file&&item.user_id[0].avatar_file.url" :src="item.user_id[0].avatar_file.url"></cloud-image>
<image v-else style="width: 50px; height: 50px; background-color: #eeeeee;" mode="aspectFit" src="@/static/uni-center/defaultAvatarUrl.png"></image>
<view>
<text class="nickname">{{item.user_id[0].nickname}}</text>
<text>{{item.text}}</text>
</view>
<button v-if="!item.state" @click="changeState(item)" type="default"><text>{{!item.state?'审核中':'审核通过'}}</text></button>
<button v-else @click="changeState(item)" type="default"><text>{{item.state?'取消审核':'审核中'}}</text></button>
</view>
</view>
</view>
</unicloud-db>
<view class="submit-box">
<input class="input-box" v-model="text" />
<button type="default" @click="text?send():''" class="btn" :class="{active:text}">发送</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
text:"",
ifLogin: false,
}
},
onLoad() {
let hostUserInfo = uni.getStorageSync('uni-id-pages-userInfo')||{}
this.ifLogin = Object.keys(hostUserInfo).length != 0;
console.log('guestbook ifLogin = ',Object.keys(hostUserInfo).length != 0);
console.log('guestbook this.uniIDHasRole(AUDITOR) =',this.uniIDHasRole('AUDITOR'))
// #ifdef APP-PLUS
this.version = plus.runtime.version
// #endif
},
computed: {
where(){
if( this.uniIDHasRole('AUDITOR')){
return ''
}else{
//这里需要添加匿名用户可访问代码 暂未找到相应实现代码
/*
问题:匿名状态(未登录时)访问留言板时,会触发下面错误提示
// “TOKEN_INVALID_ANONYMOUS_USER 未能获取当前用户信息:当前用户为匿名身份”
//并且界面会跳转到登录界面,而不是正常浏览留言板
//原因:未登录状态下访问$cloudEnv_uid引起的
//解决方法:在onLoad()中获取缓存中(getStorageSync部分)的登录信息,
// 如果获取不到则说明未正常登录,未正常登录情况下只确定审核过的留言可显示,不判断是否显示登录者发表的未审核留言
//正常登录情况下则两个条件都判断
//当然了解决方法应该有很多种,希望高人不吝赐教,uni-app小白先谢谢了!
//遇到的其他问题,数据提交数据库成功了但 this.$refs.udb.refresh() 刷新界面显示最新结果的功能未达预期,本人错在了
控件 <unicloud-db ref="udb" 。。。中的 ref="udb"弄丢了,补上后问题解决
*/
//正常登录情况下则访问$cloudEnv_uid,否则不访问。
if(this.ifLogin) {
console.log('guestbook where multiple')
return 'state == true || user_id._id == $cloudEnv_uid'
} else {
console.log('guestbook where alone')
return 'state == true'
}
}
}
},
methods: {
async send(){
const db = uniCloud.database();
const guestbookTbl = db.collection('guestbook');
let res = await guestbookTbl.add({
"text":this.text,
//"user_id":"beike"
})
if(!res.result.errcode) {
uni.showToast({
title: '发送成功',
icon: 'none'
})
this.$refs.udb.refresh();
this.text=""
}else{
uni.showToast({
title: '保存失败',
text: res.result.errcode,
icon: 'none'
})
}
},
async changeState0(item){
this.$refs.udb.update(item._id,{state:!item.state},{complete:e=>{
console.log(e);
this.$refs.udb.refresh();
}})
},
async changeState(item){
//this.$refs.udb.update(item._id,{state:!item.state},{complete:e=>{
// console.log(e);
// this.$refs.udb.refresh();
//}})
//视频教程中的上述方法,不可行,改为下面的 aluo 2022.10.24 原因是未添加 ref="udb"
const db = uniCloud.database();
const res = await db.collection('guestbook')
.doc(item._id)
.update({
"state": !item.state,
}).catch((e) => {
console.log(e)
})
if(!res.result.errcode){
uni.showToast({
title:'审核成功',
icon: 'none'
});
//this.text = ''
this.$refs.udb.refresh()//更新后刷页面不启作用! aluo 2022.10.24
}
},
add(){
const db=uniCloud.database();
const guestbookTable = db.collection("guestbook");
guestbookTable.add({
"text":"这是第2条留言",
//"state": false,
//"user_id":"beike"
});
}
}
}
</script>
<style>
</style>
guestbook.schema.json
{
"bsonType": "object",
"required": [],
"permission": {
"read": "auth.uid == null || doc.state == true || doc.user_id == auth.uid || 'AUDITOR' in auth.role",
"create": "auth.uid != null",
"update": "'AUDITOR' in auth.role",
"delete": false
},
"properties": {
"_id": {
"description": "ID,系统自动生成"
},
"text": {
"bsonType": "string"
},
"state": {
"bsonType": "bool",
"forceDefaultValue": false
},
"user_id": {
"foreignKey": "uni-id-users._id",
"bsonType": "string",
"forceDefaultValue": {
"$env": "uid"
}
}
}
}
找到方法之前走了不少弯路,最初都放在了表的read权限上了,全改为true也是出现问题,一步一步去实现登录者可以看到自己未审核的留言时发现了问题所在!期间几次都想放弃了,项目几次重新开始!问题解决了心里豁然开朗,原来如此,感觉真得超好!
希望能帮助到遇到同样问题的小白朋友,高手请忽略!
跟着下面链接的教程做留言板功能
https://www.bilibili.com/video/BV17p4y1a71x/?p=20&vd_source=3db6d6011850c9ac1e496b824b883bee
问题:
匿名状态(未登录时)访问留言板时,会触发下面错误提示
“TOKEN_INVALID_ANONYMOUS_USER 未能获取当前用户信息:当前用户为匿名身份”
并且界面会跳转到登录界面,而不是正常浏览留言板
原因:
未登录状态下访问$cloudEnv_uid引起的
解决方法:在onLoad()中获取缓存中(getStorageSync部分)的登录信息,
如果获取不到则说明未正常登录,未正常登录情况下只确定审核过的留言可显示,不判断是否显示登录者发表的未审核留言
正常登录情况下则两个条件都判断
当然了解决方法应该有很多种,希望高人不吝赐教,uni-app小白先谢谢了!
视频教程里的能正常也许是因为较老版本的uni-starter可以正常吧!
guestbook.vue 源码如下
源码还解决了没有添加头像读取不到avatar_file.url出错的问题
添加了审核过的留言取消审核功能
<template>
<view>
<unicloud-db ref="udb" :where="where" v-slot:default="{data, loading, error, options}"
collection="guestbook, uni-id-users" field="_id,text,state,user_id.nickname,
user_id.avatar_file,user_id._id">
<view v-if="error">{{error.message}}</view>
<view v-else>
<view v-for="(item,index) in data" :key="index" class="item">
<view class="main">
<cloud-image v-if="item.user_id[0].avatar_file&&item.user_id[0].avatar_file.url" :src="item.user_id[0].avatar_file.url"></cloud-image>
<image v-else style="width: 50px; height: 50px; background-color: #eeeeee;" mode="aspectFit" src="@/static/uni-center/defaultAvatarUrl.png"></image>
<view>
<text class="nickname">{{item.user_id[0].nickname}}</text>
<text>{{item.text}}</text>
</view>
<button v-if="!item.state" @click="changeState(item)" type="default"><text>{{!item.state?'审核中':'审核通过'}}</text></button>
<button v-else @click="changeState(item)" type="default"><text>{{item.state?'取消审核':'审核中'}}</text></button>
</view>
</view>
</view>
</unicloud-db>
<view class="submit-box">
<input class="input-box" v-model="text" />
<button type="default" @click="text?send():''" class="btn" :class="{active:text}">发送</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
text:"",
ifLogin: false,
}
},
onLoad() {
let hostUserInfo = uni.getStorageSync('uni-id-pages-userInfo')||{}
this.ifLogin = Object.keys(hostUserInfo).length != 0;
console.log('guestbook ifLogin = ',Object.keys(hostUserInfo).length != 0);
console.log('guestbook this.uniIDHasRole(AUDITOR) =',this.uniIDHasRole('AUDITOR'))
// #ifdef APP-PLUS
this.version = plus.runtime.version
// #endif
},
computed: {
where(){
if( this.uniIDHasRole('AUDITOR')){
return ''
}else{
//这里需要添加匿名用户可访问代码 暂未找到相应实现代码
/*
问题:匿名状态(未登录时)访问留言板时,会触发下面错误提示
// “TOKEN_INVALID_ANONYMOUS_USER 未能获取当前用户信息:当前用户为匿名身份”
//并且界面会跳转到登录界面,而不是正常浏览留言板
//原因:未登录状态下访问$cloudEnv_uid引起的
//解决方法:在onLoad()中获取缓存中(getStorageSync部分)的登录信息,
// 如果获取不到则说明未正常登录,未正常登录情况下只确定审核过的留言可显示,不判断是否显示登录者发表的未审核留言
//正常登录情况下则两个条件都判断
//当然了解决方法应该有很多种,希望高人不吝赐教,uni-app小白先谢谢了!
//遇到的其他问题,数据提交数据库成功了但 this.$refs.udb.refresh() 刷新界面显示最新结果的功能未达预期,本人错在了
控件 <unicloud-db ref="udb" 。。。中的 ref="udb"弄丢了,补上后问题解决
*/
//正常登录情况下则访问$cloudEnv_uid,否则不访问。
if(this.ifLogin) {
console.log('guestbook where multiple')
return 'state == true || user_id._id == $cloudEnv_uid'
} else {
console.log('guestbook where alone')
return 'state == true'
}
}
}
},
methods: {
async send(){
const db = uniCloud.database();
const guestbookTbl = db.collection('guestbook');
let res = await guestbookTbl.add({
"text":this.text,
//"user_id":"beike"
})
if(!res.result.errcode) {
uni.showToast({
title: '发送成功',
icon: 'none'
})
this.$refs.udb.refresh();
this.text=""
}else{
uni.showToast({
title: '保存失败',
text: res.result.errcode,
icon: 'none'
})
}
},
async changeState0(item){
this.$refs.udb.update(item._id,{state:!item.state},{complete:e=>{
console.log(e);
this.$refs.udb.refresh();
}})
},
async changeState(item){
//this.$refs.udb.update(item._id,{state:!item.state},{complete:e=>{
// console.log(e);
// this.$refs.udb.refresh();
//}})
//视频教程中的上述方法,不可行,改为下面的 aluo 2022.10.24 原因是未添加 ref="udb"
const db = uniCloud.database();
const res = await db.collection('guestbook')
.doc(item._id)
.update({
"state": !item.state,
}).catch((e) => {
console.log(e)
})
if(!res.result.errcode){
uni.showToast({
title:'审核成功',
icon: 'none'
});
//this.text = ''
this.$refs.udb.refresh()//更新后刷页面不启作用! aluo 2022.10.24
}
},
add(){
const db=uniCloud.database();
const guestbookTable = db.collection("guestbook");
guestbookTable.add({
"text":"这是第2条留言",
//"state": false,
//"user_id":"beike"
});
}
}
}
</script>
<style>
</style>
guestbook.schema.json
{
"bsonType": "object",
"required": [],
"permission": {
"read": "auth.uid == null || doc.state == true || doc.user_id == auth.uid || 'AUDITOR' in auth.role",
"create": "auth.uid != null",
"update": "'AUDITOR' in auth.role",
"delete": false
},
"properties": {
"_id": {
"description": "ID,系统自动生成"
},
"text": {
"bsonType": "string"
},
"state": {
"bsonType": "bool",
"forceDefaultValue": false
},
"user_id": {
"foreignKey": "uni-id-users._id",
"bsonType": "string",
"forceDefaultValue": {
"$env": "uid"
}
}
}
}
找到方法之前走了不少弯路,最初都放在了表的read权限上了,全改为true也是出现问题,一步一步去实现登录者可以看到自己未审核的留言时发现了问题所在!期间几次都想放弃了,项目几次重新开始!问题解决了心里豁然开朗,原来如此,感觉真得超好!
希望能帮助到遇到同样问题的小白朋友,高手请忽略!

忍不住想吐槽下JQL语法
真不明白 jql 为为什么要把参数搞成字符串,拼接字符串难道比对象清晰,比对象不容易出错?
还有mongodb原始的修饰符不爽么,要搞个dbcmd 什么摊平参数
本来可以这样,语法大家熟悉,结构也清楚
db.collection('im_group').doc('63579a46fcf4a30001e86432').update({
$addToSet:{"uids":"1111"}
})
非要搞成这样?
const dbCmd = db.command
db.collection('im_group').doc('63579a46fcf4a30001e86432').update({
uids: dbCmd.addToSet("1111")
})
真不明白 jql 为为什么要把参数搞成字符串,拼接字符串难道比对象清晰,比对象不容易出错?
还有mongodb原始的修饰符不爽么,要搞个dbcmd 什么摊平参数
本来可以这样,语法大家熟悉,结构也清楚
db.collection('im_group').doc('63579a46fcf4a30001e86432').update({
$addToSet:{"uids":"1111"}
})
非要搞成这样?
const dbCmd = db.command
db.collection('im_group').doc('63579a46fcf4a30001e86432').update({
uids: dbCmd.addToSet("1111")
})
收起阅读 »

uniCloud视频教程 收货地址区域回显问题
代码生成工具schema2code-高级进阶_哔哩哔哩_bilibili
https://www.bilibili.com/video/BV17p4y1a71x?p=11&vd_source=9ee7cb0607a63acebf1f1d12f36a3742
我想将收货地址的区域作为字段,加入到表中。按照上面的视频教程进行操作。可以正常保存,但无法回显。
报错如下:
00:38:42.526 [本地调试]PERMISSION_ERROR: 禁止使用数据库内包含的字段名作为别名,产生冲突的数据表为:line-up,产生冲突的字段名称为:area
另外,教程中也没有回显的教程。
自己根据文档,实现了回显。但只能回显省市县中的“县”一级的名称。不太完美。
具体方法为:
- 在表的schema.json文件中,添加外键。参考:
"area": { "bsonType": "string", "title": "所在区域", "description": "所在区域", "enum": { "collection": "opendb-city-china", "field": "code as value,name as text" }, "foreignKey": "opendb-city-china.code", "enumType": "tree" },
- 在页面中,unicloud-db标签,collection属性,添加上“opendb-city-china”表。参考:
collectionList="line-up,opendb-city-china"
field属性,参考:
field="name,area{name as text}"
代码生成工具schema2code-高级进阶_哔哩哔哩_bilibili
https://www.bilibili.com/video/BV17p4y1a71x?p=11&vd_source=9ee7cb0607a63acebf1f1d12f36a3742
我想将收货地址的区域作为字段,加入到表中。按照上面的视频教程进行操作。可以正常保存,但无法回显。
报错如下:
00:38:42.526 [本地调试]PERMISSION_ERROR: 禁止使用数据库内包含的字段名作为别名,产生冲突的数据表为:line-up,产生冲突的字段名称为:area
另外,教程中也没有回显的教程。
自己根据文档,实现了回显。但只能回显省市县中的“县”一级的名称。不太完美。
具体方法为:
- 在表的schema.json文件中,添加外键。参考:
"area": { "bsonType": "string", "title": "所在区域", "description": "所在区域", "enum": { "collection": "opendb-city-china", "field": "code as value,name as text" }, "foreignKey": "opendb-city-china.code", "enumType": "tree" },
- 在页面中,unicloud-db标签,collection属性,添加上“opendb-city-china”表。参考:
collectionList="line-up,opendb-city-china"
field属性,参考:
field="name,area{name as text}"
收起阅读 »

最新安卓隐私sdk收集分享
2个安卓应用因为隐私被下架了,重新按照要求完善了隐私sdk:
<tbody>
<tr>
<td>uni-app(5+、web2app)</td>
<td>io.dcloud</td>
<td>基础模块</td>
<td>android.permission.INTERNET
android.permission.ACCESS_NETWORK_STATE
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAG
android.permission.READ_PHONE_STATE</td>
<td>存储的个人文件,设备信息(IMEI、ANDROID_ID、DEVICE_ID、IMSI),网络信息</td>
<td>https://ask.dcloud.net.cn/article/36937</td>
</tr>
<tr>
<td>阿里weexSDK</td>
<td>com.taobao</td>
<td>uni-app基础模块默认集成,用于渲染uniapp的nvue页面引擎</td>
<td>android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAG</td>
<td>存储的个人文件</td>
<td>http://doc.weex.io/zh</td>
</tr>
<tr>
<td>Fresco图库</td>
<td>com.facebook.fresco</td>
<td>用于nvue页面加载图片使用</td>
<td>android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAG</td>
<td>存储的个人文件</td>
<td>https://www.fresco-cn.org/</td>
</tr>
<tr>
<td>glide图库</td>
<td>com.bumptech.glide</td>
<td>用于图片预览使用</td>
<td>android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAG</td>
<td>存储的个人文件</td>
<td>http://bumptech.github.io/glide/</td>
</tr>
<tr>
<td>gif-drawable</td>
<td>pl.droidsonroids.gif</td>
<td>加载gif图</td>
<td>android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAG</td>
<td>存储文件</td>
<td>https://github.com/koral--/android-gif-drawable</td>
</tr>
<tr>
<td>fastjson</td>
<td>com.alibaba.fastjson</td>
<td>JSON解析</td>
<td>无</td>
<td>无</td>
<td>https://github.com/alibaba/fastjson</td>
</tr>
<tr>
<td>移动安全联盟</td>
<td>OAID</td>
<td>com.bun.miitmdid、com.zui.opendeviceidlibrary</td>
<td>获取oaid</td>
<td>无</td>
<td>设备信息</td>
<td>http://www.msa-alliance.cn/col.jsp?id=105</td>
</tr>
<tr>
<td>个推·消息推送</td>
<td>com.igexin</td>
<td>消息推送</td>
<td>android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE
android.permission.READ_PHONE_STATE
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.VIBRATE
android.permission.GET_TASKS
android.permission.QUERY_ALL_PACKAGEs</td>
<td>存储的个人文件、设备信息(IMEI、MAC、ANDROID_ID、DEVICE_ID、IMSI)、应用已安装列表、网络信息</td>
<td>http://docs.getui.com/privacy</td>
</tr>
<tr>
<td>微信开放平台</td>
<td>com.tencent.mm</td>
<td>登录、分享、支付(请根据具体使用目的填写)</td>
<td>android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE</td>
<td>存储的个人文件、网络信息</td>
<td>https://weixin.qq.com/cgi-bin/readtemplate?lang=zh_CN&t=weixin_agreement&s=privacy</td>
</tr>
<tr>
<td>新浪开放平台</td>
<td>com.sina.weibo</td>
<td>登录、分享(请根据具体使用目的填写)</td>
<td>android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE</td>
<td>存储的个人文件、网络信息</td>
<td>https://weibo.com/signup/v5/privacy?spm=a1zaa.8161610.0.0.4f8776217Wu8R1</td>
</tr>
<tr>
<td>支付宝开放平台</td>
<td>com.alipay</td>
<td>登录、分享(请根据具体使用目的填写)</td>
<td>android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE</td>
<td>网络信息 设备id IP地址 OAID IMSI</td>
<td>https://render.alipay.com/p/c/k2cx0tg8</td>
</tr>
<tr>
<td>高德开放平台</td>
<td>com.amap.api, com.loc, com.autonavi</td>
<td>实现定位/展现地图(请根据具体使用目的填写)</td>
<td>android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.READ_PHONE_STATE
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS</td>
<td>存储的个人文件、位置信息、读取手机状态和身份、网络信息</td>
<td>https://lbs.amap.com/agreement/compliance</td>
</tr>
<tr>
<td>百度开放平台</td>
<td>com.baidu</td>
<td>实现定位/展现地图(请根据具体使用目的填写)</td>
<td>android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.READ_PHONE_STATE
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.READ_LOGS
android.permission.WRITE_SETTINGS
android.permission.MOUNT_UNMOUNT_FILESYSTEM</td>
<td>存储的个人文件、位置信息、读取手机状态和身份、网络信息</td>
<td>https://map.baidu.com/zt/client/privacy/index.html</td>
</tr>
<tr>
<td>uni-AD</td>
<td></td>
<td>基础广告</td>
<td>设备品牌、型号、操作系统版本、OAID、分辨率、IMEI、android ID、SIM 卡 IMSI 信息、应用名称、应用包名、应用版本号、网络信息、应用安装列表、位置信息</td>
<td>android.permission.ACCESS_NETWORK_STATE
android.permission.READ_PHONE_STATE
android.permission.ACCESS_COARSE_LOCATION</td>
<td>广告投放合作,广告归因、反作弊、安全 隐私协议</td>
<td>https://doc.dcloud.net.cn/markdown-share-docs/1d821cdd3cdf2681045ec4be94bc8404/</td>
</tr>
<tr>
<td>腾讯浏览服务SDK</td>
<td>com.tencent.tbs、com.tencent.smtt</td>
<td>x5内核渲染webview</td>
<td>android.permission.WRITE_EXTERNAL_STORAGE
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE
android.permission.READ_PHONE_STATE</td>
<td>存储的个人文件、读取手机状态和身份、网络信息</td>
<td>https://x5.tencent.com/docs/privacy.html</td>
</tr>
<tr>
<td>openinstall</td>
<td>io.openinstall.sdk、com.fm.openinstall</td>
<td>设备品牌、设备型号、操作系统版本、IP地址、粘贴板(剪切板)</td>
<td>数据统计和分析</td>
<td>用于数据统计和分析</td>
<td>https://www.openinstall.io/privacy.html</td>
</tr>
<tr>
<td>openinstall</td>
<td>io.openinstall.sdk、com.fm.openinstall</td>
<td>Android ID、设备序列号(SerialNumber)、设备传感器(传感器数量)、本地存储权限</td>
<td>作弊监控</td>
<td>用于数据统计作弊监控</td>
<td>https://www.openinstall.io/privacy.html</td>
</tr>
<tr>
<td>openinstall</td>
<td>io.openinstall.sdk、com.fm.openinstall</td>
<td>IMEI、IDFA、OAID、Mac地址</td>
<td>移动广告效果监测</td>
<td>用户传入或系统API采集,用于移动广告效果监测</td>
<td>https://www.openinstall.io/privacy.html</td>
</tr>
</tbody>
</table>
2个安卓应用因为隐私被下架了,重新按照要求完善了隐私sdk:
<tbody>
<tr>
<td>uni-app(5+、web2app)</td>
<td>io.dcloud</td>
<td>基础模块</td>
<td>android.permission.INTERNET
android.permission.ACCESS_NETWORK_STATE
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAG
android.permission.READ_PHONE_STATE</td>
<td>存储的个人文件,设备信息(IMEI、ANDROID_ID、DEVICE_ID、IMSI),网络信息</td>
<td>https://ask.dcloud.net.cn/article/36937</td>
</tr>
<tr>
<td>阿里weexSDK</td>
<td>com.taobao</td>
<td>uni-app基础模块默认集成,用于渲染uniapp的nvue页面引擎</td>
<td>android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAG</td>
<td>存储的个人文件</td>
<td>http://doc.weex.io/zh</td>
</tr>
<tr>
<td>Fresco图库</td>
<td>com.facebook.fresco</td>
<td>用于nvue页面加载图片使用</td>
<td>android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAG</td>
<td>存储的个人文件</td>
<td>https://www.fresco-cn.org/</td>
</tr>
<tr>
<td>glide图库</td>
<td>com.bumptech.glide</td>
<td>用于图片预览使用</td>
<td>android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAG</td>
<td>存储的个人文件</td>
<td>http://bumptech.github.io/glide/</td>
</tr>
<tr>
<td>gif-drawable</td>
<td>pl.droidsonroids.gif</td>
<td>加载gif图</td>
<td>android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAG</td>
<td>存储文件</td>
<td>https://github.com/koral--/android-gif-drawable</td>
</tr>
<tr>
<td>fastjson</td>
<td>com.alibaba.fastjson</td>
<td>JSON解析</td>
<td>无</td>
<td>无</td>
<td>https://github.com/alibaba/fastjson</td>
</tr>
<tr>
<td>移动安全联盟</td>
<td>OAID</td>
<td>com.bun.miitmdid、com.zui.opendeviceidlibrary</td>
<td>获取oaid</td>
<td>无</td>
<td>设备信息</td>
<td>http://www.msa-alliance.cn/col.jsp?id=105</td>
</tr>
<tr>
<td>个推·消息推送</td>
<td>com.igexin</td>
<td>消息推送</td>
<td>android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE
android.permission.READ_PHONE_STATE
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.VIBRATE
android.permission.GET_TASKS
android.permission.QUERY_ALL_PACKAGEs</td>
<td>存储的个人文件、设备信息(IMEI、MAC、ANDROID_ID、DEVICE_ID、IMSI)、应用已安装列表、网络信息</td>
<td>http://docs.getui.com/privacy</td>
</tr>
<tr>
<td>微信开放平台</td>
<td>com.tencent.mm</td>
<td>登录、分享、支付(请根据具体使用目的填写)</td>
<td>android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE</td>
<td>存储的个人文件、网络信息</td>
<td>https://weixin.qq.com/cgi-bin/readtemplate?lang=zh_CN&t=weixin_agreement&s=privacy</td>
</tr>
<tr>
<td>新浪开放平台</td>
<td>com.sina.weibo</td>
<td>登录、分享(请根据具体使用目的填写)</td>
<td>android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE</td>
<td>存储的个人文件、网络信息</td>
<td>https://weibo.com/signup/v5/privacy?spm=a1zaa.8161610.0.0.4f8776217Wu8R1</td>
</tr>
<tr>
<td>支付宝开放平台</td>
<td>com.alipay</td>
<td>登录、分享(请根据具体使用目的填写)</td>
<td>android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE</td>
<td>网络信息 设备id IP地址 OAID IMSI</td>
<td>https://render.alipay.com/p/c/k2cx0tg8</td>
</tr>
<tr>
<td>高德开放平台</td>
<td>com.amap.api, com.loc, com.autonavi</td>
<td>实现定位/展现地图(请根据具体使用目的填写)</td>
<td>android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.READ_PHONE_STATE
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS</td>
<td>存储的个人文件、位置信息、读取手机状态和身份、网络信息</td>
<td>https://lbs.amap.com/agreement/compliance</td>
</tr>
<tr>
<td>百度开放平台</td>
<td>com.baidu</td>
<td>实现定位/展现地图(请根据具体使用目的填写)</td>
<td>android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.READ_PHONE_STATE
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.READ_LOGS
android.permission.WRITE_SETTINGS
android.permission.MOUNT_UNMOUNT_FILESYSTEM</td>
<td>存储的个人文件、位置信息、读取手机状态和身份、网络信息</td>
<td>https://map.baidu.com/zt/client/privacy/index.html</td>
</tr>
<tr>
<td>uni-AD</td>
<td></td>
<td>基础广告</td>
<td>设备品牌、型号、操作系统版本、OAID、分辨率、IMEI、android ID、SIM 卡 IMSI 信息、应用名称、应用包名、应用版本号、网络信息、应用安装列表、位置信息</td>
<td>android.permission.ACCESS_NETWORK_STATE
android.permission.READ_PHONE_STATE
android.permission.ACCESS_COARSE_LOCATION</td>
<td>广告投放合作,广告归因、反作弊、安全 隐私协议</td>
<td>https://doc.dcloud.net.cn/markdown-share-docs/1d821cdd3cdf2681045ec4be94bc8404/</td>
</tr>
<tr>
<td>腾讯浏览服务SDK</td>
<td>com.tencent.tbs、com.tencent.smtt</td>
<td>x5内核渲染webview</td>
<td>android.permission.WRITE_EXTERNAL_STORAGE
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE
android.permission.READ_PHONE_STATE</td>
<td>存储的个人文件、读取手机状态和身份、网络信息</td>
<td>https://x5.tencent.com/docs/privacy.html</td>
</tr>
<tr>
<td>openinstall</td>
<td>io.openinstall.sdk、com.fm.openinstall</td>
<td>设备品牌、设备型号、操作系统版本、IP地址、粘贴板(剪切板)</td>
<td>数据统计和分析</td>
<td>用于数据统计和分析</td>
<td>https://www.openinstall.io/privacy.html</td>
</tr>
<tr>
<td>openinstall</td>
<td>io.openinstall.sdk、com.fm.openinstall</td>
<td>Android ID、设备序列号(SerialNumber)、设备传感器(传感器数量)、本地存储权限</td>
<td>作弊监控</td>
<td>用于数据统计作弊监控</td>
<td>https://www.openinstall.io/privacy.html</td>
</tr>
<tr>
<td>openinstall</td>
<td>io.openinstall.sdk、com.fm.openinstall</td>
<td>IMEI、IDFA、OAID、Mac地址</td>
<td>移动广告效果监测</td>
<td>用户传入或系统API采集,用于移动广告效果监测</td>
<td>https://www.openinstall.io/privacy.html</td>
</tr>
</tbody>
</table>
收起阅读 »

关于应用转让后升级中心(uni-upgrade-center)的使用问题
应用转让后使用升级中心出现的问题
应用关联的 uniCloud 云服务空间
是绑定 HBuilderX 账号的。因此当应用转让后,如果无法再关联转让前所属账号的云服务空间,
则会导致用户已安装的转让前版本无法升级至转让后账号发布的新版本,可根据以下步骤处理:
-
应用转让后,使用转让后所属账号在 uni-admin 升级中心发布一个新的版本(如果已经发布过,这一步骤可以省略)。有以下注意事项:
- appId 要和转让前保持一致
- wgt、整包更新均可
iOS 端
要上架到 AppStore
-
在转让前应用所使用的升级中心中,使用同样的数据发布一个新版本,有以下注意事项:
- 如果应用已经在 uni-admin 的应用管理中删除,需要重新在应用管理中添加该应用
- appId 要和转让前保持一致
- 开启强制更新
-
应用更新成功后,后续正常使用升级中心即可
应用转让后使用升级中心出现的问题
应用关联的 uniCloud 云服务空间
是绑定 HBuilderX 账号的。因此当应用转让后,如果无法再关联转让前所属账号的云服务空间,
则会导致用户已安装的转让前版本无法升级至转让后账号发布的新版本,可根据以下步骤处理:
-
应用转让后,使用转让后所属账号在 uni-admin 升级中心发布一个新的版本(如果已经发布过,这一步骤可以省略)。有以下注意事项:
- appId 要和转让前保持一致
- wgt、整包更新均可
iOS 端
要上架到 AppStore
-
在转让前应用所使用的升级中心中,使用同样的数据发布一个新版本,有以下注意事项:
- 如果应用已经在 uni-admin 的应用管理中删除,需要重新在应用管理中添加该应用
- appId 要和转让前保持一致
- 开启强制更新
-
应用更新成功后,后续正常使用升级中心即可

直播预告 | 数据指标体系搭建秘诀,产品/运营/数据分析师都需要掌握√
科学完善的数据指标体系是企业开展数字化运营管理、打造数据驱动型组织的重要支撑。为帮助企业破解数据指标体系建设过程中遇到的难题,进一步拓展数据化运营思路,个推TechDay“治数训练营”系列直播课第三期《数据指标体系设计与开发实战》即将上线。
10月26日(下周三)19:00-20:00,来自个推治数平台部的数据架构师将为您深入浅出分享数据指标体系设计的思路和方法,手把手教学,带大家跑通数据指标体系建设全流程、轻松掌握数据化运营策略。产品、运营、数据开发、数据分析师,都值得一看~
立即预约直播,还有超多福利等你拿!
科学完善的数据指标体系是企业开展数字化运营管理、打造数据驱动型组织的重要支撑。为帮助企业破解数据指标体系建设过程中遇到的难题,进一步拓展数据化运营思路,个推TechDay“治数训练营”系列直播课第三期《数据指标体系设计与开发实战》即将上线。
10月26日(下周三)19:00-20:00,来自个推治数平台部的数据架构师将为您深入浅出分享数据指标体系设计的思路和方法,手把手教学,带大家跑通数据指标体系建设全流程、轻松掌握数据化运营策略。产品、运营、数据开发、数据分析师,都值得一看~
立即预约直播,还有超多福利等你拿!
收起阅读 »
在uni-app中使用官方的axios发起请求
简介
由于axios底层使用xhr发起请求,并不适用于各平台的小程序。好在axios提供了适配器选项,让我们可以兼容小程序平台,使其底层使用uni.request
发起请求。
为了更好的代码复用,我将自己写好的适配器发布到了npm
上,方便大家使用。
项目源码很简单,感兴趣的可以前往github
或者gitee
查看,如果觉得好用的话,请记得帮忙点个start
源码地址
npm地址
安装
安装 uniapp-axios-adapter
推荐使用pnpm
进行包管理。
pnpm/npm i uniapp-axios-adapter
# 或者 yarn add uniapp-axios-adapter
安装 axios
我们在包里添加了任何版本的axios
作为依赖,如果你不想使用最新版本的axios
,可以自行安装指定版本的axios
配合我们的UniAdapter
来使用,tree-shaking
不会将本包依赖的axios
打包进生产环境中
axios v1.0+
尚不稳定,推荐安装0.27.2
版本
pnpm/npm i axios@0.27.2
# 或者 yarn add axios@0.27.2
使用
我们按需导出了UniAdapter
适配器,并且默认导出了使用了该适配器的axios
,你可以自行使用适配器,也可以直接使用我们导出的 axios
自行使用适配器
指定axios
的适配器adapter
为本适配器即可,其余用法与axios
保持一致
import axios from "axios";
import { UniAdapter } from "uniapp-axios-adapter";
// 每次请求都创建一个新的实例
const request = axios.create({
baseURL: "https://example.com",
timeout: 10000,
adapter: UniAdapter, // 指定适配器
});
示例 1 设置请求拦截器与响应拦截器
// src/utils/http.js 中
import axios from "axios";
import { UniAdapter } from "uniapp-axios-adapter";
const request = axios.create({
baseURL: "https://example.com",
timeout: 10000,
adapter: UniAdapter,
});
request.interceptors.request.use((config) => {
//带上token
config.headers["Authorization"] = "token";
return config;
});
request.interceptors.response.use((response) => {
// 统一处理响应,返回Promise以便链式调用
if (response.status === 200) {
const { data } = response;
if (data && data.code === 200) {
return Promise.resolve(data);
} else {
return Promise.reject(data);
}
} else {
return Promise.reject(response);
}
});
export default request;
// 具体业务代码文件中
import http from 'src/utils/http.js' // 上一步封装axios的路径中
http({
url: 'example/api/test'
method: 'get',
params: {
id: 123,
}
})
http({
url: 'example/api/test'
method: 'post',
data: {
id: 123,
}
})
使用开箱即用的 axios
添加拦截器的方式
// http.js中
import axios from "uniapp-axios-adapter";
const request = axios.create({
baseURL: "https://example.com",
timeout: 10000,
});
request.interceptors.request.use((config) => {
//带上token
config.headers["Authorization"] = "token";
return config;
});
request.interceptors.response.use((response) => {
// 统一处理响应,返回Promise以便链式调用
if (response.status === 200) {
const { data } = response;
if (data && data.code === 200) {
return Promise.resolve(data);
} else {
return Promise.reject(data);
}
} else {
return Promise.reject(response);
}
});
export default request;
直接使用
// 业务代码中
import axios from "uniapp-axios-adapter";
axios.get({
url: "https://example.com/api/getUserById",
params: {
id: 1,
},
});
更新日志
TODO
- 压缩打包,减小体积
- 适配
uni.downloadFile
和uni.uploadFile
简介
由于axios底层使用xhr发起请求,并不适用于各平台的小程序。好在axios提供了适配器选项,让我们可以兼容小程序平台,使其底层使用uni.request
发起请求。
为了更好的代码复用,我将自己写好的适配器发布到了npm
上,方便大家使用。
项目源码很简单,感兴趣的可以前往github
或者gitee
查看,如果觉得好用的话,请记得帮忙点个start
源码地址
npm地址
安装
安装 uniapp-axios-adapter
推荐使用pnpm
进行包管理。
pnpm/npm i uniapp-axios-adapter
# 或者 yarn add uniapp-axios-adapter
安装 axios
我们在包里添加了任何版本的axios
作为依赖,如果你不想使用最新版本的axios
,可以自行安装指定版本的axios
配合我们的UniAdapter
来使用,tree-shaking
不会将本包依赖的axios
打包进生产环境中
axios v1.0+
尚不稳定,推荐安装0.27.2
版本
pnpm/npm i axios@0.27.2
# 或者 yarn add axios@0.27.2
使用
我们按需导出了UniAdapter
适配器,并且默认导出了使用了该适配器的axios
,你可以自行使用适配器,也可以直接使用我们导出的 axios
自行使用适配器
指定axios
的适配器adapter
为本适配器即可,其余用法与axios
保持一致
import axios from "axios";
import { UniAdapter } from "uniapp-axios-adapter";
// 每次请求都创建一个新的实例
const request = axios.create({
baseURL: "https://example.com",
timeout: 10000,
adapter: UniAdapter, // 指定适配器
});
示例 1 设置请求拦截器与响应拦截器
// src/utils/http.js 中
import axios from "axios";
import { UniAdapter } from "uniapp-axios-adapter";
const request = axios.create({
baseURL: "https://example.com",
timeout: 10000,
adapter: UniAdapter,
});
request.interceptors.request.use((config) => {
//带上token
config.headers["Authorization"] = "token";
return config;
});
request.interceptors.response.use((response) => {
// 统一处理响应,返回Promise以便链式调用
if (response.status === 200) {
const { data } = response;
if (data && data.code === 200) {
return Promise.resolve(data);
} else {
return Promise.reject(data);
}
} else {
return Promise.reject(response);
}
});
export default request;
// 具体业务代码文件中
import http from 'src/utils/http.js' // 上一步封装axios的路径中
http({
url: 'example/api/test'
method: 'get',
params: {
id: 123,
}
})
http({
url: 'example/api/test'
method: 'post',
data: {
id: 123,
}
})
使用开箱即用的 axios
添加拦截器的方式
// http.js中
import axios from "uniapp-axios-adapter";
const request = axios.create({
baseURL: "https://example.com",
timeout: 10000,
});
request.interceptors.request.use((config) => {
//带上token
config.headers["Authorization"] = "token";
return config;
});
request.interceptors.response.use((response) => {
// 统一处理响应,返回Promise以便链式调用
if (response.status === 200) {
const { data } = response;
if (data && data.code === 200) {
return Promise.resolve(data);
} else {
return Promise.reject(data);
}
} else {
return Promise.reject(response);
}
});
export default request;
直接使用
// 业务代码中
import axios from "uniapp-axios-adapter";
axios.get({
url: "https://example.com/api/getUserById",
params: {
id: 1,
},
});
更新日志
TODO
- 压缩打包,减小体积
- 适配
uni.downloadFile
和uni.uploadFile

h5 Array buffer allocation failed 解决方案
Array buffer allocation failed
多半是因为你在自己的static目录下存放着一个无法解析的目录,我就是因为失误不小心将一个下载历史的文件拖了进去,导致这个错误,大家细心检查一下就可以了
Array buffer allocation failed
多半是因为你在自己的static目录下存放着一个无法解析的目录,我就是因为失误不小心将一个下载历史的文件拖了进去,导致这个错误,大家细心检查一下就可以了