【问题标题】:How to get list of document ids?如何获取文档 ID 列表?
【发布时间】:2020-10-19 02:59:53
【问题描述】:

我正在尝试从 Firestore 中检索文档 ID 列表。 我的 firestore 函数作为静态方法存储在我创建的 FirebaseAPI 类中。

这是应该返回 documentIds 列表的函数:

static List<String> avaiableDocuments() {

  List<String> ids = [];

  final Future<QuerySnapshot> snapshot = Firestore.instance.collection('admin').getDocuments();

  snapshot.then((value) {
    value.documents.forEach((element) {
      ids.add(element.documentID);
    });
  });

  return ids;
}

当我重新启动应用程序时,没有出现文档 ID 列表。 但是,它们会在热重载时出现。

我的理解是,当应用重新启动时,字符串列表仍然是空的。 这是因为页面在未来返回之前呈现。 然后当热重载再次调用 build 方法时,列表已经被填充,所以它会显示它。

我尝试在 getDocuments 调用之前添加“等待”。 这将 Future 变成了 QuerySnapshot。很公平。 现在必须将“异步”添加到函数中。 那么这个函数现在需要一个未来的返回而不是一个列表。

我不能从这个函数中得到一个列表吗?

我尝试过,结果是这样的:

static Future<List<String>> avaiableDocuments() async{
  List<String> ids = [];

  final QuerySnapshot snapshot = await Firestore.instance.collection('admin').getDocuments();
  snapshot.documents.forEach((element) {
    ids.add(element.documentID);
  });

  return ids;
}
  1. 为什么允许我从一个说它返回未来的函数返回一个列表?
  2. 当我尝试在屏幕类中消费未来时,同样的事情发生了。列表仅在重启后热重载时出现。

注意:我觉得这是一个简单的问题,但对于异步 voodoo,我几乎是个菜鸟。


应该显示文档 ID 列表的类

import 'package:flutter/material.dart';
import 'package:hisab/database/firestore_api.dart';


class PreviousCarts extends StatefulWidget {
  const PreviousCarts({Key key}) : super(key: key);

  @override
  _PreviousCartsState createState() => _PreviousCartsState();
}

class _PreviousCartsState extends State<PreviousCarts> {

  List<String> documentIds = [];

  @override
  void initState() { 
    super.initState();
    Future<List<String>> f = FirestoreAPI.avaiableDocuments();
    f.then((value) {
      value.forEach((element) {
        documentIds.add(element);
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    print(documentIds);
    return Material(
      child: Padding(
        padding: const EdgeInsets.only(left: 8.0, top: 8.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: documentIds.map((e) {
            return Card(child: ListTile(title: Text(e)));
          }).toList(),
        ),
      ),
    );
  }
}

【问题讨论】:

    标签: firebase flutter google-cloud-firestore async-await


    【解决方案1】:

    我不能从这个函数中得到一个列表吗?

    没有。由于数据库查询是异步的,因此涉及它的所有内容也必须是异步的。尝试将异步方法转换为立即返回方法是个坏主意,因为如果查询速度慢或应用程序离线,这会导致您的应用程序冻结。

    我建议阅读本文以了解一些情况。 https://medium.com/firebase-developers/why-are-the-firebase-apis-asynchronous-e037a6654a93

    为什么允许我从一个说它返回未来的函数返回一个列表?

    因为 dart 编译器确保调用者接收到 Future。它在幕后处理有关 async/await 的难题,以便您更轻松地编写代码,这样您就不必在未来出现时明确说明。

    这种异步编程风格非常普遍,并且出现在其他语言中,例如 JavaScript。如果您想有效地使用 dart 和一般的异步编程,那么我建议您花时间熟悉这些技术。这需要练习。

    【讨论】:

    • 阅读了这篇文章,我明白了需要异步的原因。特别是关于阻塞主线程的部分。我本可以选择 FutureBuilder,但我想将与 Firestore 相关的代码保留在自己的页面中。现在我的函数只返回获取文档(等待)。然后我在 FutureBuilder 中使用它们。所以没有使用 Firestore 查询转义 Stream 或 Future 构建器?
    • 这正是我在回答中所暗示的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-14
    • 2020-03-09
    • 1970-01-01
    • 2020-09-07
    • 2021-01-28
    • 1970-01-01
    • 2019-05-05
    相关资源
    最近更新 更多