Firebase实时数据库规则问题:已认证用户无法获取自身聊天列表
解决Firebase Realtime Database聊天列表的权限问题
咱先来理清楚你遇到的权限报错核心原因:Firebase Realtime Database的规则是自上而下评估的,当你尝试读取/Chats这个父节点时,它会先检查你有没有读取整个/Chats的权限,而不是挨个检查子聊天节点的权限。你的两次规则设置都没踩对这个点:
- 初始规则里,
/Chats的.read条件是data.child('users').hasChild(auth.uid)——这里的data指的是/Chats本身,但你的users节点是在每个具体聊天ID下面的,所以这个条件永远不成立,自然读不了。 - 修改后的规则给每个
/Chats/$chatId设置了正确的.read条件,但/Chats本身没开读取权限(默认是拒绝),所以你查整个/Chats的时候直接被拦了。
正确的解决方案
要让用户能拿到自己的聊天列表,得把规则验证和匹配的查询结合起来,让Firebase能精准过滤出用户有权访问的聊天。
1. 更新数据库规则
把规则改成下面这样,用查询验证来限制用户只能读取包含自己UID的聊天:
{ "rules": { "Chats": { // 要求用户已认证,且查询必须按users/[当前UID]排序、筛选值为true的结果 ".read": "auth != null && query.orderByChild = 'users/' + auth.uid && query.equalTo(true)", // 这里提醒下:你当前的.write: true权限太松了,任何已认证用户都能改所有聊天,后续建议收紧 ".write": "true" } } }
关于写入权限的优化建议:如果要确保只有聊天成员才能修改聊天,可以把
.write改成:".write": "auth != null && (data.exists() ? data.child('users').hasChild(auth.uid) : newData.child('users').hasChild(auth.uid))"这个规则的意思是:创建聊天时,用户必须在成员列表里;修改/删除聊天时,用户也得是聊天成员。
2. 调整查询代码
你的查询必须和规则要求完全匹配——按users/[当前用户UID]排序,只筛选值为true的聊天:
// 先拿到当前已认证用户的UID const currentUserId = firebase.auth().currentUser.uid; firebase.database().ref('Chats') .orderByChild(`users/${currentUserId}`) .equalTo(true) .limitToLast(20) .on('child_added', snapshot => { callback(this.parse(snapshot)) }, function (errorObject) { console.log("The read failed: " + errorObject); });
为什么这样能解决问题?
Firebase的规则会严格校验你的查询是否符合权限要求:
- 你明确指定了按
users/${currentUserId}排序,并且只取值为true的结果 - 规则会逐个检查每个聊天节点的
users/${auth.uid}是否为true,只有符合条件的聊天才会被返回 - 因为查询和规则完全匹配,Firebase就会允许读取这些符合条件的子节点,不会再触发权限错误啦
内容的提问来源于stack exchange,提问作者khpo
相关产品推荐
相关产品推荐

