what I want to do is get network data by firebase AddSnapshotListener, store it in room database and get data from room database
so what I done is down here…
// in dataSource
fun getNetworkData(id : String) = callbackFlow<Data> {
....
streamingApi.get{
trySend(it)
}
...
}
//in repository
fun insertData(id : String) = getNetworkData(id).map{
roomDao.insert(it)
}
fun getRoomData() = roomDao.get()
// viewmodel
viewmodelScope.launch{
repository.insertData(id).collect()
repository.getRoomData().onEach{
updateUi()
...
}
}
but is it possible collect at once like this?
fun insertAndGet() = flow{
insertData().collect()
getRoomData().collect()
}
and is it right way collect flow in repository?
2
Answers
You can use merge to combine flows which takes vararg flows as argument.
Here if your
insertData
andgetRoomData
has flow of same type ,insertAndGet()
will also be in same type. If they are different, both will be combined but result from combined flow will be of typeAny
.Usage:
Please refer here.
insertData()
is kind of weird because it returns a Flow of Units. I think it would make more sense to useonEach
instead ofmap
so it at least returns a Flow that you could theoretically do something with other than just pass through data and then drop it.But regardless, the data will be passed out of the
getRoomData()
flow so it doesn’t really matter. If you combine the two, you can just drop the redundant data from theinsertData()
flow.In my opinion, these separate actions should not be combined into a single flow because they have different responsibilities, but I suppose you could do the following. Since the two flows run indefinitely, they must be collected in parallel. This flow just collects the insert flow so it will do its action, but doesn’t pass along the values. It is done in a parallel child coroutine. The Room flow’s data is simply passed out.