使用FutureBuilder读取Firestore文档赋值Artista类时触发空调用&方法报错
问题原因与解决方案
- 判断逻辑顺序错误:你在判断
snapshot.data != null之前就调用了snapshot.data.exists,当snapshot.data为null时,就会触发空调用报错,你看到的&方法调用报错本质就是空指针异常的底层实现表现。 Artista.fromDocumentSnapshot的入参设计不合理:不需要传入整个AsyncSnapshot对象,直接传入DocumentSnapshot即可,避免多层.data调用容易出的空错误。- 缺少空安全适配:从Firestore读取字段时如果字段不存在会返回null,最好给每个字段加默认值避免构造对象时出错。
修复后的代码
1. 修正FutureBuilder的判断逻辑
FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>( future: widget.database.getFutureArtistById(widget.name), builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot<Map<String, dynamic>>> snapshot) { if (snapshot.hasError) { return const Text('Error'); } // 先判断连接状态 if (snapshot.connectionState == ConnectionState.done) { // 先判断snapshot.data是否为null,再判断文档是否存在 if (snapshot.data == null || !snapshot.data!.exists) { return const Text("User does not exist"); } // 此时确认data非空,直接传DocumentSnapshot给工厂方法 Artista artistaTrovato = Artista.fromDocumentSnapshot(snapshot.data!); print(artistaTrovato.toString()); return Artists_Showroom( artistaCorrente: widget.artista, database: widget.database, lista: [artistaTrovato]); } else { // 加载中直接返回进度指示器 return const Center( child: CircularProgressIndicator(), ); } }),
2. 修正Artista的工厂方法
factory Artista.fromDocumentSnapshot( DocumentSnapshot<Map<String, dynamic>> doc) { // 先把文档数据取出来,避免重复调用data() Map<String, dynamic> data = doc.data()!; return Artista( bio: data["bio"] ?? "", regione: data["regione"] ?? "", citta: data["citta"] ?? "", comune: data["comune"] ?? "", foto: data["foto"] ?? "", nome: data["nome"] ?? "", settore: data["settore"] ?? "", lavoro: data["lavoro"] ?? "", progetti: data["progetti"] ?? [], id: data['id'] ?? "", posts: data["posts"] ?? [], ); }
内容的提问来源于stack exchange,提问作者Finley Adams
相关产品推荐
相关产品推荐

