【问题标题】:Firestore security rules based on map values基于地图值的 Firestore 安全规则
【发布时间】:2018-03-22 07:28:25
【问题描述】:

我想根据用户的电子邮件地址存储是否允许用户在文档本身中阅读文档。多个用户应该可以访问同一个文档。

根据the documentation Firestore 不允许查询数组成员。这就是为什么我将用户的电子邮件地址存储在 String-Bool Map 中,并以电子邮件地址作为键。

对于以下示例,我没有使用电子邮件作为映射键,因为它已经不适用于基本字符串。

数据库结构如下:

lists
  list_1
    id: String
    name: String
    owner: E-Mail
    type: String
    shared:
      test: true

此处列出了所有安全规则:

service cloud.firestore {
  match /databases/{database}/documents {
    match /lists/{listId=**} {
        allow read: if resource.data.shared.test == true
    }
  }
}

编辑:如果我使用match /lists/{listId} 而不是match /lists/{listId=**},它也不起作用

我的理解是,如果映射 shared[test] 中的值为 true,则此安全规则应该允许所有人进行读取访问。

为了完整起见:这是我正在使用的查询(Android 上的 Kotlin):

collection.whereEqualTo("shared.test", true).get()
        .addOnCompleteListener(activity, { task ->
            if (task.isSuccessful) {
                Log.i("FIRESTORE", "Query was successful")
            } else {
                Log.e("FIRESTORE", "Failed to query existing from Firestore. Error ${task.exception}")
            }
        })

我猜我无法从安全规则中访问映射值。那么我的问题的替代解决方案是什么?

Firestore rules reference 中写到可以像resource.data.property == 'property' 那样访问地图所以,我做错了什么?

【问题讨论】:

  • 我看到的所有关于 resource.data 的示例都没有 ** 通配符语法,所以也许 resource.data 只有在您使用match /lists/{listId} 而不是match /lists/{listId=**} 时才有效?值得一试。
  • 不,不幸的是这也不起作用
  • 嗯...老实说;这看起来应该可以正常工作。您能否先仔细检查一下您是否不小心在实时数据库中而不是 Cloud Firestore 中存储数据/编辑规则? (有时会发生)另外,如果您不进行查询,而只是尝试获取单个文档,会发生什么情况?
  • @ToddKerpelman 数据在 Firestore 中。不是实时数据库。当直接使用db.document("lists/acaa0247-eccd-4ff0-b986-7f8b6187e45f").get() 阅读文档时,它可以工作。
  • 这个问题仍然没有得到解决(2020 年 3 月),尽管评论最多。所以嵌套属性不起作用。由于我无法对此帐户发表评论,因此将其作为单独的答案发布。所以请不要在规则中使用嵌套属性。他们将与本地测试一起工作,但不是在部署之后。

标签: firebase firebase-security google-cloud-firestore


【解决方案1】:

只要您有(可选)嵌套属性,您应该确保该属性存在,然后再继续检查其值,例如。

allow read: if role in request.auth.token && request.auth.token[role] == true

在你的情况下:

allow read: if test in resource.data.shared && resource.data.shared.test == true

,我在角色方面苦苦挣扎了很长时间,直到我意识到在非管理员用户上,管理字段是未定义的,firestore 规则只是崩溃并且不会继续检查其他可能的匹配项。

对于没有 token.admin 的用户,无论您是否有其他匹配项为真,这将始终崩溃,例如:

function userHasRole(role) {
  return isSignedIn() && request.auth.token[role] == true
}

【讨论】:

    【解决方案2】:

    编辑:现在应该修复这个问题。如果您仍然看到它(并且确定这是规则评估器的错误),请在 cmets 中告诉我。

    我在这里与一些人聊过您遇到的问题,这似乎是安全规则本身的问题。从本质上讲,问题似乎特定于评估查询中的嵌套字段,就像您正在做的那样。

    因此,基本上,您正在执行的操作应该可以正常工作,并且您需要等待 Firestore 团队的更新才能使此查询正常工作。发生这种情况时,我会尽量记住更新此答案。对不起!

    【讨论】:

    • 有没有关于这个或地方的更新来检查我们自己?我也被这个问题阻止了,没有好的解决方法(没有重组数据)我们被挂了
    • 暂无更新,但我知道团队正在积极努力。
    • @ToddKerpelman 从您的编辑看来,这是可行的。它应该与电子邮件地址一起使用吗? stackoverflow.com/questions/46631421/… 这里有一条评论说它不会。我为这个案例创建了一个新问题stackoverflow.com/questions/49265907/…
    • 您好,这里有一个类似的问题,非常令人困惑。 stackoverflow.com/questions/50929366/… 非常感谢 :)
    猜你喜欢
    • 2019-06-15
    • 2018-08-04
    • 2020-05-23
    • 1970-01-01
    • 2018-11-27
    • 2019-07-23
    • 1970-01-01
    • 2020-11-27
    • 1970-01-01
    相关资源
    最近更新 更多