Flutter中Firebase数据库无法读取数据的问题求助
Flutter Firestore 读取数据失败问题排查与解决
问题描述
按YouTube博主Johannes Milke的教程实现Flutter+Firestore项目,可正常写入数据,但使用StreamBuilder<List<User>>读取时直接进入错误分支,显示“Something Went Wrong”,无法定位具体问题。
相关代码
main.dart 核心代码
class MainPage extends StatefulWidget { const MainPage({Key? key}) : super(key: key); @override State<MainPage> createState() => _MainPageState(); } class _MainPageState extends State<MainPage> { final controller = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, floatingActionButton: IconButton( icon: Icon(Icons.add), onPressed: (){ Navigator.of(context).push( MaterialPageRoute( builder: (context) => const UserInfo(), ), ); }, color: Colors.blue, ), body: StreamBuilder<List<User>>( stream: readUsers(), builder: (context,snapshot){ if(snapshot.hasError){ return Text('Something Went Wrong',style: TextStyle(color: Colors.white),); } else if(snapshot.hasData){ final users = snapshot.data!; return ListView( children: users.map(buildUser).toList(), ); } else{ return Center(child: CircularProgressIndicator(),); } } ), ); } Widget buildUser(User user)=>ListTile( leading: CircleAvatar(child: Text('${user.age}'),), title: Text(user.name,style: TextStyle(color:Colors.white),), subtitle: Text(user.birthday.toIso8601String()), ); Stream<List<User>> readUsers()=> FirebaseFirestore.instance.collection('users').snapshots().map( (snapshot)=>snapshot.docs.map((doc)=>User.fromJson(doc.data())).toList() ); }
User 模型类代码
import 'package:cloud_firestore/cloud_firestore.dart'; class User{ String id; final String name; final int age; final DateTime birthday; User({ this.id=' ', required this.name, required this.age, required this.birthday }); Map<String,dynamic> toJson()=>{ 'id':id, 'name':name, 'age':age, 'birthday':birthday, }; static User fromJson(Map<String,dynamic>json)=>User( id: json['id'], name: json['name'], age: json['age'], birthday: (json['birthday'] as Timestamp).toDate() ); }
排查与解决步骤
1. 先获取具体错误信息
当前错误分支仅显示通用提示,无法定位问题。修改StreamBuilder的错误处理逻辑,打印并显示详细错误:
if(snapshot.hasError){ // 打印错误到控制台,方便排查 print('Firestore读取错误: ${snapshot.error}'); return Text('读取失败:${snapshot.error}', style: TextStyle(color: Colors.white),); }
2. 修正ID读取逻辑(最可能的问题)
代码从文档数据中读取id字段,但通常Firestore文档ID不会存储在字段里,而是通过doc.id获取。如果写入时未将文档ID存入id字段,读取时json['id']会为null,触发非空类型错误。
方案一:直接从doc.id赋值给User.id
修改readUsers方法:
Stream<List<User>> readUsers() => FirebaseFirestore.instance .collection('users') .snapshots() .map((snapshot) => snapshot.docs .map((doc) => User( id: doc.id, name: doc.data()['name'], age: doc.data()['age'], birthday: (doc.data()['birthday'] as Timestamp).toDate(), )) .toList());
方案二:修改fromJson方法,注入文档ID
保持fromJson不变,转换时将doc.id合并到数据中:
Stream<List<User>> readUsers() => FirebaseFirestore.instance .collection('users') .snapshots() .map((snapshot) => snapshot.docs .map((doc) => User.fromJson({...doc.data(), 'id': doc.id})) .toList());
3. 验证Firestore文档字段类型
确保Firestore中每个用户文档的字段类型与模型匹配:
name:字符串类型age:整数类型(不能是字符串)birthday:Timestamp类型(不能是日期字符串或其他格式)
4. 修正写入逻辑(若需同步ID)
如果需要将文档ID存入字段,修改写入代码,确保新用户的id字段设置为Firestore自动生成的文档ID:
Future<void> addUser(User user) async { final docRef = FirebaseFirestore.instance.collection('users').doc(); final newUser = User( id: docRef.id, name: user.name, age: user.age, birthday: user.birthday, ); await docRef.set(newUser.toJson()); }
内容的提问来源于stack exchange,提问作者Aswin Pratapsingh
相关产品推荐
相关产品推荐

