Flutter+Firebase开发遇RangeError(index)报错求助
解决RangeError: Invalid value: Valid value range is empty: 0错误
错误原因
stringList初始为空数组,build方法直接访问stringList[0]时,异步数据还未加载完成,触发索引越界。getIDlist方法未被主动调用,且数据加载完成后未调用setState更新UI。- 循环内重复发起18次Firestore请求,属于无效资源消耗。
修复方案
- 在
initState中调用异步方法,数据加载完成后用setState刷新UI。 - UI层判断数组状态,为空时显示加载占位或无数据提示。
- 将循环内的重复请求改为单次请求,再基于结果处理逻辑。
修改后的代码
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; class Test extends StatefulWidget { const Test({Key? key}) : super(key: key); @override _TestState createState() => _TestState(); } class _TestState extends State<Test> { List<int> intlist = []; List<String> stringList = []; bool isLoading = true; // 加载状态标识 Future getIDlist() async { List<int> list1 = []; List<int> list2 = []; // 改为单次请求Firestore,避免重复调用 var firebaseShop = await FirebaseFirestore.instance .collection('Collection') .doc('Data') .get(); var dataShop = firebaseShop.data(); // 基于单次请求结果处理循环 for (int i = 0; i < 18; i++) { if (dataShop?['x'] == true) { list1.add(i); } else { list2.add(i); } } setState(() { intlist.addAll(list1); intlist.addAll(list2); stringList = intlist.map((int value) => value.toString()).toList(); isLoading = false; // 更新加载状态 }); } @override void initState() { super.initState(); getIDlist(); // 初始化时触发数据加载 } @override Widget build(BuildContext context) { return Scaffold( body: isLoading ? const Center(child: CircularProgressIndicator()) // 加载中显示转圈 : stringList.isNotEmpty ? Text(stringList[0]) // 数据存在时显示内容 : const Center(child: Text('无数据')), // 无数据时显示占位 ); } }
额外说明
isLoading状态让用户感知数据加载过程,避免空UI或错误。- 单次Firestore请求大幅降低网络开销,提升性能。
- 空数组判断彻底避免索引越界问题。
内容的提问来源于stack exchange,提问作者Admin_L
相关产品推荐
相关产品推荐

