3

I have a Firestore database structure like this:

Songs:
    - song1
         - artistName
         - songCover 
    - song2
    - song3

I want to be able to grab all the users that have favorited an specific song

In the past I made an structure like the following

FavoriteSongs
     - IDSong1
            - userID1 (with favorited the song)
                - artistName
                - songCover
            - userID2
Songs:
     - song1
       - artistName
       - songCover

In the previous structure, I made an exact copy of each song inside a user's id node. However, when a song changes its cover, this forces me to change every document inside the FavoritedSongs where the ID of the song that changes matches the IDSong key of FavoriteSongs.

Reading about collection group queries, I thought I could do something like this:

Songs:
        - song1
             - artistName
             - songCover 

             -> Favorited (Subcollection):
                   - userID1

        - song2
        - song3

This wat I could retrieve all the songs that a particular user has favorited, and I could get the song with all the updated values, since changing the cover of a song will only affect one document.

Is this possible, and if so, how can I write the query?

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
Andrey Solera
  • 2,311
  • 2
  • 26
  • 51
  • Please check the duplicate. It is about the exact same "issue" that you are talking about. – Alex Mamo Sep 16 '19 at 13:46
  • 1
    @AlexMamo This question is asking how to write a collection group query given an existing database structure. I don't see that it's a duplicate. – Doug Stevenson Sep 16 '19 at 13:47
  • @DougStevenson Oh yes, you're right. I missed that line. Thanks for reopening the question. – Alex Mamo Sep 16 '19 at 13:50
  • @AlexMamo I don't understand the answer that was provided, since where exactly in the query `firestore.collectionGroup("favorited").where("favorited", "==", true)` do I specify the user on which I want to get their favorited songs. Also, does this query return me the `Song` document or the document inside the `Favorited` collection? – Andrey Solera Sep 16 '19 at 15:01
  • 1
    @Andrea I think you should ask Doug about that. Sorry for closing the question earlier. I'm missed that part with collection group query. – Alex Mamo Sep 16 '19 at 15:04

1 Answers1

3

If you want to write a collection group query that finds documents among subcollections (named "favorited") where some document property (also "favorited") is true:

firestore.collectionGroup("favorited").where("favorited", "==", true)

Each user would need to be able to write their own document in the subcollection with an ID the same as their UID in order to set this boolean property. So, to mark a favorite, a user would:

firestore
    .collection("songs")
    .doc(songId)
    .collection("favorited")
    .doc(userId)
    .set({ favorited: true })
Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • Quick questions, does the previous scheme returns me the list of songs that the user have favorited, or does it return me the document from the Favorited collection? And where in the query do I restrict only to get the favorite songs by an specific user? – Andrey Solera Sep 16 '19 at 14:53
  • Each document found will have in its fully path the ID of the song that was favorited. You can extract it from there by looking at the reference of the document. – Doug Stevenson Sep 16 '19 at 15:17
  • If you want to restrict by user, you will have to also put the user id as a field in the document, and add that to a where clause. – Doug Stevenson Sep 16 '19 at 15:17