In the repository class have this listener:
override fun getState(viewModelScope: CoroutineScope) = callbackFlow {
val listener = FirebaseAuth.AuthStateListener { auth ->
trySend(auth.currentUser == null)
}
auth.addAuthStateListener(listener)
awaitClose {
auth.removeAuthStateListener(listener)
}
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), auth.currentUser == null)
In my ViewModel class I call getState
function that returns a StateFlow<Boolean>
using:
fun getState() = repo.getState(viewModelScope)
And I collect the data:
setContent {
val state = viewModel.getState().collectAsState().value
}
If I change in ViewModel:
fun getState() = viewModelScope.launch {
repo.getState(this)
}
So it can be called from a viewModelScope, I cannot collect the data anymore, as .collectAsState()
appears in red. How to solve this? Any help would be greatly appreciated.
CodePudding user response:
I'm not sure why you're trying to do this:
fun getState() = viewModelScope.launch {
repo.getState(this)
}
This code launches an unnecessary coroutine (doesn't call any suspending or blocking code) that get's a StateFlow reference and promptly releases the reference, and the function itself returns a Job (the launched coroutine). When you launch
a coroutine, the coroutine doesn't produce any returned value. It just returns a Job instance that you can use to wait for it to finish or to cancel it early.
Your repository function already creates a StateFlow that runs in the passed scope, and you're already passing it viewModelScope
, so your StateFlow was already running in the viewModelScope
in your original code fun getState() = repo.getState(viewModelScope)
.
CodePudding user response:
Use live data to send your result of state flow from view model to activity. In your view model do like this:
var isActive = MutableLiveData<Boolean>();
fun getState() {
viewModelScope.launch {
repo.getState(this).onStart {
}
.collect(){
isActive.value = it;
}
}
}
In your activity observer your liveData like this:
viewModel.isActive.observe(this, Observer {
Toast.makeText(applicationContext,it.toString(),Toast.LENGTH_LONG).show()
})
Hopefully it will help.