0
votes

Let's have a biz model defined like this

export inteface Item {
    id: string;
    name: string;
}

export interface Container {
    id: string;
    items: Item[];
}

In Cloud Firestore we have collection /containers and each container contains collection /items with documents. Each document has field name. So the structure inside Cloud Firestore copies our biz model.

Now I'd like to retrieve specific container with its collection of items.

getContainer(idIn: string) {
  const document: AngularFirestoreDocument<Container> = this.afs.doc('containers/' + idIn);
  const document$: Observable<Container> = document.snapshotChanges().map(a => {
      const data = a.payload.data() as Container;
      const id = a.payload.id;
      return this.getItems(idIn).map( item => {
        return {id, ...data, items: item};
      });
    });
  return document$;
}

getItems(id: string) {
  const collection: AngularFirestoreCollection<Item> = this.afs.collection('containers/' + id + '/items');

  return collection.snapshotChanges().map(actions => {
    return actions.map(a => {
      const data = a.payload.doc.data() as Item;
      const id = a.payload.doc.id;
      return {id, ...data};
    });
  });
}

But i keep getting this error about missing id on returning Observable. Compiling with typescript 2.6.2.

error TS2322: Type 'Observable<Observable<{ items: { 'id': string;  'item': string; }[]; 'id': string...' is not assignable to type  'Observable<Container>'.
 Type 'Observable<{ items: { 'id': string; 'item': string; }[]; 'id': string...' is not assignable to type 'Container'.
 Property ''id'' is missing in type 'Observable<{ items: { 'id': string; 'item': string; }[]; 'id': string...'.

Could anyone point out what i am doing wrong?

2

2 Answers

1
votes

It looks to me your return data is not same as the Interface modal. You only specified id and items fields in the interface, so it will be

  const data = a.payload.data() as Container;
  const id = a.payload.id;
  let items=[];
  this.getItems(idIn).valueChanges().subscribe(res=>{
      res.forEach(item=>{
        items.push(item);
      })
    });
  return {id:id, items: items};
0
votes

I am reading nested collections in Firestore to populate in my case an Expansion widget. See my solution in https://stackoverflow.com/a/51057195/5013735

The trick is in to create a structure like:

  List<Widget> _getChildren() {
    List<Widget> children = [];
    documents.forEach((doc) {
      children.add(
        ProjectsExpansionTile(
          name: doc['name'],
          projectKey: doc.documentID,
          firestore: firestore,
        ),
      );
    });
    return children;
  }