Firebase,多位置更新

时间:2016-03-01 10:43:00

标签: firebase atomic firebase-security

在FireBase中考虑以下多个位置的原子写入代码:

var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");

var newPostRef = ref.child("posts").push();
var newPostKey = newPostRef.key();

var updatedUserData = {};
updatedUserData["users/"+authData.uid+"/posts/" + newPostKey] = true;
updatedUserData["posts/" + newPostKey] = {
  title: "New Post",
  content: "Here is my new post!"
};

ref.update(updatedUserData, function(error) {
  if (error) {
    console.log("Error updating data:", error);
  }
});

此方法可用于更新不同位置的帖子,但如何在服务器端强制执行原子更新? (通过规则)。

如何在不填充/posts/的情况下确保用户无法更新位置users/UID/posts/(通过其直接参考),反之亦然?

1 个答案:

答案 0 :(得分:3)

有很多可能的“业务规则”,所以我会选择一个并实现它。假设用户引用的任何帖子都必须存在。因此,如果/users/myuid/posts/mypostid存在,您只能写信至/posts/mypostid。我还将自己实现帖子的基本验证。

{
  "posts": {
    "$postid": {
      ".validate": "hasChildren(['title', 'content'])",
      "title": {
        ".validate": "newData.isString()"
      },
      "content": {
        ".validate": "newData.isString()"
      },
      "$other": {
        ".validate": false
      }
    }
  },
  "users": {
    "$uid": {
      "posts": {
        "$postid": {
          ".validate": "newData.parent().parent().parent().parent().child('posts').child($postid).exists()
        }
      }
    }
  }
}

这里最大的诀窍是newData.parent().parent()...位,这可以确保我们获得新数据中的帖子。

你习惯于问“我怎样才能确保使用方法ABC来更新数据?”,这很少是思考问题的正确方法。在上面的规则中,我专注于验证数据的结构,并且实际上并不关心API调用可能导致哪些数据。