json - 如何在 Flutter 项目中显示来自 Firebase 的 QueryDocumentSnapshot?(颤振,Firebase,Json,飞镖)
问题描述
以下是一个名为“week”的示例 QueryDocumentSnapshot,我使用 StreamBuilder 从 Firestore 获得。我正在寻找一种方法来显示这些或多或少复杂的数据,例如 Card-Widget,其中包含来自 Flutter 项目中每个快照的信息。
{
"days":{
"3": {
"activities": {
"1628658343103": {
"query": "I am watering the plants",
"finished": false,
"params": [
{
"pronounsDefinite": "I"
},
{
"verbsHelpPresent": "am"
},
{
"verbsGerund": "watering"
},
{
"articles": "the"
},
{
"nouns": "plant"
}
],
"intent": "gHomesAndBuildingsGardensAC",
"duration": 3
},
"1628673512954": {
"query": "I am cutting the bushes",
"finished": false,
"params": [
{
"pronounsDefinite": "I"
},
{
"verbsHelpPresent": "am"
},
{
"verbsGerund": "cutting"
},
{
"articles": "the"
},
{
"nouns": "bush"
}
],
"intent": "gHomesAndBuildingsGardensAC",
"duration": 3
},
"1628673476549": {
"query": "I work in the garden",
"finished": false,
"params": [
{
"pronounsDefinite": "I"
},
{
"verbsInfinitiv": "work"
},
{
"prepositions": "in"
},
{
"articles": "the"
},
{
"nouns": "garden"
}],
"intent": "gHomesAndBuildingsGardensAC",
"duration": 4
}
}
},
"4": {
"activities": {
"1628658343104": {
"query": "I am watering the plants",
"finished": false,
"params": [
{
"pronounsDefinite": "I"
},
{
"verbsHelpPresent": "am"
},
{
"verbsGerund": "watering"
},
{
"articles": "the"
},
{
"nouns": "plant"
}
],
"intent": "gHomesAndBuildingsGardensAC",
"duration": 3
},
"1628673512956": {
"query": "I am cutting the bushes",
"finished": false,
"params": [
{
"pronounsDefinite": "I"
},
{
"verbsHelpPresent": "am"
},
{
"verbsGerund": "cutting"
},
{
"articles": "the"
},
{
"nouns": "bush"
}
],
"intent": "gHomesAndBuildingsGardensAC",
"duration": 3
},
"1628673476559": {
"query": "I work in the garden",
"finished": false,
"params": [
{
"pronounsDefinite": "I"
},
{
"verbsInfinitiv": "work"
},
{
"prepositions": "in"
},
{
"articles": "the"
},
{
"nouns": "garden"
}],
"intent": "gHomesAndBuildingsGardensAC",
"duration": 3
}
}
}
}
}
这就是问题所在:我有一个 ListView.builder 方法,它为每个快照文档构建一个小部件,就像上面的那个一样。
“活动”中的数字键是时间戳。我可以使用这个显示一些文本:
...
Text(
week['days']['3']['activities']['1628658343103']['query'].toString()
), //Which displays: "I am watering the plants"
但是这样我就必须知道每个时间戳,并用显然不起作用的确切数字这样称呼它。
如何使用“forEach()”之类的东西来遍历活动中的所有现有条目?
我还为此使用https://app.quicktype.io构建了一个模型类, 但随后它引发了 FormatException,因为我在尝试此操作时尝试将 QueryDocumentSnapshot 粘贴到该类:
Widget buildCard(BuildContext context, DocumentSnapshot week) {
final dataFromWeek = dataFromWeekFromJson(week.toString());
return new Container(.....);
//In this Container, all the text from json should be displayed
}
这是我从 JSON QuickType 工具获得的模型类。
// To parse this JSON data, do
//
// final dataFromWeek = dataFromWeekFromJson(jsonString);
import 'dart:convert';
DataFromWeek dataFromWeekFromJson(String str) =>
DataFromWeek.fromJson(json.decode(str));
String dataFromWeekToJson(DataFromWeek data) => json.encode(data.toJson());
class DataFromWeek {
DataFromWeek({
this.days,
});
Map<String, Day> days;
factory DataFromWeek.fromJson(Map<String, dynamic> json) => DataFromWeek(
days: Map.from(json["days"])
.map((k, v) => MapEntry<String, Day>(k, Day.fromJson(v))),
);
Map<String, dynamic> toJson() => {
"days": Map.from(days)
.map((k, v) => MapEntry<String, dynamic>(k, v.toJson())),
};
}
class Day {
Day({
this.activities,
});
Map<String, Activity> activities;
factory Day.fromJson(Map<String, dynamic> json) => Day(
activities: Map.from(json["activities"])
.map((k, v) => MapEntry<String, Activity>(k, Activity.fromJson(v))),
);
Map<String, dynamic> toJson() => {
"activities": Map.from(activities)
.map((k, v) => MapEntry<String, dynamic>(k, v.toJson())),
};
}
class Activity {
Activity({
this.query,
this.finished,
this.params,
this.intent,
this.duration,
});
String query;
bool finished;
List<Param> params;
String intent;
int duration;
factory Activity.fromJson(Map<String, dynamic> json) => Activity(
query: json["query"],
finished: json["finished"],
params: List<Param>.from(json["params"].map((x) => Param.fromJson(x))),
intent: json["intent"],
duration: json["duration"],
);
Map<String, dynamic> toJson() => {
"query": query,
"finished": finished,
"params": List<dynamic>.from(params.map((x) => x.toJson())),
"intent": intent,
"duration": duration,
};
}
class Param {
Param({
this.pronounsDefinite,
this.verbsHelpPresent,
this.verbsGerund,
this.articles,
this.nouns,
this.verbsInfinitiv,
this.prepositions,
});
String pronounsDefinite;
String verbsHelpPresent;
String verbsGerund;
String articles;
String nouns;
String verbsInfinitiv;
String prepositions;
factory Param.fromJson(Map<String, dynamic> json) => Param(
pronounsDefinite:
json["pronounsDefinite"] == null ? null : json["pronounsDefinite"],
verbsHelpPresent:
json["verbsHelpPresent"] == null ? null : json["verbsHelpPresent"],
verbsGerund: json["verbsGerund"] == null ? null : json["verbsGerund"],
articles: json["articles"] == null ? null : json["articles"],
nouns: json["nouns"] == null ? null : json["nouns"],
verbsInfinitiv:
json["verbsInfinitiv"] == null ? null : json["verbsInfinitiv"],
prepositions:
json["prepositions"] == null ? null : json["prepositions"],
);
Map<String, dynamic> toJson() => {
"pronounsDefinite": pronounsDefinite == null ? null : pronounsDefinite,
"verbsHelpPresent": verbsHelpPresent == null ? null : verbsHelpPresent,
"verbsGerund": verbsGerund == null ? null : verbsGerund,
"articles": articles == null ? null : articles,
"nouns": nouns == null ? null : nouns,
"verbsInfinitiv": verbsInfinitiv == null ? null : verbsInfinitiv,
"prepositions": prepositions == null ? null : prepositions,
};
}
我实际上并不想显示“参数”,但如果有一些灵活性会很棒,这就是为什么我尝试使用模型类在“卡片小部件”中显示快照数据的原因。
解决方案
您想要获取特定日期的所有活动,然后循环浏览它并创建一张卡片。
首先,这是您应该如何构建数据的方式。
'days'(集合)-> '3'(文档)-> 'activities'(文档 3 下的子集合)
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder<QuerySnapshot<Activity>>(
// below will return all the activities for under doc('3')
stream: FirebaseFirestore.instance
.collection("days")
.doc('3')
.collection("activities")
// NB: I used your Activity Model
.withConverter<Activity>(
fromFirestore: (snapshot, _) =>
Activity.fromJson(snapshot.data()),
toFirestore: (data, _) => data.toJson(),
)
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot<Activity>> snapshot) {
if (snapshot.hasError) return Text('Something went wrong');
if (snapshot.connectionState == ConnectionState.waiting)
return CircularProgressIndicator();
// you can then loop through query and build the card;
List<Activity> _activities =
snapshot.data.docs.map((e) => e.data()).toList();
return ListView.builder(
itemCount: _activities.length,
itemBuilder: (context, i) {
// you can return a card here.
return ListTile(
title: Text(_activities[i].query),
);
},
);
},
),
);
}
推荐阅读
- ionic-framework - 在 Ionic 中下载的文件位置在哪里
- django - 每个视图的 Django REST Framework page_size 未按预期工作
- angular - 如何在 Angular 7 中检查服务调用是否已完成?
- excel - Excel:单元格显示的值与其链接的值不同(迭代计算)
- html - 文本、图片和视频出现在我的弹性框后面
- flutter - 为什么我不能在颤振推送器中发送地图?
- r - 汇总/分组表中的唯一行
- bash - 如何将每个命令的 stout 重定向到 bash 中的单独日志文件?
- gtsummary - 在 gtsummary 中显示和比较连续变量的正态分布与非正态分布的简单方法
- azure - Power shell 命令禁用 Azure 数据工厂的网络设置