Проверка обновлений Firebase для нескольких мест
Мне трудно понять, как проверить обновление нескольких местоположений, где обновления зависят друг от друга.
Рассмотрим следующую структуру:
"votes": {
"$post_id": {
"$answer_id": {
"$user_id": {
".write": "...",
".validate": "..."
}
}
}
}
"users": {
"$user_id": {
"votes": {
"up": {
".write": "...",
".validate": "..."
},
"down": {
".write": "...",
".validate": "..."
}
}
}
}
Пользователи могут голосовать за ответы постов -1 / +1 (или удалять свои голоса, так же как и ноль). Пока все хорошо, я могу подтвердить, что нет проблем. Моя проблема возникает, когда я хочу также проверить счетчик голосов пользователей.
Пример сценария: пользователь A голосует за ответ +1, что также увеличивает число пользователей B up
счетчик с 1. Как я могу проверить up
поле, так что оно будет увеличено (или уменьшено) только тогда, когда за него будет фактически новый голос.
Также есть сценарии, например, когда пользователь уже проголосовал +1, а затем меняет его прямо на -1. Мне очень трудно проверять такие обновления.
Стоит ли просто добавить слой сервера и делать все обновления через сервер? Или мой подход здесь совершенно неправильный (или структура данных?). Добавление серверного уровня в значительной степени решило бы каждую проблему проверки, но также добавило бы еще одну точку отказа, поэтому я пытаюсь избежать этого.
Редактировать:
Функция обновления
function vote(postID: string, answerID: string, author: string, oldVal: number, newVal: number): firebase.Promise<void> {
let voteValue: number = newVal == 0 ? null : newVal; // -1, 0, 1, could be changed to boolean
return this.ref.child(`users/${author}/votes`).once('value', count => {
let updates = {};
updates[`votes/${postID}/${answerID}/${this.authService.current.$key}`] = voteValue;
if (voteValue == 1) {
updates[`users/${author}/votes/up`] = ++count.val().up;
if (oldVal == -1) {
updates[`users/${author}/votes/down`] = --count.val().down;
}
}
if (voteValue == -1) {
updates[`users/${author}/votes/down`] = ++count.val().down;
if (oldVal == 1) {
updates[`users/${author}/votes/up`] = --count.val().up;
}
}
if (voteValue == null && oldVal == -1) {
updates[`users/${author}/votes/down`] = --count.val().down;
}
if (voteValue == null && oldVal == 1) {
updates[`users/${author}/votes/up`] = --count.val().up;
}
this.ref.update(updates);
});
}
Когда текущие голоса автора ответа равны 0/0, а другой пользователь проголосует против одного из его ответов, он создает обновление, например:
"votes/-KM0CMCIQuBsGWQAjhRQ/-KM0CVmhK_7JQcxtdixl/fxpxj1Ky4yVpEeeB5PZviMjqNZv1": 1
"users/spAnCEKTTjX1GgdybQZIlXRI9IG2/votes/up": 1