firebase 使用StateFlows和.collectAsState后,UI不会更新

7qhs6swi  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(169)

预期行为:当按钮被点击时,它应该立即更新文本和颜色以反映新的奖励值。
实际行为:当点击按钮时,它调用函数来更新数据并将其保存到Firestore。但是,UI不会更新,直到重新加载屏幕。
尝试过的事情:我已经从LiveData切换到StateFlow,但这并没有解决问题。

Repository:

var currentUser = MutableStateFlow<User?>(null)
        private set
fun updateCurrentUserFirestore() {
        val updatedUser = hashMapOf(
            "skipCoins" to currentUser.value?.skipCoins,
            "tasksDone" to currentUser.value?.tasksDone,
            "tasksSkipped" to currentUser.value?.tasksSkipped,
            "gamesWon" to currentUser.value?.gamesWon,
            "gamesLost" to currentUser.value?.gamesLost,
            "reward" to currentUser.value?.reward
        )
        firestore.collection("user").document(currentUser.value?.userId.toString())
            .set(updatedUser)
            .addOnSuccessListener {
                Log.d(TAG, "updateCurrentUserFirebase:success")
            }
            .addOnFailureListener {
                Log.w(TAG, "updateCurrentUserFirebase:failure", it)
            }
    }

    fun changeRewardCurrentUser() {
        if (currentUser.value?.reward == "Joke") {
            currentUser.value.let {
                if (it != null) {
                    currentUser.value = User(
                        userId = it.userId,
                        skipCoins = it.skipCoins,
                        tasksDone = it.tasksDone,
                        tasksSkipped = it.tasksSkipped,
                        gamesWon = it.gamesWon,
                        gamesLost = it.gamesLost,
                        reward = if (it.reward == "Joke") "Bored" else "Joke"
                    )
                }
            }
        }
    }
fun updateCurrentUser(uid: String) {
        firestore.collection("user").document(uid)
            .get()
            .addOnSuccessListener { result ->
                currentUser.value = User(
                    userId = result.id,
                    skipCoins = result.data?.get("skipCoins").toString().toLong(),
                    tasksDone = result.data?.get("tasksDone").toString().toLong(),
                    tasksSkipped = result.data?.get("tasksSkipped").toString().toLong(),
                    gamesWon = result.data?.get("gamesWon").toString().toLong(),
                    gamesLost = result.data?.get("gamesLost").toString().toLong(),
                    reward = result.data?.get("reward").toString()
                )
                Log.d(TAG, "updateCurrentUserLocal:success")
            }
            .addOnFailureListener {
                Log.w(TAG, "updateCurrentUserLocal:failure", it)
            }
    }
ViewModel:

val currentUser: StateFlow<User?> = repository.currentUser
fun updateCurrentUserFirestore() {
        repository.updateCurrentUserFirestore()
    }

    fun changeRewardCurrentUser() {
        repository.changeRewardCurrentUser()
    }
Composable:

val user by viewModel.currentUser.collectAsState()
Button(
                        shape = ShapeDefaults.ExtraSmall,
                        onClick = {
                            viewModel.changeRewardCurrentUser()
                            viewModel.updateCurrentUserFirestore()
                        },
                        colors = ButtonDefaults.buttonColors(
                            containerColor = if (user?.reward == "Joke") Purple40 else Orange80,
                            contentColor = if (user?.reward == "Joke") Orange80 else Purple40
                        ),
                        modifier = Modifier.width(
                            calcDp(
                                percentage = 0.25f,
                                dimension = Dimension.Width
                            )
                        )
                    ) {
                        user?.let { Text(text = it.reward) }
                    }
ftf50wuq

ftf50wuq1#

当你调用Query#get()时,你只会阅读一次数据。这意味着在你获得数据后,如果服务器上的某些内容发生了更改,你不会收到有关该更改的通知。你要寻找的是获取real-time updates。这意味着每次服务器上的某些内容发生更改时,你都会收到实时通知。

zkure5ic

zkure5ic2#

我刚刚解决了我的问题,Yay,这里的解决方案:
在graddle实现中添加这个(“androidx.lifecycle:lifecycle-runtime-compose:2.6.2”)
并在Composable中使用. collectAsStateWithData而不是.collectAsState

相关问题