Flutter应用从Firestore流式拉取列表时触发where方法空调用报错
错误根因定位
报错信息明确:调用where方法时的操作对象是null,对应你代码中的触发点是todos这个getter的实现逻辑——读取_todos时它的值是null,不是你初始赋值的空列表。
常见触发场景
- 成员变量初始化时序错位:在State类里写了
List<ToDo> _todos = [];的定义,但如果组件首次build流程里,在State成员变量完成初始化前,就提前读取了todosgetter(比如父组件传参、StreamBuilder初始渲染、build前置逻辑触发),此时_todos会以未初始化的null状态被读取 - 流赋值逻辑存在空值覆盖风险:监听
readToDo()返回的Firestore流时,如果不对返回值做非空校验,直接把拿到的内容赋值给_todos,当流发出null值、查询触发错误事件时,原本初始化为空列表的_todos就会被覆盖成null - 空安全配置缺失:项目没开启空安全的情况下,类成员变量的默认值是null,如果存在未预期的代码分支修改了
_todos的值,就会直接触发空对象调用方法的报错
修复方案
- 给getter加空值兜底,从根源上避免对null对象调用
where方法:
List<ToDo> get todos => (_todos ?? []).where((todo) => todo.isDone == false).toList();
- 调整Firestore流的监听逻辑,加非空校验和异常捕获,避免空值覆盖列表状态:
readToDo().listen( (todoList) { setState(() { _todos = todoList ?? []; }); }, onError: (err) { // 查询报错时保持列表为空,不把列表置为null setState(() { _todos = []; }); } );
- 核对Firestore索引配置:
orderBy(ToDoField.createdTime)的排序查询需要对应集合的索引支持,未配置索引时流会抛出查询错误,错误处理逻辑缺失时会间接导致列表状态异常 - 把
_todos的初始化逻辑放到initState生命周期里,确保首次build前列表已经完成初始化:
@override void initState() { super.initState(); _todos = []; }
内容的提问来源于stack exchange,提问作者Kekeli.dev
相关产品推荐
相关产品推荐

