Harpreet Singh.8052
02/22/2024, 2:04 PMcoroutine
. I have a method to store image to firebase and return its URL
, it s suspend
function and i am calling that ImageUpload()
method inside my view model
var imageUri = mutableStateOf<String?>(null)
fun uploadImage(uri: Uri) {
viewModelScope.launch {
imageUri.value = saveUserRepositoryImp.saveImageToFirebase(uri)
}
_userDetail = _userDetail?.copy(
profileUri = imageUri.value
)
}
this is function inside my viewmodel
and this function is called inside viewModelScope.launch{ uploadImage(uri) }
i want it to wait for the result because i want show loading and when result is return the loading should be stopstreetsofboston
02/22/2024, 2:22 PMfun uploadImage(uri: URI) {
_uiState.value = UiState.Loading // will show Loading... on your UI
viewModelScope.launch {
_uiState.value.userDetail = _uiState.value.userDetail?.copy(profileUri = saveUserRepositoryImp.saveImageToFirebase(uri));
}
}
streetsofboston
02/22/2024, 2:23 PMviewModel.uiState
,
When it sees a UiState.Loading, then it shows a Loading.... screen/spinner/view
When later the UiState.UserDetail is observed, it shows you the upload-result/user-details.streetsofboston
02/22/2024, 2:27 PMuploadImage
suspending:
In your UI:
...
showLoadingView()
result = uploadImage(imageUri)
showResult(result)
...
In your view model:
suspend fun uploadImage(uri: URI) {
return withContext(Dispatchers.IO) {
saveUserRepositoryImp.saveImageToFirebase(uri));
}
}
(but I suggest using an MVVM pattern where your UI observes Flow(s) from your ViewModel)streetsofboston
02/22/2024, 2:28 PMHarpreet Singh.8052
02/22/2024, 2:29 PMHarpreet Singh.8052
02/22/2024, 2:30 PMstreetsofboston
02/22/2024, 2:33 PM_userDetail
inside the launch
...Harpreet Singh.8052
02/22/2024, 2:34 PMoverride suspend fun saveImageToFirebase(uri : Uri) : String {
var imageUri : String = ""
Log.d("debug", "uploadImage1")
storageReference.child(FirebaseAuth.getInstance().uid!!).putFile(uri)
.addOnSuccessListener {
storageReference.child(FirebaseAuth.getInstance().uid!!).downloadUrl.addOnSuccessListener { uri ->
imageUri = uri.toString()
Log.d("debug", "uploadImage2: ${uri}")
}
}
.addOnFailureListener{
Log.d("debug", "uploadImage3: ${it.message}")
it.printStackTrace()
Log.d("debug", "uploadImage4: ${it.message}")
}
return imageUri
}
the repo
override suspend fun saveImageToFirebase(uri: Uri) : String {
return userDetailService.saveImageToFirebase(uri)
}
viewmodel
fun uploadImage(uri: Uri) {
viewModelScope.launch {
Log.d("debug", "uploadImage: actual 1")
val profileUri = saveUserRepositoryImp.saveImageToFirebase(uri)
Log.d("debug", "uploadImage: actual 2-> ${profileUri}")
}
}
streetsofboston
02/22/2024, 2:35 PMflow.value
inside your viewModelScope.launch with the profileUri resultHarpreet Singh.8052
02/22/2024, 2:36 PMLog.d("debug", "uploadImage: actual 2-> ${profileUri}")
im getting empty string because imreturn empty sting in my actual implemt var imageUri : String = ""streetsofboston
02/22/2024, 2:36 PMfun uploadImage(uri: Uri) {
uiState.value = UiState.Loading
viewModelScope.launch {
Log.d("debug", "uploadImage: actual 1")
val profileUri = saveUserRepositoryImp.saveImageToFirebase(uri)
uiState.value = UserDetails(profileUri)
Log.d("debug", "uploadImage: actual 2-> ${profileUri}")
}
}
^^^ or something similar... the uiState is a Flow<UiState> here, where UiState a sealed class/interface that can have a Loading value or a UserDetails instance.streetsofboston
02/22/2024, 2:37 PMstreetsofboston
02/22/2024, 2:37 PMHarpreet Singh.8052
02/22/2024, 2:38 PMHarpreet Singh.8052
02/22/2024, 2:40 PMstreetsofboston
02/22/2024, 2:40 PMoverride suspend fun saveImageToFirebase(uri : Uri) : String {
return suspendCancellableCoroutine { cont->
storageReference.child(FirebaseAuth.getInstance().uid!!).putFile(uri)
.addOnSuccessListener {
storageReference.child(FirebaseAuth.getInstance().uid!!).downloadUrl.addOnSuccessListener { uri ->
imageUri = uri.toString()
cont.resume(imageUri)
}
}
.addOnFailureListener{
cont.resumeWithException(it)
}
cont.invokeOnCancellation { /* deregister your onSuccess and onFailure listeners here */ }
}
}
streetsofboston
02/22/2024, 2:42 PMHarpreet Singh.8052
02/22/2024, 2:52 PMsuspend
and call it inside a coroutine scope. i need to dive more into it , can u suggest some topics or resources , thanks