【问题标题】:Query a single document from Firestore in Flutter (cloud_firestore Plugin)Flutter 中从 Firestore 查询单个文档(cloud_firestore 插件)
【发布时间】:2019-04-30 05:44:16
【问题描述】:

编辑:这个问题已经过时了,我敢肯定,新的文档和最新的答案是现在可用的。

我只想通过其 ID 检索单个文档的数据。我使用以下示例数据的方法:

TESTID1 {
     'name': 'example', 
     'data': 'sample data',
}

是这样的:

Firestore.instance.document('TESTID1').get() => then(function(document) {
    print(document('name'));
}

但这似乎不是正确的语法。

我无法在 Flutter (dart) 中找到关于查询 firestore 的任何详细文档,因为 firebase 文档仅涉及 Native WEB、iOS、Android 等,而不涉及 Flutter。 cloud_firestore 的文档也太短了。只有一个示例显示了如何将多个文档查询到一个流中,这不是我想做的。

缺少文档的相关问题: https://github.com/flutter/flutter/issues/14324

从单个文档中获取数据并非难事。

更新:

Firestore.instance.collection('COLLECTION').document('ID')
.get().then((DocumentSnapshot) =>
      print(DocumentSnapshot.data['key'].toString());
);

不执行。

【问题讨论】:

    标签: firebase dart flutter google-cloud-firestore querying


    【解决方案1】:

    但这似乎不是正确的语法。

    这不是正确的语法,因为您缺少collection() 调用。您不能直接在您的Firestore.instance 上致电document()。为了解决这个问题,你应该使用这样的东西:

    var document = await Firestore.instance.collection('COLLECTION_NAME').document('TESTID1');
    document.get() => then(function(document) {
        print(document("name"));
    });
    

    或者更简单的方式:

    var document = await Firestore.instance.document('COLLECTION_NAME/TESTID1');
    document.get() => then(function(document) {
        print(document("name"));
    });
    

    如果要实时获取数据,请使用以下代码:

    Widget build(BuildContext context) {
      return new StreamBuilder(
          stream: Firestore.instance.collection('COLLECTION_NAME').document('TESTID1').snapshots(),
          builder: (context, snapshot) {
            if (!snapshot.hasData) {
              return new Text("Loading");
            }
            var userDocument = snapshot.data;
            return new Text(userDocument["name"]);
          }
      );
    }
    

    它还可以帮助您将名称设置为文本视图。

    【讨论】:

    • 您指出的错误是正确的,但不是主要问题。根据 AndroidStudio:the getter for DocumentReference is not defined。所以document().get() 也是无效的。我发现缺乏关于这些查询的基本语法的信息。我什至读过specification
    • 你也应该使用await。请参阅我更新的答案。现在可以用了吗?
    • 关于 Firebase,官方文档。关于 Firebase 和 Flutter 我不知道。
    • 我尝试了实时流,但收到此错误The argument type 'Stream<DocumentSnapshot>' can't be assigned to the parameter type 'Stream<QuerySnapshot>'.。有什么想法吗?
    • 知道了。现在通过userDocument.dat,这是实际的地图(stackoverflow.com/questions/56721694/…
    【解决方案2】:

    如果你想使用 where 子句

    await Firestore.instance.collection('collection_name').where(
        FieldPath.documentId,
        isEqualTo: "some_id"
    ).getDocuments().then((event) {
        if (event.documents.isNotEmpty) {
            Map<String, dynamic> documentData = event.documents.single.data; //if it is a single document
        }
    }).catchError((e) => print("error fetching data: $e"));
    

    【讨论】:

    • 我在找这个
    • 以后如何使用它从获取的文档中获取价值?
    • @Harsh Jhunjhunuwala 您可以将其用作地图。例如:如果要从文档中检索一个名为 name 的字段,则 var name = documentData["name"];
    • 它说“'Map Function()' 类型的值不能分配给 'Map' 类型的变量”
    • 可以转换成自定义模型吗?
    【解决方案3】:

    空安全码(推荐)

    您可以在函数中查询文档(例如按下按钮)或在小部件内部(如FutureBuilder)。

    • 在方法中:(一次听)

      var collection = FirebaseFirestore.instance.collection('users');
      var docSnapshot = await collection.doc('doc_id').get();
      if (docSnapshot.exists) {
        Map<String, dynamic>? data = docSnapshot.data();
        var value = data?['some_field']; // <-- The value you want to retrieve. 
        // Call setState if needed.
      }
      
    • FutureBuilder(听一次)

      FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>(
        future: collection.doc('doc_id').get(),
        builder: (_, snapshot) {
          if (snapshot.hasError) return Text ('Error = ${snapshot.error}');
      
          if (snapshot.hasData) {
            var data = snapshot.data!.data();
            var value = data!['some_field']; // <-- Your value
            return Text('Value = $value');
          }
      
          return Center(child: CircularProgressIndicator());
        },
      )
      
    • StreamBuilder:(一直在听)

      StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
        stream: collection.doc('doc_id').snapshots(),
        builder: (_, snapshot) {
          if (snapshot.hasError) return Text('Error = ${snapshot.error}');
      
          if (snapshot.hasData) {
            var output = snapshot.data!.data();
            var value = output!['some_field']; // <-- Your value
            return Text('Value = $value');
          }
      
          return Center(child: CircularProgressIndicator());
        },
      )
      

    【讨论】:

    • 我们可以通过这些方法得到子集合和文档吗?
    【解决方案4】:

    这很简单,您可以使用 DOCUMENT SNAPSHOT

    DocumentSnapshot variable = await Firestore.instance.collection('COLLECTION NAME').document('DOCUMENT ID').get();
    

    您可以使用variable.data['FEILD_NAME']访问其数据

    【讨论】:

    • 我不能“没有为类型 'Map Function()' 定义运算符'[]'。”
    • 要访问数据,您必须编写 variable.data()['FIELD_NAME']。我遇到了同样的问题,并且 () 丢失了。
    【解决方案5】:

    更新 FirebaseFirestore 12/2021

    StreamBuilder(
              stream: FirebaseFirestore.instance
                  .collection('YOUR COLLECTION NAME')
                  .doc(id) //ID OF DOCUMENT
                  .snapshots(),
            builder: (context, snapshot) {
            if (!snapshot.hasData) {
              return new CircularProgressIndicator();
            }
            var document = snapshot.data;
            return new Text(document["name"]);
         }
      );
    }
    

    【讨论】:

    • 如何使用它取出某条信息?假设我的收藏是书籍文件是哈利波特,在此之下我有一个带有标题作者描述的表格,我将如何打印作者?
    • Widget _buildBookItem(BuildContext context, int index, AsyncSnapshot snapshot) { final doc = snapshot.data.docs[index];返回文本(打印(doc.author)); };
    【解决方案6】:

    这就是 2021 年对我有用的方法

          var userPhotos;
          Future<void> getPhoto(id) async {
            //query the user photo
            await FirebaseFirestore.instance.collection("users").doc(id).snapshots().listen((event) {
              setState(() {
                userPhotos = event.get("photoUrl");
                print(userPhotos);
              });
            });
          }
    

    【讨论】:

    • 这是未来查询还是流查询?返回的是 Future,但不是 Stream 的快照查询吗?我很困惑。
    【解决方案7】:

    当您只想从 firestore 集合中获取文档,对其执行一些操作,而不是使用某些小部件显示它时使用此代码(2022 年 1 月更新)

       fetchDoc() async {
    
       // enter here the path , from where you want to fetch the doc
       DocumentSnapshot pathData = await FirebaseFirestore.instance
           .collection('ProfileData')
           .doc(currentUser.uid)
           .get();
    
       if (pathData.exists) {
         Map<String, dynamic>? fetchDoc = pathData.data() as Map<String, dynamic>?;
         
         //Now use fetchDoc?['KEY_names'], to access the data from firestore, to perform operations , for eg
         controllerName.text = fetchDoc?['userName']
    
    
         // setState(() {});  // use only if needed
       }
    }
    

    【讨论】:

      【解决方案8】:

      简单的方法:

      StreamBuilder(
                stream: FirebaseFirestore.instance
                    .collection('YOUR COLLECTION NAME')
                    .doc(id) //ID OF DOCUMENT
                    .snapshots(),
              builder: (context, snapshot) {
              if (!snapshot.hasData) {
                return new CircularProgressIndicator();
              }
              var document = snapshot.data;
              return new Text(document["name"]);
           }
        );
      }
      

      【讨论】:

        【解决方案9】:

        使用这个简单的代码:

        Firestore.instance.collection("users").document().setData({
           "name":"Majeed Ahmed"
        });
        

        【讨论】:

          猜你喜欢
          • 2020-10-11
          • 2018-07-12
          • 1970-01-01
          • 2021-01-01
          • 2023-03-30
          • 2021-04-08
          • 2020-12-26
          • 1970-01-01
          相关资源
          最近更新 更多