I have a problem using a suspend function in conjunction with jetpack compose.
I want to get the data of a user and then display it using composer
First of all I have a class to manage the states
sealed class FirebaseResult<T> {
class Success<T>(val data: T) : FirebaseResult<T>()
class Failed<T>(val exception: Exception) : FirebaseResult<T>()
}
the data is obtained with a function
suspend fun getUserdata(user:String): FirebaseResult<List<String>> try={
val snapshot = db.collection(mycollection).document(user).get().await()
val data = snapshot.get("list_data") as List<String>
FirebaseResult.Success(data)
}catch(e: exception){
FirebaseResult.Failed(e)
}
having this I want to get the data and then display it with the help of a Fragment, since compose is used, which passes the data to the main activity
class FragmentList: Fragment(){
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstaceState: Bundle?
); View? {
val view = ComposeView(requireContext())
view.apply{
setContent {
//aqui llamo al archivo y a la funcion para obtener los datos
val user = DataUser.getUserData("jon")// error ya que es una funcion suspend
//mostrar los datos del usuario
Text(text=user)
}
}
the database is as follows
users: {
jon: {
"telefono":"999999999"
"email":"[email protected]"
"list_data":{
"ciudad":"ciudad x"
"cod_postal":"codigo"
"doc_identidad": "documento"
}
}
}
How could I use the function to fetch a user's data and then display it?
In cases like these it is recommended to create models for the objects of your database
Then you convert the result of your queries to instances of those classes
Just as a composable function can only be called from another composable or from a block created with
composeView.setContet
, a suspend function can only be called from another suspend function or from a coroutine.A coroutine is usually created like this
coroutineScope.launch { }
. The functionlaunch
is a coroutine builder , inside that block you can call suspend functions. There are other builders but this one is the most common.You can create the scope manually like this
CoroutineScope(...)
but it's better to use the lifecycle-aware scopes provided by android:lifecycleScope
in an Activity or FragmentviewModelScope
in a ViewModelrememberCoroutineScope()
in a composableIn your case you want to call a suspend function from a composable so you should use
rememberCoroutineScope()
Finally you create a composable function to define how to display the data