使用与flutter's firestore example类似的代码,假设在快照文档中存储了一个名为document['userRef']
的引用字段。
首先,如何访问userRef的数据?使用document['userRef'].get().data
或document['userRef'].get().username
无法访问数据。 (NoSuchMethodError: Class 'Future<DocumentSnapshot>' has no instance getter 'data'
)
我也尝试使用document['userRef'].get().then(...)
,但收到错误消息:type 'Future<dynamic>' is not a subtype of type 'String'
即使.then
可以工作,难道不是每个消息都会再次查找相同的引用吗?在这里,数据库是实时更新的,但是不必对ListView中的多条消息进行相同的查找。
class MessageList extends StatelessWidget {
MessageList({this.firestore});
final Firestore firestore;
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: firestore.collection('messages').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) return const Text('Loading...');
final int messageCount = snapshot.data.documents.length;
return ListView.builder(
itemCount: messageCount,
itemBuilder: (_, int index) {
final DocumentSnapshot document = snapshot.data.documents[index];
// document['userRef'] exists here
return ListTile(
title: Text(document['message'] ?? '<No message retrieved>'),
subtitle: Text('Message ${index + 1} of $messageCount'),
);
},
);
},
);
}
}
编辑: 我可以使用FutureBuilder来获取嵌套数据,尽管不确定其效率如何。 (这是否可能会将大量冗余请求发送到Firebase?)
为文档['userRef']存在的嵌套数据创建小部件:
FutureBuilder(
future: userData(document['userRef']),
builder: (BuildContext context,
AsyncSnapshot<dynamic> uData) {
return Text(uData.data['username']);
},
);
userData函数如下所示:
Future<dynamic> userData(DocumentReference user) async {
DocumentSnapshot userRef = await user.get();
return userRef.data;
}
答案 0 :(得分:2)
按照Firebase和Flutter的方式,可以在Streambuilder中使用Streambuilder。也就是说,不必使用FutureBuilder来处理嵌套数据,而是让您等待每个.get请求。
(代码未经测试,但原理已通过测试。)
!wget http://mftp.mmcheng.net/Data/MSRA10K_Imgs_GT.zip