Gabe
Gabe

Reputation: 6865

Querying Subcollection into Document with Firebase

I have an angular 8 typescript interface set up that includes an array of another interface as an variable. Looks like the following:

export interface User {
    name: string;
    id: string;
    history: Job[];  //this is what is not getting generated
}

and the Job interface looks like the following:

export interface JobJson {
    id: string;
    price: number,
    notes: string
}

I am using Firebase's Cloud Firestore as my database and the database structure looks like this:

users // collection

|--> user1234 // document

|--> jobs //subcollection

|--> job1234 // sub document

When I query a user from firebase:

this.firestore.collection<UserJson>('users').doc<UserJson>(id).valueChanges().subscribe((u) => {
    // do whatever with u
  });

it, as expected, does not fill out the history: Jobs[]. But, in my program I need to set user.history array to the subcollection under user in firebase. How can this be acomplished? Thanks for any help!

Upvotes: 1

Views: 1180

Answers (1)

Soni Sol
Soni Sol

Reputation: 2612

As far as I know there is no way of getting this in only one call to firestore. The closest is the two calls workaround if you know which collection, or three if you don't know the collection name.

Also here is the documentation and no method for documentReference gets the document snapshot and the collections.

I will add both workarounds in my case the code just prints in console the content.

Whithout Knowing the subcollection name: it gets all the subcollections and their elements:

db.collection('users').doc(str[6]).get().then(documentSnapshot => {
  console.log(documentSnapshot.data());
});

db.collection(COLLECTION_ID).doc(DOCUMENT_ID).listCollections().then(collections => {
  for (let collection of collections) {
    console.log(`Found subcollection with id: ${collection.id}`);
    collection.get().then((snapshot) => {
      snapshot.forEach((doc) => {
        console.log(doc.id, '=>', doc.data());
      });
    })
    .catch((err) => {
      console.log('Error getting documents', err);
    });
  }
});

Knowing the subcollection you want to get:

db.collection(COLLECTION_ID).doc(DOCUMENT_ID).get().then(documentSnapshot => {
  console.log(documentSnapshot.data());
});

db.collection(COLLECTION_ID).doc(DOCUMENT_ID).collection(SUBCOLLECTION_ID).get()
  .then((snapshot) => {
    snapshot.forEach((doc) => {
      console.log(doc.id, '=>', doc.data());
      console.log(doc.id, '=>', JSON.stringify(doc));
    });
  })

Upvotes: 1

Related Questions