36

Screenshot of my database as requestedI'm working on an app that uses a firestore database with the following hierarchy: parent_collection: parent_document: subcollection: child_document{ string name} using collectionGroup I've been able to query subcollection for documents with a certain name, but I don't know how to get the parent_document

 db.collectionGroup("subcollection").whereEqualTo("name", searchText).get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if(task.isSuccessful()){
                          //here I want to get the parent id of all results
                        }
                    }
                });

What is the best way to achieve that?

Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
Ahmed Nabil
  • 581
  • 1
  • 7
  • 26
  • it'll be helpful if you attach screenshot of database – Mr. Patel May 20 '19 at 11:00
  • How do you get to subcollection if you don't know parent since path to subcollection is `/collection/{parent_id}/subcollection`? – TheKarlo95 May 20 '19 at 11:20
  • Instead of describing how you database looks like, please add a screenshot of it and please indicate the exact data that you want to get. Please also responde with @AlexMamo – Alex Mamo May 20 '19 at 11:20
  • I add a screenshot as requested, I just wanted the question to be more general. – Ahmed Nabil May 20 '19 at 11:31
  • Does this answer your question? [Firestore query subcollections](https://stackoverflow.com/questions/46573014/firestore-query-subcollections) – Eduardo May 15 '20 at 17:40

4 Answers4

67

The QuerySnapshot points to a number of QueryDocumentSnapshot instances.

From a QueryDocumentSnapshot, you can get the collection it's from with:

snapshot.getRef().getParent()

And then the parent DocumentReference is:

snapshot.getRef().getParent().getParent()

So to get a subscollection of the parent document with:

snapshot.getRef().getParent().getParent().collection("name_of_subcollection")

Yes, I agree... that could've been a bit more readable. :)

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thank you, that's it. I believed there must be a simple solution for it and here it's. – Ahmed Nabil May 20 '19 at 15:03
  • 1
    I usually am pretty good at getting things from the reference docs, but this time I had to ask around. All the `getBla` was getting in my way. :) – Frank van Puffelen May 20 '19 at 15:20
  • Yeah, it's a bit tricky =D. I couldn't find it on my own too. – Ahmed Nabil May 20 '19 at 15:26
  • does this only work for android development? It seems not to work with javascript.. Is there a way to get this in javascript? – dcts Jul 31 '19 at 17:09
  • 6
    It should work very similarly in JavaScript. Something like `snapshot.ref.parent.parent.collection("name_of_subcollection")`. It's mostly a matter of following the trail in the reference docs, starting with [`DocumentSnapshot`](https://firebase.google.com/docs/reference/js/firebase.firestore.DocumentSnapshot). If you're having a hard time making it work, you might want to post new question showing what you tried (see [how to create a minimal, complete, verifiable example](http://stackoverflow.com/help/mcve)), and linking back to this question/comment for reference. – Frank van Puffelen Jul 31 '19 at 19:50
  • FWIW, this syntax worked for me (Nodejs v14.3+): `snapshot.ref.parent.parent` – kip2 Sep 06 '20 at 20:23
0

You can write like this

List<DocumentSnapshot> documentSnapshotList = value.getDocuments();
                for (DocumentSnapshot documentSnapshot : documentSnapshotList) {
                    DocumentReference dr = documentSnapshot.getReference().getParent().getParent();
                    // or any field documentSnapshot.get(field);
                    assert dr != null;

                  ));
                } //for end
0

In case you use stream:

docs = db.collection_group(u'collection_name').stream()
for doc in docs:    
        path = doc.reference.path # will get you the full path
        # then you can manage the path as string
        sub_path = path.split('/')[1]
-1

You can get documents of a collection like this:

if(task.isSuccessful()) {
        List<DocumentSnapshot> documents = task.getResult().getDocuments();
        for(DocumentSnapshot documentSnapshot : documents) {
            documentSnapshot.getId();
            // or any field documentSnapshot.get(field);
        }
}
P.Juni
  • 2,365
  • 14
  • 26