Firebase Firestore安全规则-根据资源读取所有嵌套文档(但它为null) [英] Firebase Firestore security rules - read all nested docs based on resource (but it's null)

查看:50
本文介绍了Firebase Firestore安全规则-根据资源读取所有嵌套文档(但它为null)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为我做错了事,但我不知道是哪一部分...感谢我能得到的所有澄清.

I think I'm doing something wrong but I can't figure which part... Thanks for all the clarification I can get.

所以我有一个名为Bases的集合,看起来像这样:

So I have a collection named Bases that looks like this:

{
  "id1": {
    "name": "My base 1",
    "roles": {
      "idUser_123": {
        "name": "John"
      }
    }
  },
  "id2": {
    "name": "My base 2",
    "roles": {
      "idUser_456": {
        "name": "Jane"
      }
    }
  }
}

idUser_123登录并想要访问他的收藏集.所以我做: db.collection('bases').get()

idUser_123 log in and want to access his collection. So I do: db.collection('bases').get()

并且我使用匹配规则来确保John不会阅读Jane的碱基.那就是我认为错了的地方,因为我将规则用于过滤器目的.

And I use a match rule to make sure John is not reading Jane's bases. And that's where I think I'm wrong cause I'm using rule for filter purpose.

match /bases/{document=**}{
    allow read: if request.auth.uid in resource.data.roles;
}

哪个失败是因为资源为空...我试图这样做:

Which failed because resource is null... I tried to do this:

match /bases/{baseId}{
    allow read: if request.auth.uid in resource.data.roles;
}

当请求特定文档时,此操作在模拟器中进行,但是当我从客户端获取没有baseId的get()时失败-因为我想要它们全部.

This work in the simulator when requesting specific document but fails when I'm get() without baseId from client - cause I want them all.

那我应该如何处理这个非常基本的用例(IMO)?

So how am I supposed to handle this very basic use case (IMO)?

我不能将所有用户的baseId都放在user.token中,因为它很快就会超过1000个字节.

I can't put all user's baseId in user.token as it'll be over 1000 bytes quite fast.

我可以创建其他集合角色,以在baseId和我的用户之间创建关系,但是对于一个简单的用例来说,这似乎过分设计了.

I can make an other collection Roles to create a relation between a baseId and my user but that's seems overengineered for a simple use case.

或者我可以在服务器上发出请求并过滤 where("roles","has",user.uid)吗?我认为,非常快地击败了在客户端获取数据的目的...

Or I can make the request on a server and filter where("roles", "has", user.uid) ? Defeat the purpose of fetching data on client side very very quickly in my opinion...

任何有关如何解决此问题的建议将不胜感激!非常感谢:)

Any recommendation on how to address this will be gladly appreciated! Thanks a lot :)

推荐答案

这里有两个问题.

首先,您的查询要求接收所有以碱基为基础的文档,但是您的规则不允许任何人简单地接收所有文档.重要的是要意识到 Firestore安全规则不是过滤器.他们不会从查询中剥离文档-实际上不会扩展.如果某条规则对谁可以根据某些文件的内容进行查询提出了要求,则该查询将必须使用与该规则要求相匹配的过滤器.

Firstly, your query is demanding to receive all of the documents in bases, but your rules do not allow anyone to simply receive all documents. It's important to realize that Firestore security rules are not filters. They do not strip documnts from a query - this actually does not scale. If a rule puts requirements on who can query certain documents based on their contents, the query will have to use a filter that matches what the rule requires.

第二,您的数据的结构没有使客户端可以基于用户的UID仅对某些文档执行过滤器.Firestore没有可以检查地图字段是否存在的查询.它只能检查地图值.您可能需要重组文档数据,以便客户端实际上可以使用过滤器执行查询,以仅获取当前用户的文档.

Secondly, your data isn't structured in a way that the client can perform a filter of only certain documents based on the user's UID. Firestore doesn't have queries that can check for the existence of a map field. It can only check for map values. You might want to restructure your document data so that the client can actually perform a query with a filter to get only the documents for the current user.

如果角色是UID数组:

If roles was an array of UIDs:

  "id1": {
    "name": "My base 1",
    "roles": [ "idUser_123" ]
  },

然后客户端可以对该字段进行过滤:

Then the client could filter on that field:

firebase.firestore()
    .collection("bases")
    .where("roles", "array-contains", uid)

您可以在规则中强制使用该过滤器:

And you could enforce the use of that filter in rules:

match /bases/{document=**} {
    allow read: if request.auth.uid in resource.data.roles;
}

但是您可能想要做一些不同的事情.

But you might want to do something different.

这篇关于Firebase Firestore安全规则-根据资源读取所有嵌套文档(但它为null)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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