如何将snapshot.data.data()相关代码迁移适配Flutter空安全规范
报错原因
snapshot是FutureBuilder的异步快照对象,空安全规则下它的data属性默认可空;同时Firestore的DocumentSnapshot.data()方法本身也会返回可空的Map,两层可空属性叠加导致直接调用会触发编译报错。
修改方案
这里提供两种合规的空安全适配写法,优先推荐第一种带空校验的安全写法:
写法1:安全空校验(推荐)
先给FutureBuilder指定泛型明确数据类型,再在业务逻辑前逐层做非空判断,避免运行时空异常:
class HomeSlider extends StatefulWidget { final String? doc_id; HomeSlider({this.doc_id}); @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<HomeSlider> { FirebaseServices _firebaseServices = FirebaseServices(); int activeIndex = 1; @override Widget build(BuildContext context) { super.build(context); return Container( child: FutureBuilder<DocumentSnapshot>( // 明确泛型为DocumentSnapshot,确定snapshot.data的类型 future: _firebaseServices.sliderRef .doc(widget.doc_id == null ? "Slider" : widget.doc_id) .get(), builder: (context, snapshot) { if (snapshot.hasError) { return Center( child: Text("Error: ${snapshot.error}"), ); } if (snapshot.connectionState == ConnectionState.done) { // 第一层校验:判断snapshot返回的文档数据不为空 if (snapshot.hasData && snapshot.data != null) { Map<String, dynamic>? documentData = snapshot.data!.data() as Map<String, dynamic>?; // 第二层校验:判断文档解析出的业务数据不为空 if (documentData != null) { List? imageList = documentData['images']; List? suid = documentData['suid']; return SliderBody( imageList: imageList, suid: suid, ); } else { // 文档不存在时的兜底展示 return Center(child: Text("暂无轮播数据")); } } else { return Center(child: Text("暂无数据")); } } return Center( child: CircularProgressIndicator(), ); })); } }
写法2:非空断言简化(仅确认数据必然存在时使用)
如果你能100%确保请求必然返回有效文档,可以用非空断言符!简化代码,注意如果实际返回为空会触发运行时崩溃:
if (snapshot.connectionState == ConnectionState.done) { // 两层非空断言,确认snapshot.data和data()返回值都不为空 Map<String, dynamic> documentData = snapshot.data!.data() as Map<String, dynamic>; List? imageList = documentData['images']; List? suid = documentData['suid']; return SliderBody( imageList: imageList, suid: suid, ); }
内容的提问来源于stack exchange,提问作者FTF Studio
相关产品推荐
相关产品推荐

