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

首次安装或运行时ViewPager首屏Fragment的Firestore QuerySnapshot为空问题

问题根因

你遇到的现象本质是首次启动时查询条件的取值不正确,导致Firestore返回了空的查询结果,因此for循环没有可遍历的元素,和Firestore本身的bug无关,具体触发逻辑如下:

  • ViewPager第一个Fragment的初始化时机早于全局用户配置GlobalConfig.userData的赋值时机,首次启动调用fetchAssignments时,GlobalConfig.userData.shift还是空值/默认值,和你预期的筛选值不符,因此查询不到匹配的文档。
  • 第二次启动时,用户数据已经持久化在本地,应用启动时会提前完成赋值,因此查询条件正确可以拿到结果。
  • 第二个Fragment查询正常、手动重试查询正常,都是因为这些操作触发时,GlobalConfig.userData已经完成了初始化,筛选值正确。

解决步骤

  1. 校验查询条件的取值时机
    在查询逻辑前加日志确认首次启动时的筛选值是否符合预期:
fun fetchAssignments(){
    // 新增日志排查取值是否正确
    Log.d("DEBUG_ASSIGNMENT", "当前筛选shift值:${GlobalConfig.userData.shift}")
    val shift = GlobalConfig.userData.shift
    // 为空直接终止查询,避免无效请求
    if(shift.isNullOrEmpty()) return

    fireStore.collection(appContext.getString(R.string.assignment))
        .whereEqualTo(appContext.getString(R.string.type), shift)
        .orderBy(appContext.getString(R.string.time), Query.Direction.DESCENDING)
        .get()
        .addOnSuccessListener {
            // 新增日志确认返回结果数量
            Log.d("DEBUG_ASSIGNMENT", "查询返回文档数:${it.size()}")
            val assList = mutableListOf<AssignmentData>()
            for (item in it){
                val assignment = item.toObject(AssignmentData::class.java)
                assignment.documentId = item.id
                assList.add(assignment)
            }
            assignmentList.value = assList
        }
        .addOnFailureListener {
            assignmentList.value = listOf()
        }
}
  1. 调整查询触发时机
    不要在Fragment的onViewCreated/onCreate生命周期直接调用fetchAssignments,改为监听全局用户配置的初始化状态,等GlobalConfig.userData赋值完成后再触发查询,你可以通过LiveData、Flow或者自定义回调实现这个监听逻辑。

补充说明

如果排查后确认筛选值没有问题,再检查该查询对应的复合索引是否已经创建完成:whereEqualTo(type) + orderBy(time)的查询需要提前在Firestore控制台创建对应复合索引,索引创建未完成时也可能出现首次查询返回空、后续缓存命中后正常的异常现象。

内容的提问来源于stack exchange,提问作者Bitwise DEVS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 14:15:05