原子多节点更新,它们之间具有验证依赖性

时间:2016-09-01 16:20:10

标签: javascript firebase firebase-realtime-database firebase-security

我正在尝试使用ref().update

以原子方式更新多个节点 下面的示例是updatefirebase documentation的修改版本,其中包含多个子项

因此,当用户创建帖子时,代码将自动执行以下操作

  • /app-user/$uid/lastpost_timestamp更新为firebase服务器时间戳(用于速率限制)
  • 使用相同的时间戳
  • 在/ posts / $ postid下创建新帖子
  • 在/ user-posts / $ uid / $ postid中创建具有相同时间戳的用户参考帖子

JS代码

function writeNewPost(uid, username, picture, title, body) {
  // A post entry.
  var postData = {
    author: username,
    uid: uid,
    body: body,
    title: title,
    starCount: 0,
    authorPic: picture,
    timestamp:firebase.database.ServerValue.TIMESTAMP
  };

  // Get a key for a new Post.
  var newPostKey = firebase.database().ref().child('posts').push().key;

  // Write the new post's data simultaneously in the posts list and the user's post list.
  var updates = {};
  updates['/users/' + uid + '/lastpost_timestamp'] = firebase.database.ServerValue.TIMESTAMP;
  updates['/posts/' + newPostKey] = postData;
  updates['/user-posts/' + uid + '/' + newPostKey] = postData;

  return firebase.database().ref().update(updates);
}

这是正常工作,直到我在database.json中映射依赖关系以确保

  • /users/$uid/lastposttime_timestamp应为now
  • /posts/$post/timestamp应与lastposttime_timestamp
  • 相匹配
  • /users-posts/$uid/$post中,/posts中的$ post应该在链接到/user-posts/
  • 之前存在

数据库安全规则片段:

"users":{
  "$user":{
    "lastpost_timestamp":{
      ".write":"auth.uid == $user && newData.exists()"
        ".validate":"newData.val() == now && ((data.exists() && data.val() + 60000 < newData.val() )|| !data.exists())"
    }
  }
},
"posts":{
    "$post":{
      "timestamp":{
        ".validate":"newData.val() == now && newData.val() == root.child('users').child(auth.uid).child('lastpost_timestamp').val()"
      }
    }
},
"user-posts":{
  "$uid":{
    "$post":{
      ".write":"auth.uid == $uid && newData.exists()"
      ".validate":"root.child('posts').child($post).exists()"
    }
  }
}

由于这些更新一起发生,验证规则失败,因为我使用root root.child('posts').child($post).exists()引用来验证引用节点是同一更新的一部分,导致它失败。如果没有这些root引用,我可以一起更新节点。

我可以单独运行这些,但是当使用promises链接更新并在下一个.then添加每个相关更新时,更新的原子优势会消失。这也意味着时间戳不匹配,我将不得不检查每个回滚操作。

任何想法,如果我做错了或不支持。

0 个答案:

没有答案