使用Firestore安全规则检查缺少的字段

时间:2020-06-12 17:43:13

标签: google-cloud-firestore firebase-security

我正在运行由onCreate事件触发的云功能。此功能需要userID,因此在阅读本文后: https://stackoverflow.com/a/50842161/4484332 ..我在创建的文档中传递了userId。

然后,云功能将删除userId字段。

现在,由于我了解到运行云功能最多可能需要10秒钟的时间,因此我想确保在删除userId之前不查询该文档。

function isAdmin(){
    return request.auth.uid == "***(admin's uid)***"
}

match /messages/{message} {
            allow create: if request.auth.uid != null &&
                        (isNewMessage(request.resource.data)||isAdmin()) &&
                        userExists() && (matchesParent()||isFirstChild()||isSeed()||isAdmin());
            allow read: if resource.data.userId == null || resource.data.userId == request.auth.uid
            allow update: if isAdmin();
            allow delete: if isAdmin();
        }

问题出在allow read行:我得到FirebaseError: Property userId is undefined on object.

客户查询:

await db
          .collection("messages")
          .where("subcategoryId", "==", subcategorie)
          .where("rank", "==", 0)
          .orderBy(value, order)
          .limit(paginationNumber)
          .startAfter(last)
          .get();

编辑:规则不是过滤器,看起来这就是我要执行的操作。 也许解决此问题的整个方法是错误的,而我的错误是我将firebase身份验证uid用作“用户”集合中每个用户(包括admin用户)的文档ID。因此,在云函数删除userId字段之前,我不愿意让管理员的uid停留10秒钟。

2 个答案:

答案 0 :(得分:0)

您无法执行的操作是因为security rules are not filters。请仔细阅读该文档-您的规则显然是要成为过滤器。

安全规则无法从查询中过滤出文档。查询要么返回所有匹配的文档,要么生成错误。该查询必须指定自己的过滤器,并且这些过滤器必须与规则所要求的匹配。

如果您想在规则中使用resource.data,则只能用于单个文档get(),而不能用于查询。

答案 1 :(得分:0)

1)无需让您的Cloud Function删除该字段,只需将其设置为虚拟值即表示该字段已被删除。

2)除规则外,在where语句中的userid上添加条件

await db
.collection("messages")
.where("userid", "==", 0)    // Dummy value, use whatever that will never match a real userid
.where("subcategoryId", "==", subcategorie)
.where("rank", "==", 0)
.orderBy(value, order)
.limit(paginationNumber)
.startAfter(last)
.get();

您必须使用一个虚拟值,因为Firestore不允许过滤不存在​​的内容