'Why is data retrieved from Firestore returning empty array when there are subcollections present?

I am trying to retrieve data from my the my firestore database using angularfire2. This is what my current database looks like. I have a users collection that contains the userId doc which binds the userDetails and userPosts together. enter image description here

However when I query this collection, it returns an empty array in the console.

enter image description here

I am using a firebase function to retrieve the data.

Firebase Function Index.ts

export const getFeed = functions.https.onCall(async (req,res) =>{
  const docs = await admin.firestore().collection('users').get()
    return docs.docs.map(doc => {
    return {
        postID: doc.id,
        ...doc.data()
         }
     }) 
 })

TS File

  tabTwoFeedInit (){    
      const getFeed = this.aff.httpsCallable('getFeed')
      this.ajax = getFeed({}).subscribe(data=> {
        console.log(data)
        this.posts =  data 
          })  
      }

How can I retrieve data from this firebase database successfully?



Solution 1:[1]

Firestore reads are shallow, and so they won't return subcollections automatically. Thus, your get() will only return the document ID, since the document has no fields.

To return the subcollections of a document, you need to call the getCollections method on that document. This can only by done by the admin API, but that should be fine for you since you are running inside a cloud function. As the documentation notes, it is generally expected that collection names are predictable (as they appear to be in your case), but if they aren't, you might consider restructuring your data.

Why are shallow reads desirable? It makes it possible to avoid retrieving potentially large collections of information that might be associated with, say, a user, so you can structure data more naturally. Depending on the size of the data, its possible that a field that is a map might make more sense for userDetails (but a collection is probably the right thing for userPosts).

Solution 2:[2]

If you are just creating the cloud function to retrieve the posts from this structure. I would prefer to restructure the database a bit and just use Collection Group Query on client side (with no requirement of cloud functions) to pull the posts.

By restructuring I mean, you should store userID inside the documents of userPosts sub collection.

Then simply user Collection Group Query to retrieve post of specific users.

The syntax is of firebase javascript library. You can find it's equivalent of angularfire

let posts= db.collectionGroup('userPosts').where('userId', '==', 'some-user-id');

Solution 3:[3]

I also ran into the same problem but I solved it by adding a field to the particular document i am trying to retrieve.Sometimes the cause is because the documents you are trying to get has no field in it. What I mean is that a document must have a field before the server can recognize it as an existing document. Possibly there may be no field in the document you are trying to retrieve which makes tye server say it is not existing and so will not be retrieved. So if you run into this problem, then consider adding a field to that document before you can successfully retrieve it.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Sanket Patel
Solution 3 cigien