When i click picture it updates in firebase storage, but doesn’t updates in my ui. But if i click this picture again, it will update in the ui.
Code:
var user by remember {
mutableStateOf(
if(signInWithGoogle) {
User(
profilePictureUrl = userData?.profilePictureUrl,
userName = userData?.userName
)
} else {
User(
profilePictureUrl = signInEmailVM.getSignedInUser()?.photoUrl.toString(),
userName = signInEmailVM.getSignedInUser()?.displayName
)
}
)
}
//Photo picker
val singlePhotoPickerLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.PickVisualMedia(),
//Upload image to firebase and change profile picture
onResult = { uri ->
if(uri != null) {
scope.launch {
if(signInEmailVM.updateUserProfile(image = uri, name = "BRBX")) {
Toast.makeText(
context,
"Изменения сохранены",
Toast.LENGTH_SHORT
).show()
user = User(
profilePictureUrl = signInEmailVM.getSignedInUser()?.photoUrl.toString(),
userName = signInEmailVM.getSignedInUser()?.displayName
)
} else {
Toast.makeText(
context,
"Что-то пошло не так",
Toast.LENGTH_SHORT
).show()
}
}
}
}
)
AsyncImage(
model = user.profilePictureUrl,
contentDescription = "Profile picture",
modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.Crop
)
I tried to move the creation of a new instance of the user object, but result was stil the same. I tried to run top part of code, not in a coroutine, didn’t help. I think problem is compose and his recompositions. But if the picture was already updated, next time i click it, it will showed from the first try. If you need, here is code for updating user picture:
suspend fun updateUserProfile(image: Uri, name: String): Boolean {
val storageRef = FirebaseStorage.getInstance().reference.child("Users/${firebaseAuth.currentUser?.uid}/${image.lastPathSegment}")
val upload = storageRef.putFile(image)
val result = CompletableDeferred<Boolean>()
upload.addOnCompleteListener {
result.complete(it.isSuccessful)
}
storageRef.downloadUrl.addOnSuccessListener { uri ->
val profileUpdates = userProfileChangeRequest {
displayName = name
photoUri = Uri.parse(uri.toString())
}
firebaseAuth.currentUser?.updateProfile(profileUpdates)?.addOnCompleteListener {
result.complete(it.isSuccessful)
}
}
return result.await()
}
2
Answers
Finally after three hours i found solution. Problem wasn't in recompositions, it was in logic
This worked for me
It seems like the issue might be related to how the
user
state is updated after selecting a new profile picture. Since you’re updating theuser
state within a coroutine, and the UI might not be recomposed immediately after the state change, Compose might not reflect the changes promptly.To ensure that Compose recomposes immediately after updating the
user
state, you can try using aMutableStateFlow
instead ofmutableStateOf
. MutableStateFlow is a part of Kotlin Flows and is designed to be used in asynchronous scenarios like coroutines.Here’s how you can modify your code to use MutableStateFlow:
This way, Compose will be immediately notified of changes to the user state, ensuring that the UI updates accordingly after selecting a new profile picture.