英文:
Get subcollection with rules on the parent collection
问题
我有一个简单的Firestore规则用于一个集合:
match /mycollection/{documents=**} {
allow read, write: if request.auth != null && request.auth.uid == resource.data.author
allow create: if request.auth != null && request.auth.uid == request.resource.data.author
}
基本上,要访问 mycollection
,author
必须等于 uid
。这是有效的,我可以使用 React 查询这个集合:
import { collection, where, query, orderBy } from 'firebase/firestore';
import { useCollection } from 'react-firebase-hooks/firestore';
// ...
const [col, loading, error] = useCollection(
query(collection(db, "mycollection"), where("author", "==", uid), orderBy("createdAt", "desc"))
)
现在,我想访问一个子集合,但无法这样做:
const [collection, loading, error] = useCollection(
query(collection(db, `mycollection/${id}/subcollection`), orderBy("createdAt", "desc"))
)
我收到了 FirebaseError: Missing or insufficient permissions.
错误。看起来我不能在不对父集合进行身份验证的情况下访问子集合,这没问题。但是,如何在上面的查询中将条件传递给父集合呢?
英文:
I have a simple Firestore rule for a collection:
<!-- language-all: lang-js -->
match /mycollection/{documents=**} {
allow read, write: if request.auth != null && request.auth.uid == resource.data.author
allow create: if request.auth != null && request.auth.uid == request.resource.data.author
}
Basically to access mycollection
, author
must be equal to uid
. This is working fine, where I can query this collection via react using:
import { collection, where, query, orderBy } from 'firebase/firestore';
import { useCollection } from 'react-firebase-hooks/firestore';
...
const [col, loading, error] = useCollection(
query(collection(db, "mycollection"), where("author", "==", uid), orderBy("createdAt", "desc"))
)
...
Now I want to access a sub-collection but cannot do it:
const [collection, loading, error] = useCollection(
query(collection(db, `mycollection/${id}/subcollection`), orderBy("createdAt", "desc"))
)
I get the FirebaseError: Missing or insufficient permissions.
error. Looks like I can't get to the subcollection without authenticating the parent collection, which is fine. But how do I pass the where condition to parent collection in the above query?
答案1
得分: 1
感谢@alex-mamo提供的指导。然而,我可能已经找到了一个对我更有效的解决方案。
match /mycollection/{colId} {
allow read, write: if request.auth != null && request.auth.uid == resource.data.author
allow create: if request.auth != null && request.auth.uid == request.resource.data.author
match /subcollection/{subColId} {
allow read, write, create: if request.auth != null && request.auth.uid == get(/databases/$(database)/documents/mycollection/$(colId)).data.author
}
}
这个规则从父文档中获取作者值,并将其与当前用户的uid进行比较。如果它们相等,用户就可以访问子集合。
英文:
Thanks @alex-mamo for the direction. However I might have found a solution that works better for me.
match /mycollection/{colId} {
allow read, write: if request.auth != null && request.auth.uid == resource.data.author
allow create: if request.auth != null && request.auth.uid == request.resource.data.author
match /subcollection/{subColId} {
allow read, write, create: if request.auth != null && request.auth.uid == get(/databases/$(database)/documents/mycollection/$(colId)).data.author
}
}
This rule gets author value from the parent document and compares it with current user's uid. If they are equal, the user has access to the sub-collection.
答案2
得分: 0
顶级集合的规则不适用于子集合,除非您使用递归通配符。如果对集合和子集合有不同的规则,那么您必须明确为集合和子集合定义它们。因此,为了解决这个问题,您可以将子集合的规则嵌套在集合本身中。因此,您的规则应该如下所示:
match /mycollection/{documents=**} {
allow read, write: if request.auth != null && request.auth.uid == resource.data.author
allow create: if request.auth != null && request.auth.uid == request.resource.data.author
match /subcollection/ {
//您的规则
}
}
但是,如果规则相同,您可以使用递归通配符:
service cloud.firestore {
match /databases/{database}/documents {
// 匹配mycollection集合中的任何文档,以及子集合中的任何文档。
match /mycollection/{document=**} {
allow read, write: if <condition>;
}
}
}
还请参考下面的链接,了解如何使用分层数据:
英文:
The rules for the top-level collections do not apply to sub-collections unless you are using a recursive wildcard. If you have different rules for the collection and sub-collection, then you have to explicitly define them for the collection and sub-collections. So to solve this, you can nest the sub-collections rules in the collection itself. So your rules should look like this:
match /mycollection/{documents=**} {
allow read, write: if request.auth != null && request.auth.uid == resource.data.author
allow create: if request.auth != null && request.auth.uid == request.resource.data.author
match /subcollection/ {
//Your rules
}
}
However, if the rules are the same, you can use a recursive wildcard:
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the mycollection collection as well as any document in a subcollection.
match /mycollection/{document=**} {
allow read, write: if <condition>;
}
}
}
Please also see below, a link that explains how to use hierarchical data:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论