0

i have a firestore database in which i have "Singer" then inside every singer there is a sub-collection of "Song List" for every singer. i am able to get data from main collection but not from sub-collection. can you guys help?

stream Builder

StreamBuilder(
        stream: Firestore.instance.collection('singers').snapshots(),

ListView.Builder

ListView.builder(
                itemCount: snapshot.data.documents.length,
                itemBuilder: (context, index) => SingleChildScrollView(

this is where i want to show data from sub-collection

Text(
                                  snapshot.data.documents[index]['name'],
                                  style: TextStyle(
                                      fontSize: 20, color: Colors.red[500]),
                                )

Databasedatabase main database sub

Mt Khalifa
  • 459
  • 1
  • 6
  • 20
  • 2
    Does this answer your question? [Firestore: Does querying a collection also includes their sub collection?](https://stackoverflow.com/questions/55632268/firestore-does-querying-a-collection-also-includes-their-sub-collection) – robsiemb Aug 06 '20 at 10:12

3 Answers3

2

You can get the data from the collection by accessing the subcollection inside the document like this

Firestore.instance.collection('singers').document('aryana sayeed').collection('song list').snapshots()

or

Firestore.instance.collection('singers/aryana sayeed/song list').snapshots()
JideGuru
  • 7,102
  • 6
  • 26
  • 48
  • thanks @jideguru. but it will read only one document. i want to stream a list from all of the documents – Mt Khalifa Aug 06 '20 at 14:31
  • You cannot get the subcollection of a document that way, you have to do the request separately – JideGuru Aug 06 '20 at 14:32
  • so there will be hundreds of them what you say is that i have to create a different page for everyone of them – Mt Khalifa Aug 06 '20 at 14:45
  • is there a way to instead of putting "aryana sayeed" put the document id – Mt Khalifa Aug 06 '20 at 15:59
  • I’m this case “aryana sayeed” is your document Id so you can replace it with other document id that you are using. I just used that as an example – JideGuru Aug 06 '20 at 16:12
2

You can read it like this:

Firestore.instance.collection('singers').snapshot().listen((val)=>{
       val.documents.forEach((doc)=>{
          doc.reference.collection('song list')
           .getDocuments().then((res)=>{
               res.douments.forEach((d)=>{
                       print(d.data);
                    })
              })
        })
    });

Now this gives you a stream to all docs of collection singers and thier subcollection

Habib Mhamadi
  • 729
  • 1
  • 6
  • 15
2

To clarify what you are saying: you want a list of all the songs from all the singers,

Easy-Peasy. CollectionGroup is your friend.

I don't use your environment, but I can see that:

StreamBuilder(
        stream: Firestore.instance.collectionGroup('song list').snapshots(),

is the start you need. collectionGroup treats all sub-collections with the name 'song list' as one collection.

NOTE (because this always comes up) Each documentSnapshot returned include a field 'refpath' - which is a string with the entire path to that specific document. You can trivially parse the string to find the parent document(s) or collections(s). For example, a particular song with have in it's refPath ".../singers/{singerID}/songlist/{songID}"

btw, I HIGHLY HIGHLY HIGHLY recommend AGAINST using the singer name as the document ID. Queries are generally of fields, not documentID's, so it won't help your code find the artist, and they are neither unique enough nor randomly distributed enough to be efficient. Let Firestore generate unique documentID's for you, and put the artist name in a field.

LeadDreamer
  • 3,303
  • 2
  • 15
  • 18
  • thanks for you attention. let me tell you.. you open the app.. you press on a button which have the label `Singers` it gives you a list of singers.... after that what i want is when you tap on a singer name it gives you a list of that singer's songs... – Mt Khalifa Aug 06 '20 at 16:13