4

Each Notification ID collection contain only one document and I want to Iterate all the collections in ToseefShop1 and get the respective document name and fields data.

Data Model:

enter image description here Sub Collections:

enter image description here enter image description here Code:

dbRef.collection("Shop Notifications")
        .document("ToseefShop1")
        .get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
    @Override
    public void onSuccess(QuerySnapshot querySnapshot) {
        // Dont know what to do
    }
});

It's not a duplicate question. The other question (someone suggested as duplicate to) is about javascript and answers are for Node.js. With no answer accepted. Infact I can not find getcollections() method in firestore Java.

Cœur
  • 37,241
  • 25
  • 195
  • 267
MakesReal
  • 348
  • 5
  • 19
  • 1
    Are the names of the sub-collections always the same, i.e. ‘Notification ID:0’ and Notification ID:1’? – Renaud Tarnec Sep 03 '18 at 19:03
  • No they would be different every time. – MakesReal Sep 03 '18 at 21:02
  • 3
    As Doug Stevenson pointed out (via marking the question as duplicate) there is no way (with the Android/iOS/JavaScript SDKs) to get the list of (sub)-collections of a document. You **have to** know the collections' identifiers in order access them. One workaround could be to maintain a list of sub-collections' identifiers in the parent document (e.g. as a field of type array). – Renaud Tarnec Sep 04 '18 at 06:40
  • Late, but you would destroy this, if you were willing to do it in Firebase RealTimeDb ;-) – Yo Apps Apr 03 '20 at 16:44

3 Answers3

6

There is no way in Firestore to query a document to get the subcollections beneath it. In order to get the document name and fields data that you are asking for, first you need to have the names of subcollections and then use them in a reference. If you have only 2 subcollections, I suggest you to use the following code:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
Query firstQuery = rootRef
    .collection("Shop Notifications")
    .document("ToseefShop1")
    .collection("Notification ID:0");
Query secondQuery = rootRef
    .collection("Shop Notifications")
    .document("ToseefShop1")
    .collection("Notification ID:1");

Task firstTask = firstQuery.get();
Task secondTask = secondQuery.get();

Task combinedTask = Tasks.whenAllSuccess(firstTask, secondTask).addOnSuccessListener(new OnSuccessListener<List<Object>>() {
    @Override
    public void onSuccess(List<Object> list) {
         //Do what you need to do with your list
    }
});
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • I think I have to reconsider my schema design for what I want. thanks for reply :) – MakesReal Sep 04 '18 at 09:40
  • Is this the only way to do it ?? How to do if we have many sub collections ?? – K Pradeep Kumar Reddy May 08 '20 at 21:34
  • @user3410835 If you have more than two collections, you should use then pass a list of Task objects as explained in my answer from this **[this post](https://stackoverflow.com/questions/51892766/android-firestore-convert-array-of-document-references-to-listpojo/51897261)**. – Alex Mamo May 09 '20 at 04:03
  • So to have sub-collections, we need to have an array field in top level collections and this array field should have document references to sub-collections, right ?? Problem with using array field is once we create the array, later we can not more add items to the array. Once array is created, its size is fixed. so we can not add more sub collections later. To solve this problem, i'm creating one field for each sub-collection and that field will store the name of corresponding sub-collection. Is this the right approach ?? – K Pradeep Kumar Reddy May 12 '20 at 06:28
  • @user3410835 I'm afraid I did not understand your question. I suggest you post a new question using its own [MCVE](https://stackoverflow.com/help/mcve), so I and other Firebase developers can help you. – Alex Mamo May 12 '20 at 09:23
  • @Alex Mamo, This question and my question are same. I have many sub-collections under a top level collection and i want retrieve all the sub-collections. As you redirected me to another post for more than 2 sub-collections case, there he is using array field for storing document references. – K Pradeep Kumar Reddy May 14 '20 at 11:43
  • @user3410835 The idea behind that answer is to see how you can use a List not only two Task objects. – Alex Mamo May 14 '20 at 12:25
3

There is no way (with the Android/iOS/JavaScript SDKs) to get the list of (sub)-collections of a document. You have to know the collections' identifiers in order to access them.

From the comments attached to the question I understand that the sub-collection identifiers will be different for each document (and probably their number too). Therefore, one workaround could be to maintain a list of sub-collections' identifiers in the parent document (e.g. as a field of type array).

Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
0

You can use a Cloud Function to list all the subcollections of a given document.

Read Approach #2: Use a Cloud Function

At the middle of the page.

Approach #1: Save the list in a dedicated field of the parent document

Is very similar to the other answers here, but you probably want the second approach much more than the first approach, because the second approach is much more efficient, productive, cheaper and your database is much more easier to maintain than the first approach.