Firebase, обновления для нескольких местоположений

Рассмотрим следующий код для атомарной записи в нескольких местах в 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/ или наоборот?


person towi_parallelism    schedule 01.03.2016    source источник


Ответы (1)


Таких «бизнес-правил» может быть много, поэтому я выберу одно и реализую его. Допустим, любой пост, на который ссылается пользователь, должен существовать. Таким образом, вы можете писать в /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 могут привести к этим данным.

person Frank van Puffelen    schedule 01.03.2016
comment
Спасибо, Фрэнк, я использовал аналогичный подход, но я запутался с использованием newData.val() вместо exists().. кстати, я просто добавил часть источника обновления, чтобы читатели поняли, что я Я ищу решение на стороне сервера, которое гарантирует правильный вывод, независимо от того, что произошло на стороне клиента... но в любом случае спасибо за ответ. Решил мою проблему :) - person towi_parallelism; 01.03.2016
comment
Если у вас уже есть подход, который не работает, всегда публикуйте то, что у вас есть, в своем вопросе. Это показывает, что вы уже что-то пробовали, а также позволяет нам копировать/вставлять фрагменты в наш ответ. - person Frank van Puffelen; 01.03.2016
comment
ссылаясь на этот вопрос, можно ли newData.parent()... использовать несколько раз внутри правила ".validate" определенного узла? - person Andrey; 21.10.2016