Transactions Firestore-访问安全规则中的事务/嵌套数据

Transactions Firestore-访问安全规则中的事务/嵌套数据,transactions,firebase-security,google-cloud-firestore,Transactions,Firebase Security,Google Cloud Firestore,我希望有人能在这件事上帮我。我真的很喜欢新的Firestore测试版,但目前缺乏模拟器/调试器,这让我很难解决一个问题 我有一个场景集合,可以投赞成票,也可以投反对票。我想限制任何人多次恶意的向上投票/向下投票,所以我也有一个场景投票的子集合。这些只是由userId键入的文档,其中包含类似 { up: true, down, false } 为了在一个请求中写入这些多个项目(即场景文档和投票子集合),我使用了一个事务 我遇到的问题是,我想验证,当用户更新“积分”时,必须附带一个投票文

我希望有人能在这件事上帮我。我真的很喜欢新的Firestore测试版,但目前缺乏模拟器/调试器,这让我很难解决一个问题

我有一个场景集合,可以投赞成票,也可以投反对票。我想限制任何人多次恶意的向上投票/向下投票,所以我也有一个场景投票的子集合。这些只是由userId键入的文档,其中包含类似

{
  up: true,
  down, false
}

为了在一个请求中写入这些多个项目(即场景文档和投票子集合),我使用了一个事务

我遇到的问题是,我想验证,当用户更新“积分”时,必须附带一个投票文档,该文档设置/设置为true,具体取决于积分以及用户是否已经存在投票

在安全规则中,当我在场景文档级别进行验证时,如何读取请求中是否存在投票子集合数据(反之亦然)?我的理解是,“request.resource.data”只允许您查看当前文档级别的数据(我在这里可能错了,但是没有简单的方法检查,文档中也没有任何内容)。以下是迄今为止我的安全规则示例:

service cloud.firestore {
  match /databases/{database}/documents {
    // Scenarios
    match /scenarios/{scenarioId} {
        allow read;
      // Only allow write if all of these are true
      allow write: if request.auth.uid == request.resource.data.userId &&
                                            // points    
                                    request.resource.data.points == 0;
      allow update: if request.auth.uid != null &&
                       (
                        request.resource.data.points >= (resource.data.points - 2) ||
                        request.resource.data.points <= (resource.data.points + 2)
                       )
                       // TODO: Only allow write to points IF accompanied by a "votes" document for that userId
      // Votes
      match /votes/{voterId} {
        allow write: if voterId == request.auth.uid;
      }
    }
  }
}
service cloud.firestore{
匹配/databases/{database}/documents{
//情景
匹配/场景/{scenarioId}{
允许读取;
//仅当所有这些都为真时才允许写入
允许写入:if request.auth.uid==request.resource.data.userId&&
//要点
request.resource.data.points==0;
允许更新:如果request.auth.uid!=null&&
(
request.resource.data.points>=(resource.data.points-2)||

request.resource.data.points如果您仍然面临此问题,可以尝试使用安全规则中的exists()函数:

allow update: if !exists(/databases/$(database)/documents/scenarios/$(scenarios)/votes/$(request.auth.uid));

可选地,您可能需要考虑将UID列表存储在一个数组中,以检查文件本身中的规则,如果数量不能够达到FixSt店文档配额:

//your document structure
points: 0
someData: xx
voted: [id1, id2, id3 .. n]

//in the rules
allow update: if !(request.auth.uid in resource.data.voted);
使用这种方法,您将需要一个后台工作程序将用户ID添加到数组中,并使用以下方法防止用户写入投票数组:

allow update: if request.resource.data.voted == resource.data.voted;

有人吗?我有同样的问题,你找到解决方案了吗?不幸的是,没有,我向Firebase团队报告过,但从未得到响应。我认为使用exists的问题是1。这是检查现有数据(但我需要验证请求中的数据),2.exists将执行另一次“读取”我想尽量减少我的读取使用量。如果能够检查事务中的数据(Firebase允许的方式),那就太好了。在文档中存储一个数组本身可以工作,但同样,这意味着每次有人执行投票时,我都需要使用云函数和额外的写入操作。它将仔细检查我的写入/云函数调用配额,感觉有点不正常。谢谢你的建议