从 Flutter 中的 Firestore 检索数据后的空列表

Posted

技术标签:

【中文标题】从 Flutter 中的 Firestore 检索数据后的空列表【英文标题】:Null List after data retrieval from Firestore in Flutter 【发布时间】:2020-12-10 01:17:16 【问题描述】:

我是 Flutter 的新手,如果这个问题看起来微不足道或无关紧要,我很抱歉!

我创建了另一个用于获取和设置数据的类Repository,因为我使用 Cloud Firestore,我想要针对这个特定问题的数据存储在一个集合中,所以我将集合中的所有文档都作为 @ 987654323@,然后将所有文档添加到List<DocumentSnapshot>

方法如下:

Future<List<DocumentSnapshot>> getCollection(CollectionReference colRef) async 
    List<DocumentSnapshot> dummyList = new List();
    await colRef.getDocuments().then((value) 
      dummyList.addAll(value.documents);
    );
    return dummyList;
  

存储库:

CollectionReference memoriesColRef =
    _firestore
        .collection("username")
        .document("memories")
        .collection("allMem");

    List<DocumentSnapshot> documentList = new List();
    await getCollection(memoriesColRef).then((value) 
      documentList.addAll(value);
    );

毕竟,我在我的 UI 类中设置了一个方法,调用它 Repository,当我在 build 函数中调用它时,它可以完美运行,我已经传递给访问的全局列表数据,无法在其中添加值

UI 类

build(...) 
  getMemories().then((value) 
      print("value size: " + value.length.toString()); // 1
      memoriesListMap.addAll(value); // global variable
    );
  print("valSize: " + memoriesListMap.length.toString()); // 0
  print("val: " + memoriesListMap[0]["title"]); // error line


Future<List<Map<String, dynamic>>> getMemories() async
    List<Map<String, dynamic>> dummyListMap = new List();

    await MemoryOper().getMemories().then((value) 
      print("memVal: " + value[0]["title"]); // appropriate value
      dummyListMap.addAll(value);
    );
    return dummyListMap;
  

错误 RangeError (index): Invalid value: Valid value range is empty: 0\

我不知道是什么原因造成的,但请帮帮我!谢谢

编辑:

ListView.builder(
                itemBuilder: (BuildContext context, int index) 
                  String title = memoriesListMap[index]["title"]; // error prone line
                  int remind = memoriesListMap[index]["remind"];
                  String link = memoriesListMap[index]["link"];

【问题讨论】:

这能回答你的问题吗? What is a Future and how do I use it? 注意“我如何使用它”部分。如果你想构建依赖于 Future 结果的东西,你需要FutureBuilder 作为个人附注,尽量不要混用.then()await。对于 Futures 和 async/await 的新手来说,这可能会非常令人困惑。一旦您了解它们的方式,将两者一起使用并没有错,但对于初学者来说,如果您选择其中一个会更容易。我建议await,这样更难犯这样的错误。 理想情况下,如果我遵循这个答案,我应该能够形成一个解决方案,对吧? 是的,确实如此。无论是假设的披萨外卖还是从 Firestore 加载东西,“我稍后获取数据,我该怎么办?”的概念。总是一样的。 【参考方案1】:

除了 nvoigt 所说的之外,article 将帮助您了解如何实现 Future Builder,在您的具体情况下,您可以执行以下操作:

build(...)
..
body: getMemories(),
..


Widget getMemories() 
  return FutureBuilder(
    builder: (context, projectSnap) 
      if (projectSnap.connectionState == ConnectionState.none &&
          projectSnap.hasData == null) 
        return Container();
      
      return ListView.builder(
        itemCount: projectSnap.data.length,
        itemBuilder: (context, index) 
          ProjectModel project = projectSnap.data[index];
          return Column(
            children: <Widget>[
              // Widget to display the list of project
            ],
          );
        ,
      );
    ,
    future: getCollection(), //this is the important part where you get the data from your Future
  );


【讨论】:

是的,FutureBuilder 有效!我在和 nvoigt 的谈话中提到过。【参考方案2】:

我认为您在添加元素之前正在访问它,因为它是 async 方法。 尝试这样的事情,

build(...) 
  getMemories().then((value) 
      print("value size: " + value.length.toString()); // 1
      memoriesListMap.addAll(value); // global variable
      print("valSize: " + memoriesListMap.length.toString()); // 0
      print("val: " + memoriesListMap[0]["title"]); 
   );

希望它有效!

【讨论】:

是的,这可行,但我必须在 .then() 之外使用该变量,如果需要,我可以将代码发布在我使用它的地方 是的,请张贴。如果你必须使用它,那么你可以等到async函数被执行。 这行不通。如果您需要构建结果,则需要等待结果,而不是使用.then()。由于构建方法不能是异步的,所以你不能。所以你需要另一种方式。这通常使用 FutureBuilder 来处理,请参阅我的重复投票。

以上是关于从 Flutter 中的 Firestore 检索数据后的空列表的主要内容,如果未能解决你的问题,请参考以下文章

Flutter web:从 Firestore 地图检索的值在添加到列表时被截断

Flutter Firestore:从 Firestore 中检索数据并在 Flutter 中显示为小部件

Flutter Firestore 使用异步检索所有文档内容

我无法从 Firestore Flutter 检索和查看数据

Flutter - 如何从 Firestore 中检索 ID 列表并在 GridView 中显示它们的项目?

如何从 Cloud Firestore 中获取数据,其中 user.uid 等于 Flutter 中的文档 ID?