用于 Firebase 规则的 JsonPath
JsonPath used for Firebase Rules
我有以下数据:
我有以下代码:
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;
});
}
如果我使用上面的 JsonPath ('/chat/'
) 访问数据库,它 returns 所有匹配的行,然后代码过滤结果。
我确实定义了以下数据库规则:
{
"rules": {
"chat": {
"$key": {
".read": true
}
},
....
我在模拟器中测试的是:
/chat/-Ko7w9XTtuRVN4p6CMp7/memberId
它找到了一个匹配项。
现在当我 运行 使用此规则的代码时,我得到:
Error: permission_denied at /chat: Client doesn't have permission to
access the desired data
问题
我无法让代码 JsonPath 通过规则的原因是因为它只是 /chat/
吗?
为了匹配规则,代码 JsonPath 是否也必须包含 $key
和 memberId
?
例如/chat/-Ko7w9XTtuRVN4p6CMp7/memberId
正如您从我的代码中看到的那样,我正在尝试获取过滤后的 chats
列表,并且代码不知道 $key
值是什么。那么是否不可能将规则应用于只允许访问匹配行的查询?
更新
我的问题类似于。我尝试了以下但没有成功:
{
"rules": {
".write": "auth != null",
"chat": {
"$id": {
".read": true
}
},
更新
我目前有以下规则,该规则有效,但还不够。它检查用户是否已通过身份验证,但不检查他们的 auth.id
等于 memberId1
或 memberId2
.
{
"rules": {
"chat": {
".read": "auth != null",
".write": "auth != null"
},
"message": {
".read": "auth != null",
".write": "auth != null"
}
}
}
您收到错误的原因是 Firebase 规则级联。
请查看 this doc 的 "Read and Write Rules Cascade" 和 "Rules Are Not Filters" 部分。
级联本质上意味着以下内容:-
.read and .write rules work from top-down, with shallower rules overriding deeper rules. If a rule grants read or write permissions at a particular path, then it also grants access to all child nodes under it.
因此,如果规则限制访问(或者如果规则不存在)到更高的节点,那么您将无法访问该节点。
因此,在您的情况下,您可以通过从客户端代码访问 /chat/-Ko7w9XTtuRVN4p6CMp7/memberId
路径来测试它,您会发现它可以正常工作。
Firebase 文档中的以下示例是您情况的副本:-
Rules are applied in an atomic manner. That means that a read or write operation is failed immediately if there isn't a rule at that location or at a parent location that grants access. Even if every affected child path is accessible, reading at the parent location will fail completely. Consider this structure:
{
"rules": {
"records": {
"rec1": {
".read": true
},
"rec2": {
".read": false
}
}
}
}
Without understanding that rules are evaluated atomically, it might
seem like fetching the /records/ path would return rec1 but not rec2.
The actual result, however, is an error:
我有以下数据:
我有以下代码:
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;
});
}
如果我使用上面的 JsonPath ('/chat/'
) 访问数据库,它 returns 所有匹配的行,然后代码过滤结果。
我确实定义了以下数据库规则:
{
"rules": {
"chat": {
"$key": {
".read": true
}
},
....
我在模拟器中测试的是:
/chat/-Ko7w9XTtuRVN4p6CMp7/memberId
它找到了一个匹配项。
现在当我 运行 使用此规则的代码时,我得到:
Error: permission_denied at /chat: Client doesn't have permission to access the desired data
问题
我无法让代码 JsonPath 通过规则的原因是因为它只是 /chat/
吗?
为了匹配规则,代码 JsonPath 是否也必须包含 $key
和 memberId
?
例如/chat/-Ko7w9XTtuRVN4p6CMp7/memberId
正如您从我的代码中看到的那样,我正在尝试获取过滤后的 chats
列表,并且代码不知道 $key
值是什么。那么是否不可能将规则应用于只允许访问匹配行的查询?
更新
我的问题类似于
{
"rules": {
".write": "auth != null",
"chat": {
"$id": {
".read": true
}
},
更新
我目前有以下规则,该规则有效,但还不够。它检查用户是否已通过身份验证,但不检查他们的 auth.id
等于 memberId1
或 memberId2
.
{
"rules": {
"chat": {
".read": "auth != null",
".write": "auth != null"
},
"message": {
".read": "auth != null",
".write": "auth != null"
}
}
}
您收到错误的原因是 Firebase 规则级联。
请查看 this doc 的 "Read and Write Rules Cascade" 和 "Rules Are Not Filters" 部分。
级联本质上意味着以下内容:-
.read and .write rules work from top-down, with shallower rules overriding deeper rules. If a rule grants read or write permissions at a particular path, then it also grants access to all child nodes under it.
因此,如果规则限制访问(或者如果规则不存在)到更高的节点,那么您将无法访问该节点。
因此,在您的情况下,您可以通过从客户端代码访问 /chat/-Ko7w9XTtuRVN4p6CMp7/memberId
路径来测试它,您会发现它可以正常工作。
Firebase 文档中的以下示例是您情况的副本:-
Rules are applied in an atomic manner. That means that a read or write operation is failed immediately if there isn't a rule at that location or at a parent location that grants access. Even if every affected child path is accessible, reading at the parent location will fail completely. Consider this structure:
{
"rules": {
"records": {
"rec1": {
".read": true
},
"rec2": {
".read": false
}
}
}
}
Without understanding that rules are evaluated atomically, it might seem like fetching the /records/ path would return rec1 but not rec2. The actual result, however, is an error: