Как взаимодействуют Firebase сервис и репозиторий и как организовать их интеграцию
Что проверяют
Умеете ли вы встроить Firebase в слоистую архитектуру так, чтобы SDK не расползся по всему приложению. Следом обычно спрашивают, как тестировать такой репозиторий и что происходит без сети.
Как отвечать
Цепочка из рекомендаций Google по архитектуре: UI, ViewModel, репозиторий, источник данных. Firebase живёт только в последнем звене.
- источник данных: тонкая обёртка над SDK, например
FirestoreUserDataSource. Только она знает проFirebaseFirestore,DocumentSnapshotиTask; - репозиторий: интерфейс
UserRepositoryв domain-слое, реализация в data-слое. Переводит DTO из Firestore в доменные модели, объединяет удалённый источник с локальным и решает, откуда брать данные; - асинхронность: разовые операции переводятся в корутины через
await()изkotlinx-coroutines-play-services, подписки черезcallbackFlowсaddSnapshotListenerиawaitClose { registration.remove() }. Наружу репозиторий отдаётFlowиsuspend-функции,LiveDataуместна максимум во ViewModel; - ошибки:
FirebaseFirestoreExceptionпревращается в доменную ошибку илиResult, UI не разбирает коды Firebase; - внедрение:
FirebaseFirestoreиFirebaseAuthотдаёт модуль Hilt, репозиторий получает их в конструктор.
Такое разделение позволяет в тестах ViewModel подставить фейковый репозиторий, а источник данных проверять на Firebase Local Emulator Suite без боевого проекта.
Про офлайн стоит знать: у Cloud Firestore на Android локальный кеш включён по умолчанию, у Realtime Database выключен и включается через setPersistenceEnabled(true).
Где спотыкаются
Вызывают FirebaseFirestore.getInstance() прямо во ViewModel или в активити. Тестировать такой код можно только с живым бэкендом, а смена хранилища означает переписывание экранов.
Забывают снять слушатель. Без remove() в awaitClose подписка переживает экран, продолжает получать обновления и расходует оплачиваемые чтения.
Ждут завершения записи через set(...).await() без сети. Локальные слушатели увидят изменение сразу, а Task завершится только после подтверждения сервером, и корутина повиснет до появления связи.