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

Firestore查询函数提前返回致数组未填充问题排查与解决

Firestore查询返回空数组问题:原因与修复

问题场景

我尝试从Firestore数据库的集合中展示所有文档,编写了如下查询代码,但函数总是在recipes数组填充完成前就返回,导致print(recipes)输出空数组[]:

class DatabaseService {
  static List<Recipe> getSavedRecipes(String uid) {
    List<Recipe> recipes = [];
    FirebaseFirestore.instance
        .collection("users")
        .doc(uid)
        .collection('saved recipes')
        .get()
        .then(
      (querySnapshot) {
        print("Successfully completed");
        for (var docSnapshot in querySnapshot.docs) {
          recipes.add(Recipe.fromFirestore(docSnapshot));
        }
      },
      onError: (e) => print("Error completing: $e"),
    );
    print(recipes);
    return recipes; // 竞态条件:数组还没填充就返回了
  }
}

问题原因

Firestore的get()方法是异步操作,它会立即返回一个Future对象,不会阻塞后续代码执行。原函数是同步函数,then()中的回调逻辑要等Firestore返回数据后才会执行,但此时print(recipes)和return recipes已经执行完毕,所以返回的是空数组,这是典型的异步操作竞态问题。

解决办法

  • 将函数声明为异步函数,添加async关键字
  • 把函数返回类型从List<Recipe>改为Future<List<Recipe>>,因为异步操作的结果是一个Future对象
  • 使用await关键字等待Firestore的get()操作完成,确保数据填充完毕后再返回数组

修复后的代码

class DatabaseService {
  static Future<List<Recipe>> getSavedRecipes(String uid) async {
    late List<Recipe> recipes = [];
    final docs = FirebaseFirestore.instance
        .collection("users")
        .doc(uid)
        .collection('saved recipes')
        .get();

    await docs.then(
      (querySnapshot) {
        print("Successfully completed");
        for (var docSnapshot in querySnapshot.docs) {
          recipes.add(Recipe.fromFirestore(docSnapshot));
        }
      },
      onError: (e) => print("Error completing: $e"),
    );

    return recipes;
  }
}

可选优化(更简洁的写法)

可以去掉then(),直接用await获取查询结果,代码可读性更高:

class DatabaseService {
  static Future<List<Recipe>> getSavedRecipes(String uid) async {
    try {
      final querySnapshot = await FirebaseFirestore.instance
          .collection("users")
          .doc(uid)
          .collection('saved recipes')
          .get();
      print("Successfully completed");
      return querySnapshot.docs
          .map((doc) => Recipe.fromFirestore(doc))
          .toList();
    } catch (e) {
      print("Error completing: $e");
      return [];
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:30:21