Используя код, похожий на пример флаттера , предположим, что в документе снимка хранится поле ссылки, называемое: 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;
}