13

My structure of Firestore database:

|
|=>root_collection
                  |
                  |=>doc1
                         |                  
                         |=>collection
                  |
                  |=>doc2
                         |                  
                         |=>collection
                  |
                  |=>doc3
                         |                  
                         |=>collection

Now I wanna get list of document from root_collection. There would be a list with following data {"doc1", "doc2", "doc3"}. I need it because I want to make a spinner and put these data in the spinner. Then a user would be choose some document and download it.

I try to use the code below:

firestore.collection("root_collection")
            .get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if (task.isSuccessful()) {
                        for (QueryDocumentSnapshot document : task.getResult()) {
                            Log.d(TAG,document.getId() + " => " + document.getData());
                        }
                    } else {
                        Log.d(TAG, "Error getting documents: ", task.getException());
                    }
                }
            });

But the code works only then I have structure of data without collections in the documents. In other case there aren't any documents in QueryDocumentSnapshot.

Thanks!

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Ivan Banha
  • 753
  • 2
  • 12
  • 23

2 Answers2

32

To have a list that contains all the name of your documents within the root_collection, please use the following code:

firestore.collection("root_collection").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) {
        if (task.isSuccessful()) {
            List<String> list = new ArrayList<>();
            for (QueryDocumentSnapshot document : task.getResult()) {
                list.add(document.getId());
            }
            Log.d(TAG, list.toString());
        } else {
            Log.d(TAG, "Error getting documents: ", task.getException());
        }
    }
});

The result in your logcat will be:

[doc1, doc2, doc3]

Remember, this code will work, only if you'll have some properties within those documents, otherwise you'll end ut with an empty list.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • 1
    I'm grateful for your support but unfortunately it doesn't work. There is no any document id in the list. As I figured out, if I add a field in these documents then I can get ids of documents. – Ivan Banha Apr 26 '18 at 18:03
  • 1
    Yes, that's correct. I assumed you have some fieds within those documents. Without having having some properties within those documents, you'll end ut with an empty list. Just updated also my answer. – Alex Mamo Apr 27 '18 at 11:41
  • 1
    Worked perfectly in my case I wanted to select only one title from the array and I filtered appropriately using ``` if (list.contains(documentName)){ //My action } ``` – Zephania Mwando Jul 03 '20 at 13:57
  • @SatyamGondhale Good to hear that, Satyam. – Alex Mamo Mar 05 '21 at 16:12
3

You can call collection method to get documentin the root_collections then hold documents ID which will be used to get document's collection later.

create root collection object as:

    data class RootCollection(
        @DocumentId val id: String,
        val sampleField: String?
    ) {
       // empty constructor to allow deserialization
       constructor(): this(null, null)
    }

Then get the collection using FirebaseFirestore method collection as follows:

    val querySnapshot = firestore.collection("root_collection")
                .get()
                .await()
    if(!querySnapshot.isEmpty) {
             Result.SUCCESS(querySnapshot.toObjects(RootCollection::class.java))
     } else {
         Result.ERROR(Exception("No data available"))
    }

Then to get collection in the document call

    firestore.collection("root_collection/$documentId/collection") 

Note that I have use kotlin coroutines await method as describe in this link

The Result class am using to save state of returned data and handle errors.

   sealed class Result<out T: Any> {
      data class SUCCESS<out T: Any>(val data: T) : Result<T>()
      data class ERROR(val e: Exception): Result<Nothing>()
      object LOADING : Result<Nothing>()
   }
Mihango K
  • 101
  • 1
  • 1
  • 7