Мне очень нравится писать код с Firebase. Это отличный бэкэнд с множеством различных инструментов. Но я упускаю простой способ проверить путь на наличие обновленных данных, когда включено постоянство. Я думаю, что это не редкость, потому что мне часто нужно, чтобы мое приложение действовало определенным образом в зависимости от последних данных сервера, которые нужно прочитать только один раз.
Обычно я использую observeSingleEventOfType
, но это совершенно бесполезно, когда включена перисистенция, поскольку она никогда не будет получать последние данные сервера. Что я не понимаю почему. Должна быть добавлена опция, позволяющая пропускать локальный кеш и искать только данные сервера.
Отключение постоянства решает эту проблему, и observeSingleEventOfType
будет работать должным образом. Но это будет означать, что нужно заново реализовать все офлайн-возможности самостоятельно.
Первый сценарий:
// chats contain meta information about the chat like last message and count of unread messages
let chatRef = ref.child("chats").child(receiverId).child(chatId)
chatRef.observeSingleEventOfType(.Value, withBlock: { (snapshot) -> Void in
if !snapshot.exists() {
print("snapshot does not exist")
// the other side has deleted the chat
// now delete all messages and member objects
ref.child("messages").child(chatId).setValue(nil)
ref.child("members").child(chatId).setValue(nil)
} else {
print("snapshot exists")
}
})
Я также пробовал chatRef.keepSynced(true)
перед тем, как безуспешно наблюдать за событиями. Что в любом случае имеет смысл не во всех ситуациях:
Второй сценарий:
func removeOlderMessages() {
let dateInThePast = NSDate().addDays(-30).timeIntervalSince1970 * 1000
self.messagesRef.queryOrderedByChild("timestamp")
.queryEndingAtValue(dateInThePast)
.observeSingleEventOfType(.Value, withBlock: { (snapshot) -> Void in
snapshot.ref.removeValue()
})
}
Использование здесь keepSynced
приведет к загрузке всех сообщений в messagesRef
, что совершенно не нужно.
Так есть ли разумный обходной путь для этих двух сценариев? Любая помощь приветствуется.
1 ответ
Хорошо, я думаю, что нашел разумное решение для обоих сценариев:
Временное решение для первого сценария:
Используйте transactions
. Они будут работать только тогда, когда вы в сети. Блок completition
вернет последние данные сервера.
self.ref.child("chats").child(receiverId).child(chatId).runTransactionBlock({ (currentData) -> FIRTransactionResult in
// Actually do nothing with the retrieved data and re-submit it.
return FIRTransactionResult.successWithValue(currentData)
}) { (error, success, snapshot) in
if let error = error {
print(error)
return
} else if !success || snapshot == nil {
return
}
// snapshot contains the latest server data
if !snapshot!.exists() {
// the other side has deleted the chat
// now delete all messages and member objects
print("snapshot doesn't exist. deleting messages and members.")
ref.child("messages").child(chatId).setValue(nil)
ref.child("members").child(chatId).setValue(nil)
} else {
print("snapshot exists. not deleting all messages and members.")
}
}
Обратной стороной является то, что получение данных займет значительно больше времени по сравнению с observeEventType
или observeSingleEventOfType
.
Временное решение для второго сценария:
Используйте observeEventType(.Value)
. Сначала он вернет кешированные, а затем последние данные сервера, если они доступны. Наблюдатель может быть удален через заданный интервал времени с помощью NSTimer
.
В общем, эти обходные пути пока подходят, но функция пропуска локального кеша при использовании observeSingleEventOfType
незаменима.
}) { (error, success, snapshot) in
. Другой сценарий: интернет отключается непосредственно перед if !snapshot!.exists()
. Что здесь происходит? ваша функция не будет продолжать оценивать? Значит, ваше приложение останется в несогласованном состоянии, верно? Большое спасибо
Похожие вопросы
Новые вопросы
ios
iOS - мобильная операционная система, работающая на Apple iPhone, iPod touch и iPad. Используйте этот тег [ios] для вопросов, связанных с программированием на платформе iOS. Используйте связанные теги [target-c] и [swift] для проблем, характерных для этих языков программирования.