Search code examples
listfluttersnapshotitems

Flutter Future<QuerySnapshot> empty


Greetings everyone and thank you for your time upfront. As a very new member here i kindly ask to be not too harsh with me and my concern if i break any rule i wasnt aware of in this moment.

Situation: i was given flutter code to enhance with functions. The pre-existing code is getting data from a firestore database. I was asked to enhance the code to add user-management (admin functions). All persons involved are new to flutter so all code is basically done by examples from the net.

Problem: So far so ok, but as soon as i call a future function on a querysnapshot, i dont get any userdata. I tried different approaches but none actually worked (e.g. cycling though the snapshot via for-loop, added a Firestore Indexer, added the rules, etc.)

In the following i give you an oversight over the firestore structure and the latest attempt to retrieve the data and sending to a listview builder:

FireStore

And this is the code:

final _auth = FirebaseAuth.instance;
CollectionReference _collectionRef =
    FirebaseFirestore.instance.collection('users');

class _UserlistScreenState extends State<UserlistScreen> {
  final currentUser = _auth.currentUser.email;

  @override
  void initState() {
    getUserList();
    print(traceCount++);
    super.initState();
  }

  var traceCount = 0;
  var snapshotData;
  var itemCount;
  var userList;

  Future<QuerySnapshot> getUserList() async {
    return userList = await _collectionRef
        .doc('settings')
        .collection('userSettings')
        //.where('cid', isEqualTo: globals.CID)
        .get();
  }

  /*Function Cycle() {
    for (var doc in userList.docs) {
      print(doc.data);
    }
  }*/

  


  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          title: Hero(
            tag: 'logo',
            child: Image.asset(
              'assets/rgb.png',
              height: MediaQuery.of(context).size.height * 0.05,
              fit: BoxFit.cover,
            ),
          ),
          actions: [],
          centerTitle: true,
          elevation: 4,
        ),
        body: BackgroundContainer(
          child: Column(
            children: [
              Expanded(
                child: FutureBuilder(
                    future: getUserList(),
                    builder:
                        (BuildContext context, AsyncSnapshot querySnapshot) {
                      
                      if (querySnapshot.hasData) {
                      
                      print(userList.docs); // test
                         /*return ListView(children: getUser(querySnapshot));*/ // also test
                        
                        return ListView.builder(
                          itemCount: userList.docs.length,
                          itemBuilder: (BuildContext context, index) {
                            var xname = userList.docs[index]['name'].toString();
                            var xemail = userList.docs[index]['email'].toString();
                            
                            final List<Map> _tableData = [
                              {'id': 'Name:', 'content': xname},
                              {'id': 'Email:', 'content': xemail},
                            ];

                            return ListTile(
                              enabled: true,
                              selected: false,
                              tileColor: Colors.black,
                              leading: Icon(Icons.person),
                              title: Text('Name'),
                              subtitle: Text('Email'),
                              
                              /*title: Text("Name: " +
                                  //    userList.data.docs[index].get('name')),
                                  userList.data.docs[index]['name'].toString()),
                              subtitle: Text("Email: " +
                                  userList.data.docs[index].get('email')),
                              // userList.data.docs[index]['email'].toString()),*/
                              
                              onTap: () {
                                showModalBottomSheet(
                                  context: context,
                                  builder: (context) => Container(
                                    height: 500,
                                    child: Padding(
                                      padding: const EdgeInsets.all(20.0),
                                      child: Table(
                                        border: TableBorder(
                                            horizontalInside:
                                                BorderSide(width: 1)),
                                        children: _tableData.map((data) {
                                          return TableRow(
                                            children: [
                                              Container(
                                                padding: EdgeInsets.all(8.0),
                                                child: Text(data['id']),
                                              ),
                                              Container(
                                                padding: EdgeInsets.all(8.0),
                                                child: Text(data['content']),
                                              ),
                                            ],
                                          );
                                        }).toList(),
                                      ),
                                    ),
                                  ),
                                );
                              },
                            );
                          },
                        );
                      } else {

                        return Center(
                          child: CircularProgressIndicator(),
                        );
                      }
                    }),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Firestore rules:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

FireStore Index enter image description here

I feel code-blinded and cant find the basic mistake i am relying on. Help much appreciated.

Kind regards


Solution

  • your settings field is a collection not a document,

    so these two lines in your code are referring to the data that you want:

       .doc('settings')
       .collection('userSettings')
    

    they should be the opposite, like:

      Future<DocumentSnapshot> getUserList() async {
        return userList = await FirebaseFirestore.instance
            .doc('users/[email protected]/settings/userSettings')
            .get();
      }
    

    the previous code would return the document "userSettings"