Flutter中如何从Firestore的DocumentSnapshot实例中获取数据
问题原因
你当前代码的核心问题出在两点:
- 你定义的Stream监听的是
users集合下单个用户文档的快照,返回的snapshot.data本身就是_JsonDocumentSnapshot类型的单条文档对象,不是包含多条文档的集合快照,所以直接调用map方法必然报错 - 就算是监听集合快照,
map方法返回的是Iterable类型,需要调用.toList()转换后才能传入ListView的children参数
解决方案分两种场景
场景1:你需要读取当前用户单条文档内的字段
如果你的数据直接存在对应用户id的文档下,直接从单条文档中取字段即可,修改builder内的返回逻辑:
@override Widget build(BuildContext context) { return StreamBuilder( stream: _entryStream, builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasError) { return const Text("Something went wrong"); } if (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } // 强转类型为DocumentSnapshot DocumentSnapshot userDoc = snapshot.data as DocumentSnapshot; Map<String, dynamic> userData = userDoc.data() as Map<String, dynamic>; // 直接取文档内的text字段展示,可根据需求修改为其他Widget布局 return Text(userData['text']); }, ); }
场景2:你需要读取当前用户下的子集合多条数据
如果你的数据存在用户文档下的子集合中(比如命名为entries的子集合),首先修改Stream的定义:
final Stream _entryStream = FirebaseFirestore.instance .collection('users') .doc(FirebaseAuth.instance.currentUser.uid) .collection('entries') // 替换为你实际的子集合名称 .snapshots();
再修改builder内的返回逻辑,遍历集合快照下的所有文档:
@override Widget build(BuildContext context) { return StreamBuilder( stream: _entryStream, builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasError) { return const Text("Something went wrong"); } if (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } // 强转类型为QuerySnapshot(集合快照) QuerySnapshot entrySnapshot = snapshot.data as QuerySnapshot; return ListView( children: entrySnapshot.docs.map((DocumentSnapshot document) { Map<String, dynamic> data = document.data() as Map<String, dynamic>; return Text(data['text']); }).toList(), // 必须调用toList()转换为List类型 ); }, ); }
内容的提问来源于stack exchange,提问作者pythonNovice
相关产品推荐
相关产品推荐

