我正在运行由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秒钟。
答案 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不允许过滤不存在的内容