Flutter - 从 Cloud Firestore 读取嵌套地图
Posted
技术标签:
【中文标题】Flutter - 从 Cloud Firestore 读取嵌套地图【英文标题】:Flutter - Read Nested Maps from Cloud Firestore 【发布时间】:2021-09-30 22:43:20 【问题描述】:我在尝试从 Cloud Firestore 读取另一个地图中的地图时遇到问题。我在互联网上找到了几篇关于该主题的帖子,但作为 Flutter 和 Firebase 的初学者,我无法根据我的情况调整这些案例。
在 Firebase Firestore 中,我有以下数据示例,属于“媒体”集合:
我能够读取几乎所有数据,包括数组(使用强制转换),但“成分”确实让我很痛苦。它是Map<String, Quantity>
,数量是我的一类:
class Quantity
final double amount;
final String unit;
const Quantity(
required this.amount,
required this.unit,
);
String toString() => '$amount $unit';
现在它很简单,但会随着更多使用双精度值的方法而增长。这就是我不想摆脱它并简化数据库条目的原因。
我需要使用 Stream Builder 读取所有数据并将其传递给 ListView.buider,如下所示:
Widget build(BuildContext context)
return StreamBuilder(
stream: FirebaseFirestore.instance
.collection('media')
.orderBy('initials')
.snapshots(),
builder: (BuildContext ctx,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> media)
if (media.connectionState == ConnectionState.waiting)
return Center(
child: CircularProgressIndicator(),
);
var docs = media.data!.docs;
var box = Hive.box<Favorite>('favorites');
return ListView.builder(
itemCount: media.data!.docs.length,
itemBuilder: (ctx, i)
Medium md = Medium(
initials: docs[i].get('initials'),
longName: docs[i].get('longName'),
ingredients: <String, Quantity>, // docs[i].get('ingredients'),
steps: docs[i].get('steps').cast<String>(),
mediumState: PhysicalState.values.elementAt(
docs[i].get('mediumState'),
),
reference: docs[i].data().containsKey('reference')
? docs[i].get('reference')
: '',
isComplement: docs[i].data().containsKey('isComplement')
? docs[i].get('isComplement')
: false,
ps: docs[i].data().containsKey('ps') ? docs[i].get('ps') : '',
);
if (box.get(docs[i].get('initials')) == null)
box.put(
docs[i].get('initials'),
Favorite(
initials: docs[i].get('initials'),
isFavorite: false,
),
);
return MediumCard(
medium: md,
);
,
);
,
);
被调用的 Medium 构造函数是这个:
class Medium
final String initials;
final String longName;
final Map<String, Quantity> ingredients;
final List<String> steps;
final PhysicalState mediumState;
String reference;
bool isComplement;
String ps;
Medium(
required this.initials,
required this.longName,
required this.ingredients,
required this.steps,
required this.mediumState,
this.reference = '',
this.isComplement = false,
this.ps = '',
);
我可以发布很多尝试和错误消息,但帖子会不必要地长,所以只有一次尝试,尝试使用与其他条目 docs[i].get('ingredients')
相同的逻辑,这给了我这个:
type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Map<String, Quantity>'
请务必注意,“成分”中的 os 数量可能会有所不同,并且并不总是与上述示例中的两个相同(水和琼脂)。
最后,这个问题。如何调整 ListView.builder
代码中“成分”的导入以正确读取 Firebase 中的那部分数据?
我在 Flutter 2.2.3
、cloud_firestore: ^2.4.0
和 firebase_core: ^1.4.0
Ps.:很抱歉有任何英文错误。我不是母语人士(“作家”)。
【问题讨论】:
嗨@Rodrigo,我可以检查您的“步数”地图是否是动态的(意味着步数可以改变)?如果是这样,你如何在颤动中映射它?我在 ***.com/questions/69052105/… 面临类似的问题。很想听听您对此的看法。谢谢! 嗨@scottlee。我的步骤确实是动态大小的。我用来从 Firestore 解析这些信息的代码是:steps: doc.data().containsKey('steps') ? doc.get('steps').cast<String>() : <String>[],
。重要的是要注意,我的“步骤”数据实际上是 firestore 中的一个数组,它对应于 Dart/Flutter 中的 List 而不是地图。我会看看你链接的问题。如果对如何提供帮助有任何想法,我会在那里发帖。
【参考方案1】:
经过更多的尝试和失败,我能够通过添加到 ListView.builder
代码来解决我的问题:
var docs = media.data!.docs;
var box = Hive.box<Favorite>('favorites');
Map<String, Quantity> myIngredients = ;
return ListView.builder(
itemCount: media.data!.docs.length,
itemBuilder: (ctx, i)
// Convert data from firebase into <String, Quantity>
Map.from(docs[i].get('ingredients')).entries.forEach((e)
myIngredients[e.key] = Quantity(
amount: e.value['amount'].toDouble(),
unit: e.value['unit'],
);
);
Medium md = Medium(
initials: docs[i].get('initials'),
longName: docs[i].get('longName'),
ingredients: myIngredients,
steps: docs[i].get('steps').cast<String>(),
mediumState: PhysicalState.values.elementAt(
docs[i].get('mediumState'),
),
reference: docs[i].data().containsKey('reference')
? docs[i].get('reference')
: '',
isComplement: docs[i].data().containsKey('isComplement')
? docs[i].get('isComplement')
: false,
ps: docs[i].data().containsKey('ps') ? docs[i].get('ps') : '',
);
所以使用Map.from
方法我能够设置Map<String, Quantity>
实例并使用它。
如果有人找到更好、更清洁的解决方案,我很想看看。 非常感谢。
【讨论】:
以上是关于Flutter - 从 Cloud Firestore 读取嵌套地图的主要内容,如果未能解决你的问题,请参考以下文章
Flutter - 从 Cloud Firestore 读取嵌套地图
如何使用 graphql 从 Firebase 使用 Flutter 从 Cloud Firestore 获取数据?
在进行身份验证之前,如何使用 Flutter 从 Cloud Firestore 搜索和访问数据?