Flutter Firebase 数据库,DataSnapshot?如何获取值和键,null 安全

Posted

技术标签:

【中文标题】Flutter Firebase 数据库,DataSnapshot?如何获取值和键,null 安全【英文标题】:Flutter Firebase Database, DataSnapshot? how to get values and keys, null safe 【发布时间】:2021-09-21 17:17:04 【问题描述】:

使用 firebase_database:^7.1.1

在 null 安全之前,我曾经这样做是为了从 firebase 数据库中获取数据:

DataSnapshot dataSnapshot = await References.getReferenceYears().once();
Map<dynamic, dynamic> values = dataSnapshot.value;
values.forEach((key, value) ...

现在当我尝试这样做时,我得到如下错误:

DataSnapshot? dataSnapshot = await References.getReferenceYears().once();
Map<dynamic, dynamic> values = dataSnapshot.value;

[ERROR:flutter/lib/ui/ui_dart_state.cc(199)] 未处理的异常:类型 'List' 不是类型 'Map' 的子类型

我认为这意味着 key 没有在 dataSnapshot.value 中返回,我现在如何像以前一样使用它来获取 (key, value)?

如果我打印我得到的 snapshot.value,所以看起来键不再像以前一样出现在 snapshot.value 中,我现在不知道键在哪里:

[name: 2016-2017, name: 2017-2018, name: 2018-2019]

提前致谢。

【问题讨论】:

听起来您在References.getReferenceYears() 下有连续的数字键,SDK 会将其转换为数组。我认为这在最近的 SDK 中没有改变,因为 Firebase 总是试图将这些键强制转换为数组。如果您确定它已更改,您可以编辑您的问题以在References.getReferenceYears() 显示 JSON(作为文本,请不要截图)?您可以通过单击 Firebase Database console 的溢出菜单 (⠇) 中的“导出 JSON”链接来获取此信息。 啊,是的,你是对的。非常感谢。 【参考方案1】:

试试这个

DataSnapshot dataSnapshot = await References.getReferenceYears().once();

(dataSnapshot as Map<dynamic, dynamic>).forEach((key, value) ...

【讨论】:

它像这样在 null 安全之前工作,但现在它具有 null 安全性,结果是 List 所以不起作用。【参考方案2】:

听起来您在References.getReferenceYears() 下有连续的数字键,SDK 会将其转换为数组。我认为这在最近的 SDK 中没有改变,因为 Firebase 总是试图将这些键强制转换为数组。

如果您不希望将值存储到数组中,防止这种情况发生的最简单方法是在键前面加上一个短的非数字值,例如:

"key_0": "value 0",
"key_1": "value 1",
"key_2": "value 2",
...

【讨论】:

【参考方案3】:

您可能也更新了 Flutterfire cloud_firestore,因为从错误中可以看出,在最新版本中,从快照返回的数据是 ObjectList&lt;Object&gt; 而不是地图。

你可以这样解决:

snapshot.value as Map<String, dynamic>

编辑:

我在哪里看到你提到 firebase 实时数据库。 所以问题不是flutter_fire引起的。

错误告诉您您正在尝试将 List 放入 Map

一种解决方案可能是:

Map<dynamic, dynamic> values = dataSnapshot.value as Map<dynamic, dynamic>;

【讨论】:

谢谢回复,我没有用cloud_firestore,是firebase_database,这段代码不起作用。 哦,对不起,我刚刚看到你编辑了。无论如何解决方案应该是相似的,我将更新我的答案。 我尝试了第二种方式,但结果是 List 现在,不是地图,如果我打印 snapshot.value,我会得到一个对象列表,但没有键。所以看起来键不再在结果中了? 我也有同样的问题..你找到解决方案了吗? 自从我将 firebase 版本更新到 9.0.5 后,我也遇到了同样的问题

以上是关于Flutter Firebase 数据库,DataSnapshot?如何获取值和键,null 安全的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 和 Firebase 的前台打印(message.data)

Flutter Firebase 在 null 上调用了方法“数据”

Flutter Firebase 实时数据库:“[permission-denied] 客户端无权访问所需数据。”问题

如何使用具有 Null 安全性的 FlutterFire Firestore 和 Flutter 2.0 从 Firebase 获取数据

Flutter Firebase/Firestore 一次写入多个表

Firebase Query 不适用于 Flutter,如何解决?