You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中如何从Firestore获取与成就LiveData的所有者列表匹配的用户列表LiveData?

Android中如何从Firestore获取与成就LiveData的所有者列表匹配的用户列表LiveData?

看起来你已经搭好了成就数据的LiveData监听框架,接下来要实现的就是当成就的所有者列表更新时,自动同步获取对应的用户列表,这个需求可以通过MediatorLiveData结合Firestore的批量查询来实现,我给你一步步拆解解决方案:

1. 扩展ViewModel的LiveData定义

首先在你的AchievementDetailsViewModel里,新增一个用来持有用户列表的MediatorLiveData,它会依赖成就的LiveData变化:

class AchievementDetailsViewModel(private val achievementId: String) : ViewModel() {
    private val _achievement: MediatorLiveData<Achievement> = MediatorLiveData()
    public val achievement: LiveData<Achievement> get() = _achievement

    // 新增:持有所有者用户列表的LiveData
    private val _owners: MediatorLiveData<List<User>> = MediatorLiveData()
    public val owners: LiveData<List<User>> get() = _owners

    init {
        fetchAchievementData()
    }

    // ... 原有代码
}

2. 监听成就变化,触发用户列表获取

在你获取成就LiveData的逻辑里,添加一个监听:当成就数据更新时,立刻根据它的owners列表去获取对应的用户数据。修改fetchAchievementData方法:

private fun fetchAchievementData() {
    viewModelScope.launch {
        val achievementLiveData = AchievementService.getAchievement(achievementId)
        _achievement.addSource(achievementLiveData) { achievement ->
            achievement?.let {
                // 成就更新时,同步获取所有者用户
                fetchOwners(it.owners)
            }
        }
    }
}

3. 实现批量获取用户的逻辑

接下来写fetchOwners方法,这里要注意Firestore的whereIn查询最多支持10个参数,所以如果所有者数量超过10,我们需要分批查询。另外用协程的await()来简化异步操作:

import com.google.firebase.firestore.FieldPath
import kotlinx.coroutines.tasks.await

private fun fetchOwners(ownerIds: List<String>) {
    viewModelScope.launch {
        if (ownerIds.isEmpty()) {
            _owners.postValue(emptyList())
            return@launch
        }

        // 把ID列表分成每10个一组,适配Firestore的限制
        val idBatches = ownerIds.chunked(10)
        val users = mutableListOf<User>()

        idBatches.forEach { batch ->
            val querySnapshot = FirebaseFirestore.getInstance()
                .collection("users")
                // 通过文档ID批量查询
                .whereIn(FieldPath.documentId(), batch)
                .get()
                .await()

            // 把查询结果转换成User对象并收集
            querySnapshot.documents.forEach { doc ->
                doc.toObject(User::class.java)?.let { users.add(it) }
            }
        }

        // 更新LiveData,通知UI层
        _owners.postValue(users)
    }
}

4. 额外注意事项

  • 确保你的User数据类已经正确配置了Firestore的序列化规则(比如字段名和Firestore文档键名一致,或者用@PropertyName注解映射)。
  • 如果某个所有者ID对应的用户文档不存在,这段代码会自动跳过该条目,你可以根据需求添加日志提示或者错误处理逻辑。
  • 因为用了viewModelScope,当ViewModel销毁时,协程会自动取消,避免内存泄漏。

这样一来,当你的achievement LiveData更新时,owners LiveData会自动同步更新对应的用户列表,完美适配你的需求~

备注:内容来源于stack exchange,提问作者matetamasi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 10:04:30