Вроде бы простой вопрос, но если я позвоню:

query.observeSingleEvent(of: .value ...

Тогда я всегда получаю данные, которые хранятся локально. Единственный способ обойти это (который я нашел) - настроить наблюдателя, который продолжает наблюдение бесконечно.

Например, скажем, у меня есть приложение, в котором я просматриваю профиль пользователя. Данные этого пользователя сохраняются локально. Я возвращаюсь через десять дней к тому же профилю. Этот пользователь изменил свое имя (или что-то в этом роде). Мне нужно наблюдать только одно событие, но это единственное событие предоставит мне кэшированные данные (которые теперь устарели). Я не хочу настраивать постоянного наблюдателя для каждого профиля пользователя, который я посещаю, потому что это приведет к ненужным обновлениям (скажем, я никогда больше не вернусь к этому профилю).

В любом случае, надеюсь, этот вопрос ясен. Буду признателен за любые идеи.

РЕДАКТИРОВАТЬ:

В качестве обходного пути я решил просто вызвать наблюдение (.value) и дать ему ответить дважды. Первый ответ - из кеша; второй с сервера. Это помогает в тех случаях, когда у вас нет гарантии, что соединение будет сразу после того, как вы сделаете запрос.

1
joelg 30 Июн 2017 в 18:07
Использование observeSingleEvent плохо сочетается с сохранением на диске. Используйте одно или другое, но не оба. См. Мой ответ здесь: stackoverflow.com/questions/34486417/ … Хотя вопрос касался Android, то же самое относится и к iOS SDK.
 – 
Frank van Puffelen
30 Июн 2017 в 20:39
Фрэнк, есть некоторая оплошность в том, что нельзя напрямую запрашивать сервер, даже если он сохраняется. Например, если я получаю push-уведомление, которое хочет рассказать о чем-то на сервере, и я хочу его, как только приложение запускается (после нажатия на push-уведомление), мне нужно дождаться, пока слушатель скажет мне, что есть данные, которые я ищу. Действительно странный способ сделать это. @FrankvanPuffelen
 – 
joelg
2 Авг 2017 в 21:48

2 ответа

Насколько я понимаю, вы хотите получать свежие данные с помощью ObserverSingleEvent. Для этого вы можете прикрепить keepSynced:

    let query = FIRDatabase.database().reference().child("item")

    query.keepSynced(true)

    query.observeSingleEvent(of: .value ... 

РЕДАКТИРОВАТЬ

ObserveSingleEventType с keepSycned не будет работать, если соединение Firebase не может быть установлено вовремя. Это особенно верно во время appLaunch или в appDelegate, где есть задержка в соединении Firebase и вместо этого предоставляется кешированный результат. Иногда это также не сработает, если включено постоянное хранение, а наблюдение за одиночным событием может сначала предоставить кэшированные данные. В подобных ситуациях предпочтительнее использовать Continuos ObserveEventType, если вам абсолютно необходимы свежие данные.

1
gwinyai 7 Авг 2017 в 11:33
На самом деле это не так. Вызов keepSynced не делает ничего, кроме присоединения слушателя к этому запросу, который затем сохраняет последнюю информацию в памяти. Но мне нужна последняя версия «сейчас», то есть, как только вызывается ObserverSingleEvent.
 – 
joelg
2 Авг 2017 в 21:47
KeepSynced не прикрепляет слушателя, как вы подразумеваете, он заставляет запрос к Firebase искать самые свежие данные для загрузки, если и только если он может установить соединение. Так что ваш вопрос кажется неясным. Если вы просмотрите ссылку Фрэнка на его решение в комментариях, она согласуется с моим и объясняет, как изменить наблюдениеSingleEvent для получения последних значений с помощью keepSynced. Если вы нашли решение, не могли бы вы опубликовать его, чтобы прояснить это для других, которые могут просмотреть это и задаться вопросом, почему keepSynced никогда не работал для вас.
 – 
gwinyai
3 Авг 2017 в 20:23
"это согласуется с моим и объясняет, как изменить наблюдениеSingleEvent для получения последних значений с помощью keepSynced". Где именно вы это видите?
 – 
joelg
3 Авг 2017 в 21:40
stackoverflow.com/questions/34486417/… под заголовком «Решение и обходной путь» в последнем абзаце.
 – 
gwinyai
3 Авг 2017 в 23:07
Перефразируя сказанное здесь: «В качестве обходного пути вы также можете вызвать keepSynced (true) в тех местах, где вы используете однозначный прослушиватель событий. Это гарантирует, что данные обновляются всякий раз, когда они меняются, что значительно повышает вероятность того, что ваш прослушиватель однозначных событий увидит текущее значение. " Кажется, это соответствует вашему вопросу, не так ли?
 – 
gwinyai
3 Авг 2017 в 23:11

В моем случае обновление firebase iOS SDK до v5.4.0 с v4.11.0 решило проблему.

0
sagaraya 9 Июл 2018 в 05:51