1

I have two collections in my firestore db; "queries" and "users". My requirement is to get all the queries with respect to specific flag from "queries" collection. Once done I need to check uid in each query and query my user's data using that uid from "users" collection. In this case I am fetching user's name and number using StreamBuilder in flutter. Below is my approach:

return new StreamBuilder(
  stream: db.collection("queries").where("isAttended", isEqualTo: false).snapshots(),
  builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
    if(!snapshot.hasData) return new Text("Loading...");
    return new ListView(
      children: snapshot.data.documents.map((document){
        String name = '';
        String number = '';
        var doc = db.collection("users").document(document["uid"]).get();
        doc.then((onValue) {
          number  = onValue.data['number'];
          name = onValue.data['name'];
        });
       return new ListTile(
         title: new Text(name),
         subtitle: new Text(number),
       ); 
      }).toList(),
    );
  },

);

Problem is onValue returns null. Please advise on my approach for querying data in the manner I specified above. TIA.

1
  • The then() callback only runs once the data is loaded, while the return new ListTile() that uses the data from the database runs straight away. I'm not enough of a Flutter expert to show you how to do this, but this answer shows something similar (though not the same). Commented Oct 5, 2019 at 13:32

1 Answer 1

1

Lets start,

This is your children list List<Widget> children = [];

Change your ListView children to ListView(children: children, ...)

And update your streambuilder like that,

if(!snapshot.hasData) return new Text("Loading...");
initChildren(snapshot); // here is important
return new ListView(...

And initChildren is

initChildren(snapshot) async {
  final list = await Future.wait(snapshot.data.documents.map((document) async {
    String name = '';
    String number = '';
    var doc = await db.collection("users").document(document["uid"]).get();
    doc.then((onValue) {
      number = onValue.data['number'];
      name = onValue.data['name'];
    });
    return new ListTile(
      title: new Text(name),
      subtitle: new Text(number),
    );
  }));
  setState(() => children = list);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.