【问题标题】:Get all from a Firestore collection in Flutter从 Flutter 中的 Firestore 集合中获取所有内容
【发布时间】:2018-03-18 14:13:10
【问题描述】:

我在我的项目中设置了 Firestore。我创建了名为 categories 的新集合。在这个集合中,我创建了三个具有唯一 ID 的文档。现在我想在我的 Flutter 应用程序中获取这个集合,所以我创建了CollectionReference

Firestore.instance.collection('categories')

但我不知道接下来会发生什么。

我正在使用这个插件firebase_firestore: 0.0.1+1

【问题讨论】:

  • 你想做什么?阅读收藏?添加新文档?
  • 我要阅读收藏。
  • 你可以使用StreamBuilder
  • 你能告诉我怎么做吗?代码示例会很有用。

标签: firebase dart flutter google-cloud-firestore


【解决方案1】:

使用StreamBuilder

import 'package:flutter/material.dart';
import 'package:firebase_firestore/firebase_firestore.dart';

class ExpenseList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new StreamBuilder<QuerySnapshot>(
        stream: Firestore.instance.collection("expenses").snapshots,
        builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
          if (!snapshot.hasData) return new Text("There is no expense");
          return new ListView(children: getExpenseItems(snapshot));
        });
  }

  getExpenseItems(AsyncSnapshot<QuerySnapshot> snapshot) {
    return snapshot.data.documents
        .map((doc) => new ListTile(title: new Text(doc["name"]), subtitle: new Text(doc["amount"].toString())))
        .toList();
  }
}

【讨论】:

  • 是的。我在插件文档中看到了这个例子。就我而言,我想将整个集合加载到 Dart 数组而不创建小部件。有可能吗?
  • 这个我试过了,听值Firestore.instance.collection("expenses").snapshots.listen((snapshot) { snapshot.documents.forEach((doc) =&gt; debugPrint(doc.data.toString())); });
  • 它是如何工作的。块中的代码将指示每次集合更改?我应该停止听吗?这个日期可以读一次吗?
  • 是的。似乎没有订阅者时侦听器会自动删除。不幸的是,它的原生 api 插件上没有 single value listener
  • 您应该能够在snapshots.firstawait 获得一个QuerySnapshot
【解决方案2】:

这里是代码,如果你只想读一次

   QuerySnapshot querySnapshot = await Firestore.instance.collection("collection").getDocuments();
    var list = querySnapshot.documents;

【讨论】:

  • 如果要在文档下加载列表怎么办?
  • getDocuments() 现已弃用。
【解决方案3】:

我想出了一个解决方案:

Future getDocs() async {
  QuerySnapshot querySnapshot = await Firestore.instance.collection("collection").getDocuments();
  for (int i = 0; i < querySnapshot.documents.length; i++) {
    var a = querySnapshot.documents[i];
    print(a.documentID);
  }
}

调用getDocs()函数,我使用了build函数,它在控制台打印了所有的文档ID。

【讨论】:

    【解决方案4】:
    QuerySnapshot snap = await 
        Firestore.instance.collection('collection').getDocuments();
    
    snap.documents.forEach((document) {
        print(document.documentID);
      });
    

    【讨论】:

    • 欢迎来到 SO!请不要发布“仅代码”答案。添加一些解释这是如何解决问题的。
    • getDocuments() 不再可用
    【解决方案5】:

    这是从我发现有效的集合中获取所有数据的最简单方法,无需使用已弃用的方法。

    CollectionReference _collectionRef =
        FirebaseFirestore.instance.collection('collection');
    
    Future<void> getData() async {
        // Get docs from collection reference
        QuerySnapshot querySnapshot = await _collectionRef.get();
    
        // Get data from docs and convert map to List
        final allData = querySnapshot.docs.map((doc) => doc.data()).toList();
    
        print(allData);
    }
    

    【讨论】:

    • 截至 2021 年,这是可行的解决方案。
    • 终于!每个答案都有不推荐使用的方法,但这很有效,谢谢。
    • 我认为这里的问题是我们在这里是命令式而不是声明式地思考。当两端发生变化时,我们希望反映这一点,对吗?这就是构成“实时数据库”的原因。使用此实现,我们有效地消除了来回传输更改的能力。这不再是声明性的!
    • 我同意你的看法。有诸如流构建器、mobx 或其他反应性库之类的解决方案来保持您的数据库实时。但是,对于不需要实时更新功能的人来说,这个解决方案就可以了。
    【解决方案6】:

    对我来说,它适用于 cloud_firestore 版本 ^2.1.0

    这是以 JSON 形式显示每个集合的简单代码。我希望这会对某人有所帮助

    FirebaseFirestore.instance.collection("categories").get().then(
      (value) {
        value.docs.forEach(
          (element) {
            print(element.data());
          },
        );
      },
    );
    

    【讨论】:

      【解决方案7】:

      更新:

      • 一次性读取所有数据:

        var collection = FirebaseFirestore.instance.collection('users');
        var querySnapshot = await collection.get();
        for (var doc in querySnapshot.docs) {
          Map<String, dynamic> data = doc.data();
          var fooValue = data['foo']; // <-- Retrieving the value.
        }
        
      • 监听所有数据:

        var collection = FirebaseFirestore.instance.collection('users');
        collection.snapshots().listen((querySnapshot) {
          for (var doc in querySnapshot.docs) {
            Map<String, dynamic> data = doc.data();
            var fooValue = data['foo']; // <-- Retrieving the value.
          }
        });
        

      【讨论】:

        【解决方案8】:

        截至 2021 年,cloud_firestore 软件包发生了一些重大变化。我在一个项目中使用 firestore,发现由于 API 更改,所有旧教程都无法正常工作。

        在查看文档和 Stack 上的其他一些答案后,以下是相同的解决方案。

        您需要做的第一件事是为您的收藏创建一个参考。

        CollectionReference _cat = FirebaseFirestore.instance.collection("categories");
        

        下一步是查询集合。为此,我们将在集合引用对象上使用get 方法。

        QuerySnapshot querySnapshot = await _cat.get()
        

        最后,我们需要解析查询快照以从集合中的每个文档中读取数据。在这里,我们将每个文档解析为地图(字典)并将它们推送到列表中。

        final _docData = querySnapshot.docs.map((doc) => doc.data()).toList();
        

        整个函数看起来像这样:

        getDocumentData () async {
            CollectionReference _cat = FirebaseFirestore.instance.collection("categories");
            final _docData = querySnapshot.docs.map((doc) => doc.data()).toList();
            // do any further processing as you want
        }
        
        

        【讨论】:

          【解决方案9】:

          如果您将数据存储在文档 ID 中会怎样? 如果文档为空,则无法获取 id 文档,这是一个错误,除非您在特定文档中设置字段

          enter image description here

          import 'package:flutter/material.dart';
          import 'package:cloud_firestore/cloud_firestore.dart';
          
          final database1 = FirebaseFirestore.instance;
          Future<QuerySnapshot> years = database1
            .collection('years')
            .get();
          
          class ReadDataFromFirestore extends StatelessWidget {
          
            @override
            Widget build(BuildContext context) {
          
              return FutureBuilder<QuerySnapshot>(
                  future: years,
                  builder: (context, snapshot) {
                    if (snapshot.hasData) {
                      final List<DocumentSnapshot> documents = snapshot.data.docs;
                      return ListView(
                          children: documents
                              .map((doc) => Card(
                                    child: ListTile(
                                  title: Text('doc.id: ${doc.id}'),
                                      //subtitle: Text('category:     ${doc['category']}'),
                                ),
                              ))
                          .toList());
                } else if (snapshot.hasError) {
                  return Text(snapshot.error);
                }
                return CircularProgressIndicator();
              }
              );
            }
          }
          

          【讨论】:

            【解决方案10】:
            final _fireStore = FirebaseFirestore.instance;
            Future<void> getData() async {
                // Get docs from collection reference
                QuerySnapshot querySnapshot = await _fireStore.collection('collectionName').get();
            
                // Get data from docs and convert map to List
                final allData = querySnapshot.docs.map((doc) => doc.data()).toList();
              //for a specific field
              final allData =
                      querySnapshot.docs.map((doc) => doc.get('fieldName')).toList();
            
                print(allData);
            }
            

            【讨论】:

            • 不解释,这个用处不大
            【解决方案11】:

            从 Firestore 中检索数据的最简单方法是:

                void getData() async {
                    await for (var messages in _firestore.collection('collection').snapshots()) 
                    { 
                        for (var message in messages.docs.toList()) {
                            print(message.data()); 
                        }
                    }
                }
            

            【讨论】:

            • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
            • 替换_firestore。使用 FirebaseFirestore.instance。
            猜你喜欢
            • 2021-07-29
            • 1970-01-01
            • 2018-06-23
            • 1970-01-01
            • 2021-08-02
            • 2020-08-08
            • 2021-12-16
            • 2021-03-04
            相关资源
            最近更新 更多