Flutter使用Dart对接Firestore时出现NoSuchMethodError空调用get报错
这个报错的核心原因是异步查询未完成时就访问了空的calendarLogs变量,同时你的代码还存在状态未同步、查询逻辑缺失、类型不匹配等问题,按以下步骤修复即可:
修复步骤
- 第一步:补全异步回调的状态同步
你在initState的异步回调中修改了calendarLogs和calendarLogFlag后,没有调用setState通知UI刷新,UI会一直使用初始值为null的calendarLogs渲染。修改initState代码:
bool calendarLogFlag = false; var calendarLogs; @override void initState(){ super.initState(); DateTime date1 = DateTime.utc(2021, 10, 27); Timestamp date = Timestamp.fromDate(date1); CalendarLog().getCalendarLog('weightlifting', date).then((QuerySnapshot docs){ if(docs.docs.isNotEmpty){ setState(() { calendarLogFlag = true; calendarLogs = docs.docs[0]; }); } }); }
- 第二步:补全Firestore查询的日期过滤条件
你定义的getCalendarLog方法接收了date参数,但查询语句中没有添加日期过滤逻辑,会返回所有运动类型匹配的文档,无法命中对应日期的目标数据。修改CalendarLog类代码(注意将下方logDate替换为你集合中实际存储日期的字段名):
class CalendarLog { Future<QuerySnapshot> getCalendarLog(String sportName, Timestamp date) { return FirebaseFirestore.instance .collection('users') .where('sport', isEqualTo: sportName) .where('logDate', isEqualTo: date) .get(); } }
- 第三步:UI渲染层添加空判断与类型适配
Text组件仅支持字符串类型参数,你原有代码中?? 0返回的是数字类型会额外触发类型错误,同时要先判断calendarLogs是否为空再调用方法,另外需要确认legPressReps字段名的大小写与Firestore中存储的完全一致,避免字段匹配失败。修改渲染代码:
label: Text(calendarLogs?.get('legPressReps')?.toString() ?? '0'),
可选优化
你可以用FutureBuilder简化异步逻辑,无需手动维护加载状态变量:
@override Widget build(BuildContext context) { DateTime date1 = DateTime.utc(2021, 10, 27); Timestamp date = Timestamp.fromDate(date1); return FutureBuilder<QuerySnapshot>( future: CalendarLog().getCalendarLog('weightlifting', date), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Text('加载中'); } if (snapshot.hasError || !snapshot.hasData || snapshot.data!.docs.isEmpty) { return const Text('0'); } final log = snapshot.data!.docs[0]; return Text(log.get('legPressReps').toString()); }, ); }
内容的提问来源于stack exchange,提问作者kiara
相关产品推荐
相关产品推荐

