首页 > 解决方案 > 使用 firebase 规则限制每个用户创建一个文档的 firestore 文档

问题描述

我有一个Questions收藏。它里面是一个嵌套的集合Responses。因此,可以在该特定文档中找到对特定问题的所有回答。

我必须限制用户对同一问题发送多个回复。

目前,我通过将用户的保存在响应文档中来在服务器端(admin-SDK)上执行此操作。uid

 firestore
    .collection("questions")
    .doc(questionID)
    .collection("responses")
    .where("uid", "==", AuthUser.id)
    .get().then(snapshot => {
      if (snapshot.docs.length == 0) {
        let createdAt = Date.now()
        firestore
            .collection("questions")
            .doc(questionID)
            .collection("responses")
            .add({
              uid: AuthUser.id,
              answer,
              createdAt,
              updatedAt: createdAt
        }).then(() => {
            return res.status(200).json({ msg: 'Success' })
        })
      } else {
        return res.status(400).json({ error: 'You cannot send more than one response' })
      }
    })

有什么方法可以通过 firebase 安全规则实现这种行为?

标签: firebasegoogle-cloud-firestorefirebase-security

解决方案


最简单的方法是让用户写入 ID 等于其用户 ID 的文档,而不是随机 ID。如果您不将 userId 存储在文档的 ID 中,那么您将不得不遍历所有现有响应以检查用户是否提交了多个响应。

firestore
    .collection("questions")
    .doc(questionID)
    .collection("responses")
    .doc(user.uid)
    .set({ ..... })

如果您让用户使用与他们的用户 ID 匹配的 ID 写入文档,那么构建规则非常简单,这样人们只能编辑自己的响应。

这是一个示例,允许任何人阅读回复,并且人们只能创建/更新/删除自己的文档。这确保他们只能提交一个响应,因为他们只能在这一键上写入数据。

service cloud.firestore {
  match /databases/{database}/documents {
  match /Questions/{questionId}/responses/{responseId} {

    allow create, update, delete: if request.auth.uid == responseId;
    allow read: if true;
  }
  }
}

推荐阅读