前端调用 uniCloud.database() 返回 permission denied 或空数组,根本原因是权限未生效,常见于控制台权限配置错误、登录态缺失或字段类型不匹配。

前端调用 uniCloud.database() 返回 permission denied 或空数组,基本可以断定不是代码写错了,而是权限根本没生效——绝大多数情况,问题出在控制台配置、登录态缺失或字段类型不匹配,而非云函数逻辑。
为什么 permission denied 不是后端报错而是前端直接卡死
因为 uni-app 前端 SDK 明确禁止直连数据库,所有 uniCloud.database().collection().get() 请求都会被拦截并交由云端 schema 校验。校验失败时,服务端不返回数据,也不抛 JS 错误,而是静默返回空数组或触发 permission denied 提示。
- 查不到数据但没报错?大概率是
"read": false或规则表达式始终为false - 控制台日志里看到
TOKEN_INVALID_ANONYMOUS_USER?说明用户根本没登录,或uni-id没初始化成功 - 用了
<unicloud-db></unicloud-db>组件却渲染{{data?.id}}为undefined?先别改模板,先确认 schema 的read是否已设为true或合法 JQL 表达式
schema.permission.read 配置必须手动开,且只认双等号
数据库表的权限不写在代码里,必须去 uniCloud 控制台「数据库 → 表 → 表结构 → 权限」里配。刚建的表默认 "read": false,哪怕你只查一条记录也会被拒。
- 临时排查:把
"read"改成true,看是否能查到数据;确认后再收紧为{"auth": "user"}或 JQL 表达式 - JQL 规则中必须用
==,不能用===(JQL 不支持严格等于) - 判断角色要用
"admin" in auth.role,不是auth.role == "admin"(auth.role是数组) - 字段名含驼峰(如
userName)会导致 schema 权限失效,统一改用下划线(user_name)
auth.uid 拿不到?先验证登录态和 token 是否真实有效
auth 对象不是前端传的,是 uniCloud 根据请求头里的 token 自动解析出来的。如果规则里写了 doc.user_id == auth.uid 却不生效,90% 是 auth.uid 根本为空。
- 在页面
onLoad里加console.log(uni.getStorageSync('uni_id_token')),输出长度应为 100+ 字符;为空或太短,说明没登录或 token 过期 - 确认
uni-id插件已安装,且uni-id/config.json中的tokenSecret与当前云空间密钥一致 - 使用
uniCloud.getCurrentUserInfo()获取当前用户信息,比自己存 localStorage 更可靠;但注意它返回的是缓存值,敏感操作前建议在云函数里重查uni-id-users表 - 真机调试时务必关掉 HBuilderX 的「本地数据库模拟」开关,否则 clientDB 会读 mock 数据,掩盖权限问题
云函数里查数据库仍被拒?检查表权限是否配在对应服务空间
云函数运行在某个服务空间(如 aliyun-xxx),但它访问的数据库表必须在**同一个服务空间**里配置好权限。跨空间调用不会自动继承权限。
- 进 uniCloud 控制台,确认你打开的是当前云函数所属的服务空间,再点「数据库」→ 找到目标表 → 点「权限」标签页
- 如果表是通过扩展库(如 opendb)自动创建的,需确认是否已启用付费版空间——公测版可能无法自动创建依赖表
- 联表查询(如
collection('a,b,c'))时,所有涉及的表都得单独配好read权限,缺一不可 - 字段级隐藏(如不让普通用户看到
phone)要写在field节点下:"phone": {"read": "auth.role == 'admin'"},而不是放在顶层permission里
真正卡住人的地方,往往不是规则多复杂,而是 auth.uid 拿不到、schema 没上传、或者表权限配在了错误的服务空间里。每次改完 schema,记得点「测试规则」填模拟数据实时验证,别靠前端反复试错。


















