Android Firebase获取集合文档ID时触发索引越界异常如何解决
问题成因
- 核心问题是代码执行顺序写错了:你把ID赋值、RecyclerView适配器初始化的逻辑全放在了遍历单条文档的
for (userDocuments2 in userDocuments)循环内部。 - 当集合里有2条文档时,第一次循环刚执行完
users.add(userObject),此时users列表长度只有1,你紧接着写的内层循环for (i in 0 until userDocuments.size())会遍历0、1两个索引,访问users[1]时列表长度不足,直接抛出IndexOutOfBoundsException。 - 由于你用
try-catch把异常捕获后仅打印日志,没有中断后续流程,第二条文档还是会正常被加入users列表,后续循环中创建的适配器最终能拿到2条完整数据,所以才会出现「报越界错误但RecyclerView最终能显示2条数据」的矛盾现象。 - 就算没有触发越界,你的ID赋值逻辑本身也是错的:内层循环会把列表里所有User对象的userId都赋值为当前遍历到的单条文档ID,最终所有条目的userId都会是最后一条文档的ID,完全达不到给每个用户匹配对应文档ID的目的。
- 额外问题:每遍历一条文档就重复创建适配器、重复设置LayoutManager,属于无意义的性能损耗。
修复方案
调整代码执行顺序,遵循两个原则:
- 解析单条文档时,直接给当前解析出的User对象赋值对应文档ID,不需要额外循环列表
- 等所有文档全部解析完成、
users列表填充完毕后,再一次性初始化适配器、绑定RecyclerView
修复后的完整代码如下:
private fun queryCollection() { val users = arrayListOf<User2>() db.collection(USER2_COLLECTION_NAME).get() .addOnCompleteListener { task -> if (task.isSuccessful) { val userDocuments = task.result ?: return@addOnCompleteListener // 第一步:遍历所有文档,完成解析和ID赋值 for (document in userDocuments) { try { val userObject = document.toObject<User2>() // 直接给当前对象赋值当前文档的ID即可 userObject.userId = document.id users.add(userObject) } catch (e: Exception) { Log.e("a7a error", "文档解析失败: $e") } } // 第二步:所有数据处理完成后,统一绑定RecyclerView val adapter = AdapterClass2(users) binding?.rvUsers2?.layoutManager = LinearLayoutManager(this) binding?.rvUsers2?.adapter = adapter binding?.rvUsers2?.visibility = View.VISIBLE } else { Log.e("a7a error", "查询失败: ${task.exception?.message}") } } }
内容的提问来源于stack exchange,提问作者user18145931
相关产品推荐
相关产品推荐

