在 flutter 中映射 Firebase 流

Los*_*xan 2 stream firebase flutter google-cloud-firestore

我主要通过阅读这里的帖子和观看 YouTube 视频来学习 flutter,但似乎我已经达到了视频不能满足我需要的程度,所以我来这里寻求帮助。

我正在尝试了解 Streams、Firebase 和映射。

我需要使用 Riverpod 创建一个 StreamProvider。这是我用来创建 StreamProvider 的代码:

final trxnStreamProvider = StreamProvider.autoDispose<List<Trxns>>((ref) {
  final stream = firestoreService.getAgencyTrxns();
  return stream.map((snapshot) => snapshot.docs.map((doc) =>
      Trxns.fromFirestore(doc.data)).toList());
});
Run Code Online (Sandbox Code Playgroud)

我在这段代码中从 Firebase 获取流:

  Stream<QuerySnapshot> getAgencyTrxns() async* {
    yield* FirebaseFirestore.instance
        .collection('agency').doc(globals.agencyId)
        .collection('trxns')
        .where('trxnStatus', isNotEqualTo: 'Closed')
        .snapshots();
  }
Run Code Online (Sandbox Code Playgroud)

因此,我根据上面的代码片段从 Firebase 获取了 QuerySnapshot。这效果很好。

然后,此 QuerySnapshot 返回到我创建 StreamProvider 的第一个代码片段中的“stream”变量。

然后,QuerySnapshot 变量“stream”被映射到 <List> 并通过此代码返回到 trxnStreamProvider。

return stream.map((snapshot) => snapshot.docs.map((doc) =>
          Trxns.fromFirestore(doc.data)).toList());
Run Code Online (Sandbox Code Playgroud)

我在“doc.data”处收到错误,指出:参数类型“对象?” Function()' 无法分配给参数类型 'Map<String,dynamic>'。

我试图了解这行代码到底在做什么,我需要你的帮助。

return stream.map((snapshot) => snapshot.docs.map((doc) =>
          Trxns.fromFirestore(doc.data)).toList());
Run Code Online (Sandbox Code Playgroud)

让我告诉你我认为它在做什么:

  1. 变量stream有一个名为“map”的方法,调用该方法将QuerySnapshot映射到列表。我不确定“快照”来自哪里,但我认为它是通过此调用 firestoreService.getAgencyTrxns() 从 Firebase 返回的 QuerySnapshot。

  2. QuerySnapshot 由 Firebase 集合“trxns”中包含的文档组成。这解释了 snapshot.docs,现在我们希望使用 snapshot.docs.map() 方法将每个文档映射到列表。我使用以下代码传递要映射的每个单独文档:snapshot.docs.map(doc)。

  3. 我正在使用 Trxns.fromFirestore(doc.data)).toList() 方法将文档中包含的元素映射到列表。将返回的列表类型将是 Map<String,dynamic> (我认为)。

这是映射代码:

Trxns.fromFirestore(Map<String, dynamic> firestore)
      : trxnId = firestore['trxnId'],
        agentId = firestore['agentId'],
        agencyId = firestore['agencyId'];
Run Code Online (Sandbox Code Playgroud)

在返回的地图中看起来像这样:

trxnId:某个值,agentId:某个值,agencyId:某个值;

它是否正确?

这些都是 Trxns 类的成员,因此它现在具有 <List> 的形式。它是否正确?

那么,“doc.data”只是 QuerySnapshot 中文档之一的快照,对吗?

为什么我在“doc.data”上收到错误?

在此输入图像描述

Hut*_*yad 5

将其更改为此,并将其转换为Map

return stream.map((snapshot) => snapshot.docs.map((doc) =>
Trxns.fromFirestore(doc.data() as Map<String, dynamic>)).toList());
Run Code Online (Sandbox Code Playgroud)

Map要访问您的实际内容doc,您需要使用data()来获取所有密钥,或者您可以使用.get('name')例如来获取文档中名为 name 的特定密钥。

那么,“doc.data”只是 QuerySnapshot 中文档之一的快照,对吗?

正确,QuerySnapshot是 的列表DocumentSnapshots,并且它们在名为 的对象中保存在一起docsdocs您可以像 length 一样执行列表操作docs.map

您唯一错过的是调用该data函数。当您输入 时doc.data,这里将其视为对从文档中data提取对的函数的引用{key:value},它包含由 Firebase 编写的幕后所有逻辑,但如果您在此停止而不使用(),则不会调用该函数。

因此,只需使用 , 修复类型doc.data()就可以解决您的问题。