You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 20:40:34