HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

Uniapp中用GoEasy集成IM过程中常见问题的处理

IM

1. 调用了GoEasy connect接口后,怎么日志中一直在打印connecting呢?

答:调用了connect接口之后,GoEasy sdk会自动尝试重连直到连接成功,如果出现一直连接中,你需要检查你的网络是否稳定,是否有防火墙限制等,最简单的方式则是切换到手机移动数据热点来看看是否可以连接成功。

2. GoEasy connect 接口返回code:401,error:Sorry, your application is a Basic Edition and does not support IM APIs, please upgrade to the Enhanced Edition if you need to invoke IM APIs,怎么回事?

答:这个错误是因为你创建的应用的类型不支持im 模块,只有增强型才可以使用im 模块,所以只需要重新创建一个免费的增强型就可以使用了。增强型是既支持pubsub模块又支持im模块,但基础型只支持pubsub模块。两个类型都有免费应用可以创建,所以不影响我们试用。

3. GoEasy connect 接口返回code:408,error:It is already connected, don't try again until disconnect() is called, 怎么回事?

答:这个就是客户端已经建立goeasy连接了,又在尝试调用connect接口就会报这个错。处理方式很简单,在连接时加上状态判断,只有当连接断开时才调用connect接口。这个goEasy.getConnectionStatus()接口在goeasy的官方文档中没有描述,但是在goeasy提供的im demo中有使用范例。

 // 因为已经连接过GoEasy的客户端,在未断开重连的前提下,是不能再次调用connect接口的,  
            //所以这里需要判断,只有当连接断开,才需要调用connect接口  
            if(this.goEasy.getConnectionStatus() === 'disconnected') {  
                this.connectGoEasy();  //连接goeasy  
                this.subscribeGroup(); //建立连接后,就应该订阅群聊消息,避免漏掉  
            }

4. GoEasy 参数或方法Undefined的问题,比如goEasy is undefined, im is undefined 等

答:这个undefined 的问题,不多说了,多数情况是没有挂载到全局导致其他页面无法获取到您要的goeasy参数。遇到这种问题,需要逐步看看参数的定义情况,具体的就不多说了,前端程序员的基本排查能力要具备吧。

5. GoEasy connect接口中的data属性是干什么的?

答:data可以带上当前用户的一些用户信息,比如常见的有昵称和头像,这个data属性会在多个接口中作为用户的附加信息返回给我们,比如会话列表接口、历史消息接口,这样可以省去我们再次从数据裤中读取这些信息。

6. GoEasy消息监听器中只能监听到好友或群组其他成员的消息,自己发送的消息不能被自己监听吗?

答:是的,自己发送的无论是私聊还是群聊消息,在消息创建成功后,就可以将创建好的message对象直接push到消息列表。

sendMessage(message){  
                this.messages.push(message);  
                this.scrollToBottom();  
                this.goEasy.im.sendMessage({  
                    message: message,  
                    onSuccess: function (message) {  
                        console.log('发送成功.', message);  
                    },  
                    onFailed: function (error) {  
                        if(error.code === 507){  
                            console.log('发送语音/图片/视频/文件失败,没有配置OSS存储,详情参考:https://www.goeasy.io/cn/docs/goeasy-2.x/im/message/media/send-media-message.html');  
                        }else{  
                            console.log('发送失败:',error);  
                        }  
                    }  
                });  
            },  

7. GoEasy IM的history接口返回的消息有遗漏,怎么回事呢?

答:调用history接口时,首次调用时lastTimestamp必须传null ,第二次查询时(加载更多历史消息时),lastTimestamp为上次查询结果里最后一条消息的时间戳。出现这个问题,多半是首次调用时传的不是null。 (我当时就没有仔细看文档传了当前时间)

8. 发送了消息,但goeasy的私聊监听器中没有收到监听消息,是什么原因呢?

答:询问goeasy在线客服得知,监听器中的代码如果报错了,那么有新消息时是不会触发监听器的;或者满足消息渲染的条件导致看起来没有收到消息。你可以注释掉监听器中的所有代码,只留一句打印收到的消息,看看是否可以打印出新收到的消息。(我当时就是因为监听器中if (friendId === this.friend.uuid)的条件不满足导致消息没有渲染到页面,根本原因是 “12”===12返回了false,所以这些细节都需要注意)

9. 集成了GoEasy的原生插件后,iOS收不到离线通知,如何排查呢?这里我引用GoEasy客服的回复。

请排查以下几点:

  1. app在后台运行是否可以收到通知栏提醒
  2. 发送消息时是否有带notification的相关参数,具体参考文档进行排查
  3. 如果是付费应用,排查是否购买了通知栏推送服务
  4. 手机里app的通知权限是否打开
  5. 是否添加了原生插件并按文档要求打包自定义基座(特别是是须勾选了push模块且不能勾选unipush)
  6. 确认iOS推送证书是否配置正确
    a. 请确认是否在GoEasy后台上传时的iOS的推送证书, iOS推送证书跟iOS的开发打包证书是两个完全不同的证书
    b. ios推送证书与开发证书的bundle id是否一致
    c. 推送证书是否是测试环境跟正式环境通用的证书
    d. 如果您选择的运行证书的环境为正式环境,您的app是否已经上架app store
  7. 如果以上6点都没有问题,请运行一下咱们的IM 的demo,看是否是您的代码有问题

没有你遇到的问题?GoEasy官网www.goeasy.io找在线客服啊,哈哈哈哈

继续阅读 »

1. 调用了GoEasy connect接口后,怎么日志中一直在打印connecting呢?

答:调用了connect接口之后,GoEasy sdk会自动尝试重连直到连接成功,如果出现一直连接中,你需要检查你的网络是否稳定,是否有防火墙限制等,最简单的方式则是切换到手机移动数据热点来看看是否可以连接成功。

2. GoEasy connect 接口返回code:401,error:Sorry, your application is a Basic Edition and does not support IM APIs, please upgrade to the Enhanced Edition if you need to invoke IM APIs,怎么回事?

答:这个错误是因为你创建的应用的类型不支持im 模块,只有增强型才可以使用im 模块,所以只需要重新创建一个免费的增强型就可以使用了。增强型是既支持pubsub模块又支持im模块,但基础型只支持pubsub模块。两个类型都有免费应用可以创建,所以不影响我们试用。

3. GoEasy connect 接口返回code:408,error:It is already connected, don't try again until disconnect() is called, 怎么回事?

答:这个就是客户端已经建立goeasy连接了,又在尝试调用connect接口就会报这个错。处理方式很简单,在连接时加上状态判断,只有当连接断开时才调用connect接口。这个goEasy.getConnectionStatus()接口在goeasy的官方文档中没有描述,但是在goeasy提供的im demo中有使用范例。

 // 因为已经连接过GoEasy的客户端,在未断开重连的前提下,是不能再次调用connect接口的,  
            //所以这里需要判断,只有当连接断开,才需要调用connect接口  
            if(this.goEasy.getConnectionStatus() === 'disconnected') {  
                this.connectGoEasy();  //连接goeasy  
                this.subscribeGroup(); //建立连接后,就应该订阅群聊消息,避免漏掉  
            }

4. GoEasy 参数或方法Undefined的问题,比如goEasy is undefined, im is undefined 等

答:这个undefined 的问题,不多说了,多数情况是没有挂载到全局导致其他页面无法获取到您要的goeasy参数。遇到这种问题,需要逐步看看参数的定义情况,具体的就不多说了,前端程序员的基本排查能力要具备吧。

5. GoEasy connect接口中的data属性是干什么的?

答:data可以带上当前用户的一些用户信息,比如常见的有昵称和头像,这个data属性会在多个接口中作为用户的附加信息返回给我们,比如会话列表接口、历史消息接口,这样可以省去我们再次从数据裤中读取这些信息。

6. GoEasy消息监听器中只能监听到好友或群组其他成员的消息,自己发送的消息不能被自己监听吗?

答:是的,自己发送的无论是私聊还是群聊消息,在消息创建成功后,就可以将创建好的message对象直接push到消息列表。

sendMessage(message){  
                this.messages.push(message);  
                this.scrollToBottom();  
                this.goEasy.im.sendMessage({  
                    message: message,  
                    onSuccess: function (message) {  
                        console.log('发送成功.', message);  
                    },  
                    onFailed: function (error) {  
                        if(error.code === 507){  
                            console.log('发送语音/图片/视频/文件失败,没有配置OSS存储,详情参考:https://www.goeasy.io/cn/docs/goeasy-2.x/im/message/media/send-media-message.html');  
                        }else{  
                            console.log('发送失败:',error);  
                        }  
                    }  
                });  
            },  

7. GoEasy IM的history接口返回的消息有遗漏,怎么回事呢?

答:调用history接口时,首次调用时lastTimestamp必须传null ,第二次查询时(加载更多历史消息时),lastTimestamp为上次查询结果里最后一条消息的时间戳。出现这个问题,多半是首次调用时传的不是null。 (我当时就没有仔细看文档传了当前时间)

8. 发送了消息,但goeasy的私聊监听器中没有收到监听消息,是什么原因呢?

答:询问goeasy在线客服得知,监听器中的代码如果报错了,那么有新消息时是不会触发监听器的;或者满足消息渲染的条件导致看起来没有收到消息。你可以注释掉监听器中的所有代码,只留一句打印收到的消息,看看是否可以打印出新收到的消息。(我当时就是因为监听器中if (friendId === this.friend.uuid)的条件不满足导致消息没有渲染到页面,根本原因是 “12”===12返回了false,所以这些细节都需要注意)

9. 集成了GoEasy的原生插件后,iOS收不到离线通知,如何排查呢?这里我引用GoEasy客服的回复。

请排查以下几点:

  1. app在后台运行是否可以收到通知栏提醒
  2. 发送消息时是否有带notification的相关参数,具体参考文档进行排查
  3. 如果是付费应用,排查是否购买了通知栏推送服务
  4. 手机里app的通知权限是否打开
  5. 是否添加了原生插件并按文档要求打包自定义基座(特别是是须勾选了push模块且不能勾选unipush)
  6. 确认iOS推送证书是否配置正确
    a. 请确认是否在GoEasy后台上传时的iOS的推送证书, iOS推送证书跟iOS的开发打包证书是两个完全不同的证书
    b. ios推送证书与开发证书的bundle id是否一致
    c. 推送证书是否是测试环境跟正式环境通用的证书
    d. 如果您选择的运行证书的环境为正式环境,您的app是否已经上架app store
  7. 如果以上6点都没有问题,请运行一下咱们的IM 的demo,看是否是您的代码有问题

没有你遇到的问题?GoEasy官网www.goeasy.io找在线客服啊,哈哈哈哈

收起阅读 »

数组去重

js

利用对象的属性的唯一性,来去重。
let arr=[1,2,3,4,5,2,4,6,7,8,5,7],obj={},newArr=[],newArr2=[];
// 第一种:
for(let i=0;i<arr.length;i++){
if(!obj[arr[i]]){
obj[arr[i]]=arr[i];
newArr.push(arr[i]);
}
}
console.log(newArr)

// 第二种:
for(let i=0;i<arr.length;i++){
obj[arr[i]]=arr[i];
}
newArr2=Object.values(obj);
console.log(newArr2)

继续阅读 »

利用对象的属性的唯一性,来去重。
let arr=[1,2,3,4,5,2,4,6,7,8,5,7],obj={},newArr=[],newArr2=[];
// 第一种:
for(let i=0;i<arr.length;i++){
if(!obj[arr[i]]){
obj[arr[i]]=arr[i];
newArr.push(arr[i]);
}
}
console.log(newArr)

// 第二种:
for(let i=0;i<arr.length;i++){
obj[arr[i]]=arr[i];
}
newArr2=Object.values(obj);
console.log(newArr2)

收起阅读 »

微信h5苹果端图片上传失败

微信 h5

在公众号h5项目中,出现一个问题,微信的JSSDK的选择图片的接口,count属性,默认为9,当count的值大于默认值时,安卓端可以上传成功,苹果端,可以选择到count属性设置到数量的图片(如:count为10,可以一次选择10个),但是后续的上传操作就失败了,

防止出现这种情况,不使用count属性或者count属性的值保持在9以内的数。

继续阅读 »

在公众号h5项目中,出现一个问题,微信的JSSDK的选择图片的接口,count属性,默认为9,当count的值大于默认值时,安卓端可以上传成功,苹果端,可以选择到count属性设置到数量的图片(如:count为10,可以一次选择10个),但是后续的上传操作就失败了,

防止出现这种情况,不使用count属性或者count属性的值保持在9以内的数。

收起阅读 »

webView 里面嵌入H5 控制其前进后退

首先获取到承载H5 的webView 对象,使用plus.webview.getWebviewById( id ) 或者plus.webview.currentWebview(),拿到 webView ,使用webView.canBack() 和webView. canForward 获取H5 是否能够前进和后退,再使用webView.back()进行后退。即可控制webView 嵌入H5 页面的路由。

继续阅读 »

首先获取到承载H5 的webView 对象,使用plus.webview.getWebviewById( id ) 或者plus.webview.currentWebview(),拿到 webView ,使用webView.canBack() 和webView. canForward 获取H5 是否能够前进和后退,再使用webView.back()进行后退。即可控制webView 嵌入H5 页面的路由。

收起阅读 »

离线打包aab无法上架到google play,解决方式和结论

GooglePlay

aab 必须使用google play 签名计划。
uniapp离线打包必须也要key,而且要验证sh1,一个项目只能配置一个。
出现的后果就是所有问题解决了之后
uniapp推送到google play后时app打不开的。报错是key不对。

结论结论结论;google 官方,和uniapp官方都目前都没有解决这个问题。。uniapp上架google play最好用云打包。(其实只有这一条路)。干

继续阅读 »

aab 必须使用google play 签名计划。
uniapp离线打包必须也要key,而且要验证sh1,一个项目只能配置一个。
出现的后果就是所有问题解决了之后
uniapp推送到google play后时app打不开的。报错是key不对。

结论结论结论;google 官方,和uniapp官方都目前都没有解决这个问题。。uniapp上架google play最好用云打包。(其实只有这一条路)。干

收起阅读 »

uni-admin的uni-stat自定义事件统计官方更新较慢,共享一个事件ID、设备标识、查询当天事件的优化代码

uniCloud uniapp

修改代码路径:pages/uni-stat/event/event.vue
改动后效果
可以根据事件ID、设备标识查询,以及解决了uniCloud数据库时区问题导致无法查询到当天统计数据问题

改动点

改动代码

#21 -                   <uni-datetime-picker type="daterange" :end="new Date().getTime()" v-model="query.create_time"  
#21 +                   <uni-datetime-picker type="daterange" :end="new Date().getTime()" :value="query.create_time"  

#26 +                   <view class="flex" style="padding-left: 32rpx;">  
#27 +                   <view class="my-label-text">搜索条件:</view>  
#28 +                   <input v-model="query.event_key" placeholder="事件ID" style="color: #a8a7a7; margin-right: 20rpx;"/>  
#29 +                   <input v-model="query.device_id" placeholder="设备标志" style="color: #a8a7a7"/>  
#30 +               </view>  

#96 +                   device_id: '', // 设备标志  
#97 +                   event_key: '', // 事件ID  

#147 +              useDatetimePicker(e) {  
#148 =              this.currentDateTab = -1  
#149 +              this.query.create_time = [e[0], e[1] + 24 * 3600000]  
#150 =          },  

#163 +                      end = getTimeOfSomeDayAgo(0)  

#275 +      .my-label-text {  
#276 +      font-size: 14px;  
#277 +      font-weight: bold;  
#278 +      color: #555;  
#279 +      margin-top: 17px;  
#280 +      margin-bottom: 17px;  
#281 +      margin-right: 5px;  
#282 +  }
继续阅读 »

修改代码路径:pages/uni-stat/event/event.vue
改动后效果
可以根据事件ID、设备标识查询,以及解决了uniCloud数据库时区问题导致无法查询到当天统计数据问题

改动点

改动代码

#21 -                   <uni-datetime-picker type="daterange" :end="new Date().getTime()" v-model="query.create_time"  
#21 +                   <uni-datetime-picker type="daterange" :end="new Date().getTime()" :value="query.create_time"  

#26 +                   <view class="flex" style="padding-left: 32rpx;">  
#27 +                   <view class="my-label-text">搜索条件:</view>  
#28 +                   <input v-model="query.event_key" placeholder="事件ID" style="color: #a8a7a7; margin-right: 20rpx;"/>  
#29 +                   <input v-model="query.device_id" placeholder="设备标志" style="color: #a8a7a7"/>  
#30 +               </view>  

#96 +                   device_id: '', // 设备标志  
#97 +                   event_key: '', // 事件ID  

#147 +              useDatetimePicker(e) {  
#148 =              this.currentDateTab = -1  
#149 +              this.query.create_time = [e[0], e[1] + 24 * 3600000]  
#150 =          },  

#163 +                      end = getTimeOfSomeDayAgo(0)  

#275 +      .my-label-text {  
#276 +      font-size: 14px;  
#277 +      font-weight: bold;  
#278 +      color: #555;  
#279 +      margin-top: 17px;  
#280 +      margin-bottom: 17px;  
#281 +      margin-right: 5px;  
#282 +  }
收起阅读 »

Dcloud认证服务商 武汉实体企业,可上门考察 全栈开发 擅长:高并发项目 微信:Yxhbbb

外包

Dcloud认证服务商
武汉实体企业,可上门考察
全栈开发

擅长:高并发项目

微信:Yxhbbb

Dcloud认证服务商
武汉实体企业,可上门考察
全栈开发

擅长:高并发项目

微信:Yxhbbb

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")  
})
收起阅读 »

解决组件调用中出现 $refs[ref].push is not a function 问题。

组件


如上图所示,控制台出现 refs[ref].push is not a function 问题。
原因是 在项目中 存在 同名的 ref=“xxx” ref 名称必须唯一


如上图所示,控制台出现 refs[ref].push is not a function 问题。
原因是 在项目中 存在 同名的 ref=“xxx” ref 名称必须唯一

uniCloud视频教程 收货地址区域回显问题

schema2code

代码生成工具schema2code-高级进阶_哔哩哔哩_bilibili
https://www.bilibili.com/video/BV17p4y1a71x?p=11&vd_source=9ee7cb0607a63acebf1f1d12f36a3742

我想将收货地址的区域作为字段,加入到表中。按照上面的视频教程进行操作。可以正常保存,但无法回显。
报错如下:
00:38:42.526 [本地调试]PERMISSION_ERROR: 禁止使用数据库内包含的字段名作为别名,产生冲突的数据表为:line-up,产生冲突的字段名称为:area

另外,教程中也没有回显的教程。

自己根据文档,实现了回显。但只能回显省市县中的“县”一级的名称。不太完美。

具体方法为:

  1. 在表的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"  
    },
  2. 在页面中,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

另外,教程中也没有回显的教程。

自己根据文档,实现了回显。但只能回显省市县中的“县”一级的名称。不太完美。

具体方法为:

  1. 在表的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"  
    },
  2. 在页面中,unicloud-db标签,collection属性,添加上“opendb-city-china”表。参考:
collectionList="line-up,opendb-city-china"

field属性,参考:

field="name,area{name as text}"
收起阅读 »