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

Flutter中FutureBuilder加载Firestore数据首次不显示问题求助

问题解决:FutureBuilder首次加载Firestore数据不显示

问题根源

你的getPetsBD()方法存在逻辑错误:使用snapshots().listen()订阅实时数据流,但listen是异步非阻塞的,方法会在回调函数处理数据前就返回空的mascotas列表。首次加载时FutureBuilder拿到空数据,页面无法展示;刷新时之前的订阅已经完成数据加载,_pets已有内容,所以能显示。

解决方案

方案1:改为一次性获取数据(适合不需要实时更新的场景)

修改pet_service.dart中的getPetsBD()方法,用get()代替snapshots().listen(),get()会返回Future,等待数据获取完成后再返回结果:

Future<List<Pet>> getPetsBD() async {
  List<Pet> mascotas = [];

  final FirebaseAuth auth = FirebaseAuth.instance;
  final User? user = auth.currentUser;
  final uid = user?.uid;

  try {
    final querySnapshot = await FirebaseFirestore.instance
        .collection('pets')
        .where('owner', isEqualTo: uid)
        .get(); // 改用get()一次性获取数据

    for (var doc in querySnapshot.docs) {
      Map<String, dynamic> data = doc.data();
      Pet newPet = Pet(
          data["id"],
          data["owner"],
          data["birthday"].toString(),
          data["name"],
          data["neutering"],
          data["age"],
          data["breed"],
          data["specie"],
          data["color"],
          data["gender"],
          data["clinic"]);
      mascotas.add(newPet);
    }
    return mascotas;
  } catch (e) {
    print(e); // 打印错误便于调试
    return mascotas;
  }
}

方案2:使用StreamBuilder实现实时数据监听(适合需要实时同步的场景)

如果需要页面实时响应Firestore数据变化,用StreamBuilder代替FutureBuilder,同时修改服务层返回Stream:

  1. 修改pet_service.dart:
Stream<List<Pet>> getPetsStream() {
  final FirebaseAuth auth = FirebaseAuth.instance;
  final User? user = auth.currentUser;
  final uid = user?.uid;

  return FirebaseFirestore.instance
      .collection('pets')
      .where('owner', isEqualTo: uid)
      .snapshots()
      .map((querySnapshot) {
        List<Pet> mascotas = [];
        for (var doc in querySnapshot.docs) {
          Map<String, dynamic> data = doc.data();
          Pet newPet = Pet(
              data["id"],
              data["owner"],
              data["birthday"].toString(),
              data["name"],
              data["neutering"],
              data["age"],
              data["breed"],
              data["specie"],
              data["color"],
              data["gender"],
              data["clinic"]);
          mascotas.add(newPet);
        }
        return mascotas;
      });
}
  1. 修改pet_controller.dart:
Stream<List<Pet>> getPetsStream() {
  return _service.getPetsStream();
}
  1. 修改pet_page.dart中的body部分,替换FutureBuilder为StreamBuilder:
body: StreamBuilder<List<Pet>>(
    stream: petCont.getPetsStream(),
    builder: (BuildContext context, AsyncSnapshot<List<Pet>> snapshot) {
      if (snapshot.hasError) {
        print("error");
        return const Text('Error');
      } else if (snapshot.hasData) {
        List<Pet> species = snapshot.data ?? [];
        print(species);
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: ListView(
            children: [
              for (Pet specie in species)
                Card(
                  // 原有Card内容保持不变
                )
            ],
          ),
        );
      } else {
        // 数据加载中显示加载指示器,提升用户体验
        return const Center(child: CircularProgressIndicator());
      }
    }),

额外优化建议

  • 数据加载状态下显示CircularProgressIndicator,替代"Empty data"文本,更符合用户预期。
  • 删除操作后无需重新路由跳转,依赖Stream自动更新或调用setState()即可刷新页面,避免不必要的页面重建。

内容的提问来源于stack exchange,提问作者Alejandro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 15:40:23