FireStoreとローカルDBからのデータ取得についてメモ
FireStoreとローカルDBとのデータ取得・同期について、なんとなく動いた()のでメモ。
なお、リモートのデータソースはFireStoreを利用、ローカルはRoomで実装している。
リモートデータソースからの結果待ちの間、ローカルで保持しているデータを表示しておこうというよくあるシチュ。
処理フローはこんな感じ。 常にリモートに同期させるならこれでいいけど、ローカルの更新をリモートに反映させたときの処理がうまくいかない気がする。 全然わからん。
MainActViewModel ↓ UseCase(実装はUseCaseInteractor) ↓ Repository ↓ リモート/ローカルデータソースに並列に問合せ (当然ローカルの方が先に返る) ↓ ローカルデータをいったん返す ↓ リモートデータが取得され次第、コールバックで値を返す
処理の起点となるViewModel。
getFests()
をコールすることでデータ取得を開始する。
class MainActViewModel(val app: Application) : AndroidViewModel(app) { // RecyclerView のリストにバインド private val _festListLiveData = MutableLiveData<List<Fest>>() val festListLiveData: LiveData<List<Fest>> get() = _festListLiveData private val useCase: FestControlUseCase = FestControlInteractor( /*Repositoryを渡す*/ ) fun getFests() { viewModelScope.launch(Dispatchers.IO) { // Coroutineの起動 launch { // リモートデータソースとローカルデータソース両方からデータを取得 val fests = useCase.getFests(object : RemoteDataSourceCallback<Fest> { // リモートデータソースからデータを受信した際のコールバック override fun onResult(contents: List<Fest>) { _festListLiveData.postValue(contents) } }) // 先にローカルデータソースからfestsに値が返るのでpostする _festListLiveData.postValue(fests) } } } }
データソースを集約しているRepository。 非同期処理が必要なのでCoroutineScopeを実装。
// Repositoryパターンを採用してみた class AppRepository( private val firebaseRemoteDataSource: FirebaseRemoteDataSource, private val appLocalDataSource: AppLocalDataSource ) : AppDataSource, CoroutineScope { // FestControlUseCase#getFestsから流れてくる override suspend fun findAllFests(listener: RemoteDataSourceCallback<Fest>): List<Fest> { // Coroutineの起動 launch { // リモートデータソースからのデータ取得。 // 実装で store.collection("fests").get().await() をしているので、 // 基本的に時間がかかる処理。 val remoteFests = firebaseRemoteDataSource.findAllFests(listener) //データが取得できたらローカルを更新 if (!remoteFests.isNullOrEmpty()) { appLocalDataSource.deleteAllFests() appLocalDataSource.insertFests(remoteFests) // リモートのデータをコールバック listener.onResult(remoteFests) } } // リモートデータソースからの取得中にローカルデータソースからデータを返す // ここは上で起動したCoroutineの外 return appLocalDataSource.findAllFests(listener) } }
どう書けばいいのかぜんぜんわからない……。