基于映射值的Firestore安全规则

时间:2017-10-10 19:20:43

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

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

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

对于以下示例,我没有将电子邮件用作地图密钥,因为它已经不能使用基本字符串。

数据库结构如下所示:

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]中的值为真,此安全规则应允许读取所有人的访问权限。

为了完整性:这是我使用的查询(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'一样访问地图,那么我做错了什么?

2 个答案:

答案 0 :(得分:9)

修改:此问题现在应该修复。如果您仍然看到它(并且确定它是规则评估者的错误),请在评论中告诉我。

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

因此,基本上,您正在做的事情应该可以正常工作,并且您需要等待Firestore团队的更新才能使此查询正常工作。当发生这种情况时,我会记得更新这个答案。很抱歉'回合!

答案 1 :(得分:0)

无论何时具有(可选)嵌套属性,都应先确保该属性存在,然后再继续检查其值,例如。

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

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

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

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