Validation 用于验证多个批量创建的firestore规则

Validation 用于验证多个批量创建的firestore规则,validation,google-cloud-firestore,firebase-security,Validation,Google Cloud Firestore,Firebase Security,我正在编写一个应用程序,用户可以在线程中放置注释。由于我使用Firestore的NoSQL后端进行此操作,因此我将每个注释存储在两个位置: /threads/THREADID/comments/COMMENTID /users/USERID/comments/COMMENTID 通过这种方式,我可以对一个线程中的所有评论进行概述,也可以对用户发布的所有评论进行概述。为了确保始终创建这两个注释,我使用了批写。批处理写入是原子性的,因此这不会导致任何问题,但我担心的是,恶意用户可能会使用自定义代码

我正在编写一个应用程序,用户可以在线程中放置注释。由于我使用Firestore的NoSQL后端进行此操作,因此我将每个注释存储在两个位置:

/threads/THREADID/comments/COMMENTID
/users/USERID/comments/COMMENTID
通过这种方式,我可以对一个线程中的所有评论进行概述,也可以对用户发布的所有评论进行概述。为了确保始终创建这两个注释,我使用了批写。批处理写入是原子性的,因此这不会导致任何问题,但我担心的是,恶意用户可能会使用自定义代码在一个位置创建注释,而不是在两个位置都创建注释。我需要找到一个规则来验证是否创建了两个注释,或者两个注释都不应该创建

  match /users/{userId}/comments/{commentId} {  
    allow create: if exists(/databases/$(database)/documents/threads/$(request.resource.data.threadId)/comments/$(commentId)
  }

  match /threads/{threadId}/comments/{commentId} {  
    allow create: if exists(/databases/$(database)/documents/users/$(request.auth.uid)/comments/$(commentId)
  }
commentId被重用,因此它在两个集合中应该是相同的,所以我可以在我的规则中重用它。前面的示例显然失败了,因为要插入到一个位置,我要求它已经插入到另一个位置,反之亦然

谢谢大家!

编辑:

云函数更适合解决这个问题。使用onCreate触发器,可以在/threads下创建/users后自动创建此文档。也就是说,我的旧解决方案没有云功能,如下所示:

没有云功能的解决方案:

没有与getAfter()等价的existsAfter()(存在用于在批处理或事务之后验证数据的函数)。因此,我是如何做到这一点的,遵循以下规则:

  match /users/{userId}/comments/{commentId} {  
    allow create: if getAfter(/databases/$(database)/documents/threads/$(request.resource.data.threadId)/comments/$(commentId)).data.author == userId;
  }

  match /threads/{threadId}/comments/{commentId} {  
    allow create: if getAfter(/databases/$(database)/documents/users/$(request.auth.uid)/comments/$(commentId)).data.createdAt == request.time;
  }

getAfter()函数将在回写后检查有效性,并检查字段的值。因为我只需要检查它们是否存在,所以字段的值实际上并不重要。

您是否可以编辑您的问题,以包含可用于拒绝规则的最低代码?如果我理解正确,您希望将这些安全规则设置为“确保始终创建这两个注释”。由于您使用的是批处理写入,因此不需要使用安全规则来确保“始终同时创建两条注释”,因为“本质上”,批处理写入是原子的。@user2696806感谢您的澄清:您的目标现在更加明确了!自答案发布后是否添加了
existsAfter
方法?看起来是这样的: