Flutter获取Firestore数据时报The getter 'length' was called on null错
错误原因
报错核心是代码对null对象调用了length属性,触发点是FutureBuilder的builder方法里直接使用了snapshot.data.length。你当前的逻辑只判断了加载状态为waiting的情况,没有覆盖以下异常场景:
- Firestore请求触发异常:比如Firebase安全规则过期拒绝访问、网络异常、传入的集合名称不存在,都会导致
fetchData执行出错,snapshot.data返回null - 请求参数异常:传入的
collection参数为空或者拼写错误,也会导致请求失败返回null
如果此前代码运行正常现在突然报错,90%以上概率是Firebase默认的安全规则过期了——Firestore初始默认规则仅允许创建后30天内的读写请求,过期后会直接拒绝所有访问请求。
修复方案
步骤1:完善fetchData方法的异常捕获
给数据请求逻辑增加异常捕获,请求出错时返回空数组而非null,同时增加泛型约束避免类型歧义:
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/cupertino.dart'; class ManageData extends ChangeNotifier { FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance; Future<List<QueryDocumentSnapshot>> fetchData(String collection) async { try { QuerySnapshot querySnapshot = await firebaseFirestore.collection(collection).get(); return querySnapshot.docs; } catch (e) { debugPrint('获取集合数据出错:$e'); return []; } } }
改完后先去Firebase控制台检查安全规则,调整为符合你业务需要的权限规则,比如测试阶段可以临时设置为允许所有读写(正式上线前务必修改为严格权限)。
步骤2:完善FutureBuilder的判断逻辑
增加错误判断和空数据判断分支,确保只有snapshot.data不为空时才调用length属性:
class MiddleHelpers extends ChangeNotifier { Widget datafav(BuildContext context, String collection) { return Container( height: 280.0, child: FutureBuilder<List<QueryDocumentSnapshot>>( future: Provider.of<ManageData>(context, listen: false) .fetchData(collection), builder: (BuildContext context, AsyncSnapshot<List<QueryDocumentSnapshot>> snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center( child: CircularProgressIndicator(), ); } // 处理错误场景 if (snapshot.hasError) { return Center( child: Text('加载失败:${snapshot.error}'), ); } // 处理空数据场景 if (!snapshot.hasData || snapshot.data!.isEmpty) { return const Center( child: Text('暂无相关数据'), ); } // 确认数据非空后再渲染列表 return ListView.builder( scrollDirection: Axis.horizontal, itemCount: snapshot.data!.length, itemBuilder: (BuildContext context, int index) { final document = snapshot.data![index]; return GestureDetector( onTap: () { Navigator.push( context, PageTransition( child: DetailScreen( queryDocumentSnapshot: document), type: PageTransitionType.bottomToTop), ); }, child: Padding( padding: const EdgeInsets.all(8.0), child: Container( decoration: const BoxDecoration( borderRadius: BorderRadius.all( Radius.circular(20.0), ), color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black26, blurRadius: 5, offset: Offset(3, 3), ), ], ), // 此处补充容器内的实际展示内容 ), ), ); }, ); }, ), ); } }
内容的提问来源于stack exchange,提问作者Kavindu Wijesekara
相关产品推荐
相关产品推荐

