经过身份验证的用户电子邮件的 Firestore 数据库规则

时间:2021-07-12 07:55:05

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

目的:登录用户的文档应该是用户可以访问的。

集合结构:

> root(collection_name)
    > user1@gmail.com(document_name)
        > "name" : "User One"(field key and value)
    > user2@gmail.com
        > "name" : "User TWO"

我使用的 Android 代码

db.collection("/root/")
                .get()
                .addOnCompleteListener(task -> {
                    if (task.isSuccessful()) {
                        for (QueryDocumentSnapshot document : Objects.requireNonNull(task.getResult())) {
                            System.out.println(document.getId() + " => " + document.getData());
                        }
                    } else {
                        System.out.println(task.getException());
                    }
                });

我尝试过的数据库规则:

    service cloud.firestore {
      match /databases/{database}/documents {
        match /root/{email} {
          allow read, update, delete: if request.auth.token['email'] == email;
          allow create: if request.auth != null;
        }
      }
    }
    

我得到的错误:

<块引用>

com.google.firebase.firestore.FirebaseFirestoreException:PERMISSION_DENIED:权限缺失或不足。

Listen for Query(target=Query(root order by name);limitType=LIMIT_TO_FIRST) 失败:状态{code=PERMISSION_DENIED, description=权限缺失或不足。,cause=null}

我也试过使用

service cloud.firestore {
  match /databases/{database}/documents {
    match /root/{email} {
      allow read, update, delete: if request.auth!=null;
      allow create: if request.auth != null;
    }
  }
}

上述规则返回集合中的所有文档,但我只希望它返回登录的特定用户的文档。所以我知道问题在于检查用户的电子邮件。

1 个答案:

答案 0 :(得分:2)

当您使用以下规则时:

match /root/{email} {
  allow read, update, delete: if request.auth.token['email'] == email;
  allow create: if request.auth != null;
}

这意味着您只允许经过身份验证的用户在您指向的位置(即用户的文档)读取、更新或删除数据。但是,在您的代码中,您从整个“根”集合中请求数据:

db.collection("/root/").get()

因此出现错误消息。要解决此问题,您可以更改代码中的查询,或者更改规则。但很可能您应该使用以下参考更改获取数据的方式:

db.collection("root").document(userEmail).get().addOnCompleteListener(/* ... /*);