Eben Oasis
Eben Oasis

Reputation: 187

Query documents in a Firestore subcollection based on a field in the parent document

My app has a collection(users) and a subcollection (Documents). The 'user' collection has the usual user's info including the field 'Status'. The status is dynamic though. It can be 'Not verified', 'pending verification', or 'verified'.

The 'Document' subcollection has all info from the user plus additional field 'document' where the user sends his document for verification. Currently the admin accesses the list of 'Document' field directly. However I want him to access it if and only if the field 'Status' in the 'user' collection is 'pending verification'. I don't know how to do that. Any help?

This is how the admin panel accesses the main collection 'users' users on a screen.

QueryDocumentSnapshot<Map<String, dynamic>>? selectedUser;
StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
                
                stream:
                    FirebaseFirestore.instance.collection('users').snapshots(),
                builder: (context, snapshot) {
                  if (snapshot.hasData) {
                    return ListView.builder(
                      itemCount: snapshot.data!.docs.length,
                      itemBuilder: (context, index) {
                        return Card(
                          child: ListTile(
                            onTap: () {
                              setState(() {
                                selectedUser = snapshot.data!.docs[index];
                              });
                            },
                            title: Text(
                              snapshot.data!.docs[index].get('Status'),
                            ),
                          ),
                        );
                      },
                    );
                  }
                  if (snapshot.hasError) {
                    return const Text('Error');
                  } else {
                    return const Center(child: Text('Do requests yet'));
                  }
                },
              ),

And this is how the admin panel accesses the subcollection 'Document' on a different screen: but I want access it only if the 'status' field in the 'user' collection is 'pending verification'.

QueryDocumentSnapshot<Map<String, dynamic>>? pendingVerifications;
StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
          stream: FirebaseFirestore.instance
              .collectionGroup('Documants')
              .snapshots(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return ListView.builder(
                itemCount: snapshot.data!.docs.length,
                itemBuilder: (context, index) {
                  return Card(
                    child: ListTile(ElevatedButton( onPressed: () {}, child: const 
                 Text('Approve')),
                   )

Upvotes: 2

Views: 678

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 600006

Firestore queries can only order and filter based on the data that is inside the documents it returns.

While is is possible to query across all collections named Documents with a collection group query, there is no way for Firestore to filter those documents based on a value in the user document.

Your options are:

  • Duplicate the data from the parent user document into each document in the Documents subcollection. This is the most common solution, although it may not be ideal if the status value is volatile.
  • First perform a query to get the list of applicable users, and then query the Documents subcollection for each of them in turn.

Both of these have advantages and this advantages, so you'll have to decide for yourself what will work best for your app.

Upvotes: 3

Related Questions