Я пытаюсь получить сообщения из коллекции Firestore, которая называется "posts", которая содержит userID создателя сообщения и описание сообщения, и это возможно при использовании как StreamBuilder, так и FutureBuilder (не желательно, потому что этополучает снимок только один раз и не обновляется при изменении поля).
Однако я хочу запросить другую коллекцию, называемую "пользователи", с помощью идентификатора пользователя создателя поста и получить документ, соответствующий идентификатору пользователя.
Это был мой первый подход:
StreamBuilder<QuerySnapshot>(
stream:Firestore.instance.collection("posts").snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(
child: _showProgressBar,
);
}
List<DocumentSnapshot> reversedDocuments = snapshot.data.documents.reversed.toList();
return ListView.builder(
itemCount: reversedDocuments.length,
itemBuilder: (BuildContext context, int index){
String postAuthorID = reversedDocuments[index].data["postAuthorID"].toString();
String postAuthorName = '';
Firestore.instance.collection("users")
.where("userID", isEqualTo: postAuthorID).snapshots().listen((dataSnapshot) {
print(postAuthorName = dataSnapshot.documents[0].data["username"]);
setState(() {
postAuthorName = dataSnapshot.documents[0].data["username"];
});
});
String desc = reversedDocuments[index].data["post_desc"].toString();
return new ListTile(
title: Container(
child: Row(
children: <Widget>[
Expanded(
child: Card(
child: new Column(
children: <Widget>[
ListTile(
title: Text(postAuthorName, //Here, the value is not changed, it holds empty space.
style: TextStyle(
fontSize: 20.0,
),
),
subtitle: Text(desc),
),
)
После понимания того, что ListView.builder () может отображать только элементы, основанные на списке DocumentSnapshot, и не может обрабатывать запросы внутри компоновщика.
После многих исследований: Я перепробовал много альтернатив, например, попытался построить список в initState (), попробовал использовать Nested Stream Builder:
return StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('posts').snapshots(),
builder: (context, snapshot1){
return StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection("users").snapshots(),
builder: (context, snapshot2){
return ListView.builder(
itemCount: snapshot1.data.documents.length,
itemBuilder: (context, index){
String desc = snapshot1.data.documents[index].data['post_description'].toString();
String taskAuthorID = snapshot1.data.documents[index].data['post_authorID'].toString();
var usersMap = snapshot2.data.documents.asMap();
String authorName;
username.forEach((len, snap){
print("Position: $len, Data: ${snap.data["username"]}");
if(snap.documentID == post_AuthorID){
authorName = snap.data["username"].toString();
}
});
return ListTile(
title: Text(desc),
subtitle: Text(authorName), //Crashes here...
);
},
);
}
);
}
);
Пробовалс Stream Group и не мог найти способ сделать это, так как он просто объединяет два потока, но я хочу, чтобы второй поток был получен по значению из первого потока.
Это скриншот моей коллекции Firebase:
Коллекция "сообщений" Firestore:
Коллекция "пользователей" Firestore:
Я знаю, что это очень простая вещь, но все еще не мог найти учебник или статьи для этого.