У нас есть приложение, которое использует содержимое в кодировке 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/.