我正在使用Firebase实时数据库。我有以下数据:
我也有规则:
{
"rules": {
".read": "auth != null",
".write": "auth != null",
"chat": {
"$key": {
".read": "data.child('memberId1').val() === auth.uid && data.child('memberId2').val() === auth.uid",
".write": "data.child('memberId1').val() === auth.uid || data.child('memberId2').val() === auth.uid"
}
},
初始规则完美无缺:
".read": "auth != null",
".write": "auth != null",
问题
以下2条规则无效。
"chat": {
"$key": {
".read": "data.child('memberId1').val() === auth.uid && data.child('memberId2').val() === auth.uid",
".write": "data.child('memberId1').val() === auth.uid || data.child('memberId2').val() === auth.uid"
}
},
正如您所看到的,为了测试这些规则,在第一条规则中,我已经使memberId1
和memberId2
的不可能条件都等于用户uid
。结果我希望它失败。
如果我删除:
".read": "auth != null",
".write": "auth != null",
并且只有:
"chat": {
"$key": {
".read": "data.child('memberId1').val() === auth.uid || data.child('memberId2').val() === auth.uid",
".write": "data.child('memberId1').val() === auth.uid || data.child('memberId2').val() === auth.uid"
}
},
然后访问被拒绝。即使我将其更改为:
"data.child('memberId1').val() === 'h6qQg5YfQveTaCyBEXwDMSJPqwk1'
以下内容也被拒绝:
"chat": {
"Ko7w9XTtuRVN4p6CMp7": {
".read": true,
问题
如何构建规则以允许用户只能访问uid
与memberId1
或memberId2
匹配的行?
由于
更新
我有以下代码:
findChats(): Observable<any[]> {
return this.af.database.list('/chat/', {
query: {
orderByChild: 'negativtimestamp'
}
}).map(items => {
const filtered = items.filter(
item => (item.memberId1 === this.me.uid || item.memberId2 === this.me.uid)
);
return filtered;
});
}
我的问题类似于this one。我尝试以下方法但没有成功:
{
"rules": {
"chat": {
"$id": {
".read": true
}
},
答案 0 :(得分:2)
Firebase规则是原子的。因此,如果您尝试阅读/chat
(这就是您当前正在做的事情),它只会检查/chat
分支规则。由于您在/chat
中没有任何规则,因此默认情况下它不提供访问权限。因此,只有在您尝试阅读/chat/chatId
时才会评估您的规则。
您可以采用的一种可能解决方案是存储每个用户所属的聊天列表。因此,您可以保留当前的聊天分支,但使用以下结构将另一个分支存储在数据库中:
user_chats: {
uid1: {
chatId1: true,
chatId2: false
}
uid2: ...
}
规则:
"user_chats": {
"$uid": {
".read": "auth.uid === $uid",
".write": "auth.uid === $uid"
}
}
然后,您可以保留chat
规则,就像您已经拥有它们一样,但首先从/user_chats/uid
获取数据,然后对于检索到的每个chatId
,您需要阅读{{1 }}