Добавляя контекст из нашего вчерашнего разговора, вы сказали:
Мы создали приложение для викторины, в котором могут играть даже тысячи людей.
в режиме реального времени, и поэтому все должны видеть одно и то же значение в обратном отсчете
таймер. Наша логика работает довольно хорошо, за исключением того факта, что
редко я получаю странные значения смещения.
Насколько это возможно, вы не хотите зависеть от часов клиента. Уже существует некоторая разница, неизбежная в зависимости от качества сети людей и расстояния от сервера, так что, как вы видели, добавление ненадежных локальных часов может усугубить это. Сроки для онлайн-игр - задача не из легких, и я не буду претендовать на лучшее решение, но вот совет:
Иметь источник правды, скорее всего, сервер, который отслеживает оставшееся время в игре и обновляет его в базе данных. Вы можете использовать Firebase Admin SDK для доступа к базе данных с вашего сервера, что может быть тем, как вы уже вводите отметку времени прямо сейчас.
Запись в базу данных из Admin SDK будет выглядеть примерно так:
admin.database().ref(".info/timeRemaining").set({
time_remaining: time_remaining
});
Где time_remaining
будет временем, которое вы будете обновлять каждую секунду.
Тогда на клиенте вместо отслеживания смещения остается только оставшееся время.
var offsetRef = firebase.database().ref(".info/timeRemaining");
offsetRef.on("value", function(snap) {
var offset = snap.val();
// do what you will
});
Тогда у вас могут быть правила на клиенте, которые заканчивают игру на 0. Конечно, разработчики могли бы найти способы обойти это, поэтому, если это возможно, было бы лучше включить строгую проверку. Если клиенты также пишут в базу данных, но вы не хотите, чтобы они могли это делать после того, как истек срок, одним из вариантов является использование правил. Теперь ваши правила будут выглядеть по-разному в зависимости от вашей структуры данных. Я просто размышляю о применении записей к любому ребенку с ".info"
, что, вероятно, не совсем то, что вам нужно.
{
"rules": {
".info": {
"$info": {
".read": "auth != null",
// writes can only happen before the timer reaches 0
".write": "data.parent().child('time_remaining').val() > 0"
}
}
}
}
Это правило позволяет пользователям записывать в это местоположение только тогда, когда значение time_remaining
больше 0. Если они попытаются выполнить запись после этого, будет возвращена ошибка, и вы можете обработать ее отображение на клиенте.