Open johnGachihi opened 4 years ago
Will check on this and see the best possible way to handle it with your suggestion in mind
We could also use kotlin Flow to first emit the cached data then (in the background) refresh the cached data by fetching and emit the data again if it changes. This way even if the fetch fails the UI will already contain the cached data
// In WifiDetailsRepo
override fun fetchWifiDetails(): Flow<FirebaseResult<WifiDetailsModel>> = flow {
val cachedTravelInfo = runCatching { TravelInfoModelFactory.create(firebaseRemoteConfig) }
emit(cachedTravelInfo)
val refreshedTravelInfo = runCatching {
firebaseRemoteConfig.fetchAndActivate().await()
TravelInfoModelFactory.create(firebaseRemoteConfig)
}
if (cachedTravelInfo != refreshedTravelInfo)
emit(freshTravelInfo)
}
// In the ViewModel
fun getWifiDetails() = viewModelScope.launch(Dispatchers.IO) {
wifiDetailsRepo.fetchWifiDetails().collect { value ->
when (value) {
is FirebaseResult.Success -> wifiDetails.postValue(value.data)
is FirebaseResult.Error -> fetchError.postValue(value.exception)
}
}
}
@johnGachihi Anyway to reproduce the said error?
Disconnect your phone from internet Then open the info page
Okay will test this and get back to you
On this case, am trying to investigate why it's not loading the default values in case of an error at the very least.
RemoteConfig doesn't work sometimes. I have faced this issue before.
Okay we can go with what @johnGachihi is suggesting
Haha. Flow to the rescue once again.
Haha. Flow to the rescue once again. @johnGachihi you can do that pull request.
Here are my thoughts on the implementation on EventTypeViewModel. I think the also
function is not necessary on the wifiDetails
variable.
val wifiDetails: MutableLiveData<FirebaseResult<WifiDetailsModel>> by lazy {
MutableLiveData<FirebaseResult<WifiDetailsModel>>().also {
fetchWifiDetails()
}
}
Or what was your thinking in making it to be this way?
Without it, the method fetchWifiDetails()
would have to be called in EventFragment
(as with fetchSession()
) .
So I saw that it will be called every time EventFragment
is recreated.
Without it, the method
fetchWifiDetails()
would have to be called inEventFragment
(as withfetchSession()
) . So I saw that it will be called every timeEventFragment
is recreated.
Yes am aware of that #73 is aimed at improving that and avoid the methods being called on fragment recreation. Thank you for your clarification!
Sorry, closed it by mistake
I have re-done the TravelFragment Remote config architecture, with what we were following previously with the app and it works without showing the error. Seems the problem is with your implementation bit. Let me do re-write and see if the error persists
@johnGachihi Latest commit fixes the issue
@wangerekaharun, in TravelDetailsRepo
, you left out await()
after fetchAndActivate()
.
It's the one that was causing the issue in my code
I noticed that when a firebase remote config (frc) fetch fails in
WifiDetailsRepoImpl
, instead of falling back to and returning the default or cached frc wifi details, FirebaseResult.error() is returned. This happens because theawait()
ext. function throws an exception whenever the fetch fails. And since it is wrapped inrunCatching
, aFirebaseResult.error()
is returned.Ideally, whenever an frc fetch fails, the frc defaults or cached values should be returned.
My approach to solve this would be to wrap this in a try-catch like so:
so that even when the fetch fails this will be called
WifiDetailsModelFactory.create(firebaseRemoteConfig)
and return the default or cached values