带子集合的Firestore查询规则 [英] Firestore query rules with sub collections

查看:58
本文介绍了带子集合的Firestore查询规则的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有关于Firestore规则的问题.

I have a question regarding firestore rules.

我有一个保存文档的集合...,这些文档也有子集合....,这些文档也有子集合.

I have a collection that holds documents... and these documents also have sub- collections.... and these documents also have subcollections.

例如

"Collection" -> "Document" -> "Sub-collection-1"  -> "Document1" -> "Sub-collection-2" -> "Document2"
              
(i have changed the names to make it simpler to understand)                                     

我有2个时间戳存储在文档"用于控制用户何时能够阅读文档的...它必须在"startTimestamp"之后但在"endTimestamp"之前.

I have a 2 timestamps stored in the "Document" that are used to control when the user is able to read the document... e.g. it must be after the 'startTimestamp' but before the 'endTimestamp'.

我对此的规则如下.

        allow read: if request.auth.uid != null
                  && int(resource.data.startReadTimestamp) < request.time.toMillis()
                  && int(resource.data.endReadTimestamp) > request.time.toMillis()

我的问题是,如果用户尝试读取子集合文档,例如文档1"或"Document2"并且根据文档"中的时间戳,他们请求的时间无效.会因为父收集规则而自动拒绝吗?

My question is that if the user tries to read a sub-collection document, e.g. "Document1" or "Document2" and the time they request is invalid based on the timestamps in "Document" will this automatically reject because of the parent collection rule?

如果没有,我已经看到您可以使用与get结合使用的功能来访问其他文档,但这似乎很浪费,因为这将使我无法自拔.

If not, I have seen that you can use the functions combined with get to access other documents but it seems wasteful as this will be charging me reads.

例如这样做

  function getTopLevelDocData() {
            return get(/databases/$(database)/documents/Collection/$(documentWildcard)).data
        }

我唯一想到的另一种方法是将时间戳记写入子集合中的每个文档...但这可能很难跟踪.

The only other method I can think of is writing the timestamps to each document in the sub collection... but this could be hard to keep track of.

我们将不胜感激:)

---更新

我刚刚尝试过,它确实允许读取"Document1"如果我不调用检查文档"的功能,"Document1"中的时间戳规则...为了澄清起见,将阅读"Document1"或"Document2"只需多读一遍,因为它必须检查文档"时间戳?

I just tried it and it does allow reads to "Document1" If i dont call the function that checks the "Document" timestamps in the "Document1" rules... Just to clarify will reading "Document1" or "Document2" be only 1 extra read as it will have to check the "Document" timestamps?

---第二次更新

想象一下文档"上面示例中的文档名称实际上是"2020-08-29".

Imagine "Document" in the above example actually has the doc name "2020-08-29".

如果我尝试阅读"Document1",或"Document2"是否有一个Firestore规则,该规则不会引起任何文档读取,但是在请求时间戳(转换后)与父"Document"标签不匹配的情况下,仍会阻止读取.名称,例如" 2020-08-29"

If I try to read "Document1" or "Document2" is there a firestore rule that will not incur any document reads but will still block reads where the request timestamp (after transformation) does not match the parent "Document" name, e.g. "2020-08-29"

例如,这样的工作可行吗?

for Example, would something like this work?

match /collection/{document}{
   match /Sub-collection-1/{document1}{

      function transfomRequestTimestampToDate(){
           return request.time.year() + "-" + request.time.month() + request.time.day();
      }

      allow read  if request.auth.uid != null && transfomRequestTimestampToDate() == {document}
   }
}

推荐答案

我只是试过了,如果我不调用该函数,它确实允许读取...

I just tried it and it does allow reads If i dont call the function...

您不会显示将问题中显示的 read 安全规则应用于哪个集合,但是请注意 resource.data 指向 资源 试图阅读,因此,如果子集合文档中没有相应的字段,则这些文档将无法正常工作.

You don't show to which collection(s) you apply the read security rules shown in your question, but note that resource.data points to the resource you are trying to read, therefore if you don't have the corresponding fields in the subcollections docs, it will not work as such for these docs.

将读取"Document1"或"Document2"只能多读一遍将必须检查文档"时间戳?

Will reading "Document1" or "Document2" be only 1 extra read as it will have to check the "Document" timestamps?

是的,它将在每次评估安全规则时继续读取一个文档.

Yes, it will cont for one document read each time the security rule is evaluated.

是的,通过使用通配符语法,您可以使用父级的文档ID来为子级编写规则,例如,如下所示:

Yes, by using the wildcard syntax, you can use the document ID of the parent to write the rules for the children, like, for example, as follows:

service cloud.firestore {
  match /databases/{database}/documents {
    match /Collection/{parentDocId} {
      allow read: if parentDocId == '2020-08-29';

        match /Subcollection1/{SubcollectionDoc} {
           allow read: if parentDocId == '2020-08-29';
        }
    }
  }
}

,如果要使其动态化,可以执行以下操作:

and if you want to make this dynamic, you could do as follows:

service cloud.firestore {
  match /databases/{database}/documents {
    match /a/{a} {
      allow read: if a == string(request.time.year()) + "-" + string(request.time.month()) + "-" +  string(request.time.day());

        match /b/{b} {
                 allow read: if a == string(request.time.year()) + "-" + string(request.time.month()) + "-" +  string(request.time.day());

        }
    }
  }
}

但是,请注意, string(request.time.day()) string(request.time.month())将返回一个字符的字符串,用于十月前的几个月,例如8月8日或10日之前的8天.您可以通过使用YYYY-M-D或微调安全规则来解决此问题.

However, note that string(request.time.day()) and string(request.time.month()) will return a string of one character for months before October, e.g. 8 for August or days before 10. It's up to you to deal with that, either by using YYYY-M-D or by fine tuning the security rule.

这篇关于带子集合的Firestore查询规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆