Гарантирует ли Firebase, что набор данных с использованием updateValues ​​или setValue доступен в бэкэнде как одна атомарная единица?

У нас есть приложение, которое использует содержимое в кодировке base64 для передачи вложений на серверную часть. Затем серверная часть перемещает содержимое в хранилище после некоторых манипуляций. Таким образом, мы можем наслаждаться автономной поддержкой и синхронизацией мирового класса и в то же время использовать гораздо более дешевое хранилище для хранения файлов.

Первоначально мы использовали updateChildren для установки содержимого за один раз. Это работает довольно хорошо, но затем пользователи начали загружать все больше и больше файлов одновременно, что привело к молчаливому зависанию базы данных на устройствах конечных пользователей.

Затем мы изменили код, чтобы записывать файлы один за другим, используя FirebaseDatabase.getInstance().getReference("/full/uri").setValue(base64stuff), а затем используя updateChildren, чтобы установить только метаданные.

Это позволяло, казалось бы, бесконечное количество файлов (при условии, что оно было нарезано до максимум 9 мегабайт), но теперь мы столкнулись с другой проблемой.

Наш бэкенд использует прослушиватель Firebase, чтобы начать работу, как только станет доступен новый контент. Триггер ожидает метаданные, а затем начинает обрабатывать вложения. Кажется, что даже несмотря на то, что клиентское устройство записывает файлы до, когда мы устанавливаем метаданные, серверная часть обычно получает метаданные до того, как контент из файлов становится доступным. Это заставило нас изменить внутренний код, чтобы остановить обработку и снова проверить позже, доступны ли данные base64 вложения.

Это работает, но не элегантно, тратит циклы процессора и увеличивает задержки.

Я ничего не нашел в документах, что Firebase гарантирует что-либо о порядке, в котором данные получены серверной частью. Кажется, что все, что написано за один раз (используя setValue или updateChildren), доступно в бэкенде как одна атомарная единица.

Это правильно? Могу ли я полагаться на это как на факт, который не изменится в будущем?

То, как я собираюсь это сделать (если предположения верны выше), состоит в том, чтобы сначала написать метаданные, используя updateChildren в клиенте, как это

"/uri/of/metadata/uid/attachments/attachment_uid1" = "per attachment metadata"
"/uri/of/metadata/uid/attachments/attachment_uid2" = "per attachment metadata"

а затем каждый фрагмент base64 с использованием updateChildren со следующей полезной нагрузкой:

"/uri/of/metadata/uid/uploaded_attachments/attachment_uid2" = true
"/uri/of/base64/content/attachment_uid" = "base64content"

Я не могу использовать setValue для каких-либо данных, чтобы предотвратить случайную перезапись в зависимости от порядка, в котором запись будет происходить в конце.

Это позволило бы мне прослушивать /uri/of/base64/content и пытаться запускать обработку пакета метаданных каждый раз, когда новое вложение завершает загрузку. Единственное, что нужно, чтобы определить, все ли файлы уже были загружены, — это получить метаданные и увидеть, что все идентификаторы вложений, найденные из /attachments/, также присутствуют /uploaded_attachments/.


person anotherdev    schedule 26.05.2017    source источник
comment
firebaser здесь Записи от одного клиента базы данных Firebase доставляются на сервер в том же порядке, в котором они выполняются на клиенте. Они также рассылаются всем прослушивающим клиентам в том же порядке. Кроме того, трудно понять, что происходит. Можно ли как-то решить проблему с помощью MCVE?   -  person Frank van Puffelen    schedule 26.05.2017
comment
Привет! Спасибо за отзыв! Я нашел это: stackoverflow.com/questions/29100656/ Это не проблема, хотя теперь, когда я перепроектировал наш бэкенд (который является одним клиентом Firebase), чтобы справиться с в конечном счете согласованной природой Firebase. Перефразируя вопрос: синхронизирует ли Firebase порядок событий внутри, так что нет возможности, чтобы события, отправленные с одного клиента, наблюдались на другом клиенте в другом порядке, чем записано в (первом)? Ответ на это: такой гарантии нет. Если я правильно понял?   -  person anotherdev    schedule 29.05.2017
comment
Нет, это утверждение, которое вы только что сделали, ложно. Записи от одного клиента выполняются по порядку. Нет никаких шансов, что другой клиент увидит результаты записи B, не увидев результатов записи A (если только A не был отклонен правилами безопасности).   -  person Frank van Puffelen    schedule 29.05.2017
comment
Потрясающий! Таким образом, записи гарантированно всегда будут в порядке. Тогда в этой истории есть нечто большее, чем кажется на первый взгляд, но ваш предыдущий комментарий полностью отвечает на мой вопрос. Если вы достаточно любезны, чтобы скопировать его в качестве ответа, я приму его.   -  person anotherdev    schedule 30.05.2017
comment
Готово. Если у вас все еще есть проблемы, опубликуйте MCVE, чтобы мы могли увидеть, что происходит.   -  person Frank van Puffelen    schedule 30.05.2017


Ответы (1)


Записи от одного клиента базы данных Firebase доставляются на сервер в том же порядке, в котором они выполняются на клиенте. Они также рассылаются всем прослушивающим клиентам в том же порядке.

Нет никаких шансов, что другой клиент увидит результаты записи B, не увидев результатов записи A (если только A не был отклонен правилами безопасности).

person Frank van Puffelen    schedule 30.05.2017