当我单击图片时,它会在 Firebase 存储中更新,但不会在我的用户界面中更新。但如果我再次点击这张图片,它会在用户界面中更新。
代码:
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
)
我尝试移动用户对象的新实例的创建,但结果仍然相同。我尝试运行代码的顶部部分,而不是在协程中,但没有帮助。我认为问题在于写作和他的重新组合。但如果您需要,这里是更新用户图片的代码:
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()
}
问题似乎可能与选择新的个人资料图片后
user
状态如何更新有关。由于您要在协程中更新 user
状态,并且 UI 可能不会在状态更改后立即重新组合,因此 Compose 可能不会立即反映更改。
为了确保 Compose 在更新用户状态后立即重新组合,您可以尝试使用
MutableStateFlow
而不是 mutableStateOf
。 MutableStateFlow 是 Kotlin Flows 的一部分,旨在用于协程等异步场景。
以下是修改代码以使用 MutableStateFlow 的方法:
val userStateFlow = remember { mutableStateOf(
if(signInWithGoogle) {
User(
profilePictureUrl = userData?.profilePictureUrl,
userName = userData?.userName
)
} else {
User(
profilePictureUrl = signInEmailVM.getSignedInUser()?.photoUrl.toString(),
userName = signInEmailVM.getSignedInUser()?.displayName
)
}
) }
var user by userStateFlow
//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
)
这样,Compose 将立即收到用户状态更改的通知,确保用户界面在选择新的个人资料图片后相应更新。