获取具有关于父集合的规则的子集合。

huangapple go评论75阅读模式
英文:

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
}

基本上,要访问 mycollectionauthor 必须等于 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 &amp;&amp; request.auth.uid == resource.data.author
  allow create: if request.auth != null &amp;&amp; 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 &#39;firebase/firestore&#39;;
import { useCollection } from &#39;react-firebase-hooks/firestore&#39;;

...
const [col, loading, error] = useCollection(
  query(collection(db, &quot;mycollection&quot;), where(&quot;author&quot;, &quot;==&quot;, uid), orderBy(&quot;createdAt&quot;, &quot;desc&quot;))
)
...

Now I want to access a sub-collection but cannot do it:

const [collection, loading, error] = useCollection(
  query(collection(db, `mycollection/${id}/subcollection`), orderBy(&quot;createdAt&quot;, &quot;desc&quot;))
)

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 &amp;&amp; request.auth.uid == resource.data.author
  allow create: if request.auth != null &amp;&amp; request.auth.uid == request.resource.data.author
  
  match /subcollection/{subColId} {
    allow read, write, create: if request.auth != null &amp;&amp; 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 &amp;&amp; request.auth.uid == resource.data.author
  allow create: if request.auth != null &amp;&amp; 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 &lt;condition&gt;;
    }
  }
}

Please also see below, a link that explains how to use hierarchical data:

huangapple
  • 本文由 发表于 2023年7月20日 16:28:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76728009.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定