【问题标题】:What is the difference between existing types of snapshots in Firebase?Firebase 中现有的快照类型有什么区别?
【发布时间】:2021-04-28 15:13:58
【问题描述】:

随着我的代码和 Flutter 编码经验的进一步发展。在使用 Firebase API 时,我遇到了不同类型的快照。我说的是 AsyncSnapshots、QuerySnapshots、DocumentSnapshots 和 DataSnapshots。如果还有更多请给他们命名。

我想知道,这些快照之间的确切区别是什么。

到目前为止,我认为 AsyncSnapshot 可能是异步拍摄的快照,这意味着小部件是在快照的数据可用之前构建的,因此使其异步(如果我错了,请纠正我) .这就是我的困惑开始的地方,快照到底是什么?他们每个人的“数据”是什么。 例如:为什么同一个函数不能在所有快照中检索所需的数据,而是只在特定快照上起作用。

为什么需要将数据从 QuerySnapshot 转换为 DocumentSnapshot 以使其可访问(如果我错了,请再次纠正我)? DocumentSnapshot 和 DataSnapshot 之间的确切区别是什么。当它们都返回 Maps 时,为什么它们的名称不同?

提前谢谢你。

【问题讨论】:

  • 好问题!我在下面回答。由于我经常对此感到困惑,因此我尽量保持我的回答非常笼统,但如果您的特定用例有任何不清楚的地方,请告诉我。
  • 非常感谢,对我帮助很大。

标签: firebase flutter snapshot


【解决方案1】:

据我所知,你是在 Flutter 的上下文中问这个问题的,所以我将在下面回答这个问题。

Firebase 中有两个数据库:原始实时数据库和较新的 Cloud Firestore。今天两者都是同样有效的选项,但它们与自己的 API 完全分开。但两者都返回数据的快照,其中快照是应用程序代码中数据库数据的副本。

在 Flutter 中有 FutureBuilderStreamBuilder,它们处理异步加载的数据快照。

让我们看看我是否可以覆盖它们:

  • AsyncSnapshot 是 Fl​​utter 对来自异步数据源(例如 Firestore 和实时数据库)的数据的包装器。它们涵盖了此类数据可能处于的状态,从初始连接到检索,直到出现错误或拥有数据。
  • DocumentSnapshots 和 QuerySnapshots 是 Firestore 的类,用于表示单个文档或从数据库读取时获得的文档列表。因此,如果您加载单个文档,您将获得带有其数据的 DocumentSnapshot。如果你加载一个文档列表,你会得到一个QuerySnapshot,然后循环访问单个DocumentSnapshots。
  • DataSnapshot 是实时数据库的类,既适用于单个节点,也适用于数据库中的节点列表。

因此,在 Flutter 中,您将拥有一个引用 Firebase 快照类之一的 AsyncSnapshot,然后该 Firebase 快照会包装实际数据。


假设您要显示包含 Firestore 集合中文档的列表,您将拥有:

  1. AsyncSnapshot 提供给您的StreamBuilder,以便它可以呈现正确的数据加载状态。
  2. QuerySnapshot 用于数据库中的文档列表。
  3. 然后,该列表中的每个项目都是 DocumentSnapshot,其中包含来自单个文档的数据快照。

我实际上发现在代码中更容易看到这一点,就像FlutterFire documentation 中的这个示例一样:

class UserInformation extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    CollectionReference users = FirebaseFirestore.instance.collection('users');

    return StreamBuilder<QuerySnapshot>(
      stream: users.snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) {
          return Text('Something went wrong');
        }

        if (snapshot.connectionState == ConnectionState.waiting) {
          return Text("Loading");
        }

        return new ListView(
          children: snapshot.data.documents.map((DocumentSnapshot document) {
            return new ListTile(
              title: new Text(document.data()['full_name']),
              subtitle: new Text(document.data()['company']),
            );
          }).toList(),
        );
      },
    );
  }
}

【讨论】:

  • QueryDocumentSnapshot 怎么样?它只是 QuerySnapshot 中的一个文档?如果是这样,如果没有任何不同,我如何将其转换为与 DocumentSnapshot 匹配。
  • A QueryDocumentSnapshot 只是 DocumentSnapshot 的子类,具有相同的属性,但有一些额外的保证:“由于查询结果仅包含现有文档,exists 属性将始终为 true 并且 data()永远不会返回 null。”对于此类问题,我强烈建议您将文档放在手边:pub.dev/documentation/cloud_firestore/latest/cloud_firestore/…
猜你喜欢
  • 2013-06-28
  • 2020-01-23
  • 2010-10-02
  • 2020-10-19
  • 2018-08-29
  • 1970-01-01
  • 2018-12-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多