我有一个访问数据库(Firebase)并计算文档数量的ViewModel.数据库的 struct 是:集合"Posts"-->文档-->集合"Like"-->文档. 因此,我访问集合"post",然后对于包含我的用户名的每个文档,我访问集合"like"并获取快照大小,以计算有多少个赞.问题是,当创建一个新的Like文档时,在应用程序重新启动之前,ViewModel不会获得更新.

The way I am using the ViewModel:个 我有一个导航图,在那里我创建了一个ViewModel实例,然后我调用检索数据的函数,然后在需要数据的另一个屏幕中将该实例作为参数传递.在另一个屏幕中,我访问存储数据的变量.将数据存储在StateFlow中的变量(因为我在这里传递的是计数器值,而不是文档)

Code (ViewModel):

class PointsViewModel : ViewModel() {
    private val firebase = Firebase.firestore
    private var _points = MutableStateFlow(0)
    val points: StateFlow<Int> = _points

    fun calculate(username: String){
        firebase.collection("Posts")
            .whereEqualTo("PostUser",username)
            .get()
            .addOnSuccessListener { posts ->
                for(post in posts){
                    post.reference.collection("Likes").get().addOnSuccessListener { likes ->
                        _points.value += likes.size()
                    }
                }
            }
    }
}

Code (Where I create instance in NavGraph):

val pointsViewModel: PointsViewModel = viewModel()

//sharedViewModel contains the username
sharedViewModel.user?.username?.let { pointsViewModel.calculate(it) }

Code (Where I need the data):

fun AwardsScreen(sharedViewModel: SharedViewModel,pointsViewModel: PointsViewModel){
    
    val points by pointsViewModel.points.collectAsState()
    

    Column(modifier = Modifier
        .fillMaxWidth()
        .padding(15.dp, 15.dp)) {


        Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
           Text(text = points.toString())
        }
    }

我试着在屏幕内进行所有这些操作,我需要数据.因此,我try 访问数据库并从那里检索所有数据,添加了一个快照侦听器来获取更新,但它不起作用

推荐答案

当涉及到FiRestore中的计数器时,这不是您应该做的.当您像现在这样计算文档时,查询返回的每个文档都要花费一次阅读费用,当点赞数量较多时,这可能会很昂贵.不幸的是,count()不提供实时更新.然而,如果您自己创建和维护一个计数器,它将会更便宜.它可以仅仅是文档中存在的类型编号的字段.这意味着每次将新文档添加到集合中时,您可以简单地对计数器进行increment计数,并在删除文档时将其递减.在本文档中,您可以附加一个实时监听程序,您将拥有一个始终处于最新状态的计数器.这意味着,为了显示点赞的数量,你只需要为一次阅读付费.

此类操作不应在客户端代码中执行,而应在受信任的环境中执行.所以我建议你在Cloud Functions for Firebase中写一个函数,它会自动为你做这件事.

Android相关问答推荐

将动作传递给嵌套的可组合物

为什么R8不混淆某些类?

Jetpack Compose中的导航找不到NavHost类的名称为:startDestination";的参数

Jetapck Compose:将Compose BOM更新为最新版本&2024.01.00&Quot;CircularProgressIndicator后出现错误

无法使用MenuItemColors.Copy()

在以XML格式设置完整屏幕视图时可见App Compat按钮

BroadCastReceiver的onReceive方法中的Intent上的Extras为空

将DiffUtils用于Android上的Recrecerview适配器

未解析的引用:视图模型

尽管我在onCreate()期间已经初始化,但仍出现未初始化的late init变量错误

Android WebView 不会在滚动端加载新内容

我怎样才能在多行 TextView 旁边有一个 ImageView 并且不超过父级的限制?

Android 模拟器 Wifi 连接没有互联网

修复错误 Invariant Violation: requireNativeComponent: "RNSScreenStackHeaderConfig" was not found in the UIManager

Android CompanionDeviceManager 永远找不到任何附近的蓝牙设备

Jetpack Compose 动画性能问题

在compose中,为什么修改List元素的属性,LazyColumn不刷新

ionic - capacitor - Android 风味 - 无法在模拟器或真实设备中运行应用程序

如何在 Jetpack Compose 中为中心对齐设置动画?

compose FontFamily 错误:必须初始化变量