Я пытаюсь создать игру с базой данных Firestore, и чтобы избежать мошенничества на стороне клиента, я хочу обрабатывать большинство действий внутри облачных функций.
Моя текущая структура Firestore выглядит следующим образом:
matches: {
matchID1: {
//fields
matchname: "Test match",
timestamp: 12/6/2018 16:41:05 PM,
players: [playerID123, playerID345, playerID678],
//subcollections
attackPool: {
attackID123: {
playerID123: "punch"
}
attackID345: {
playerID123: "kick"
},
attackID678: {
playerID123: "headbutt"
}
}
}
}
Документы на совпадения должны быть доступны для чтения клиенту, но attackPool должен быть доступен для записи только клиенту.
Я структурировал данные таким образом, чтобы пользователь мог получить все совпадения, которые онучаствуют по телефону:db.collection("matches").where("players", "array-contains", currentUserID)
но это не выявит каких-либо атак, которые были сделаны, так как они находятся во вложенной коллекции, ходы других игроков должны храниться в секрете.После того, как все игроки атаковали, матч заканчивается.
Моя идея состояла в том, чтобы затем создать облачную функцию, чтобы наблюдать, когда запись записывается в attackPool, после чего она будет захватывать все атаки в attackPool и достигать дородительский матч и захватить всех игроков.Затем функция проверяет, есть ли у каждого игрока в массиве игроков запись в attackPool, в этом случае она определяет, что матч завершен, определяет победителя и распределяет награды и баллы.
Пока чтовот что у меня есть в терминах моей облачной функции:
exports.watchMatchAndAttackUpdates = functions.firestore
.document("matches/{matchId}/attackPool/{attackId}")
.onWrite((change, context) => {
//Get all attacks in attack pool
change.after.ref.parent.get().then(function(querySnapshot) {
const attackers = [];
querySnapshot.forEach(function(doc) {
attackers.push(doc.data())
});
//Get match data
change.after.ref.parent.parent.get().then(res => {
const matchData = res.data();
const players = matchData.players;
//Compare arrays to check that all players moved
//If so, complete match, divvy rewards
});
});
});
Однако я остановился на этом, потому что все это кажется действительно неправильным.Вложенный attackPool для скрытия коллекции от запросов get () кажется нормальным, но теперь мои облачные функции имеют несколько вызовов БД и сравнивают элементы между несколькими уровнями / коллекциями.Должен быть лучший способ.
Итак, мой вопрос: как правильно структурировать эти коллекции?Если это лучший способ, как лучше проверить, что все игроки совершили атаку?