Search code examples
angularfirebasegoogle-cloud-firestoreangularfire2

Angularfire2 attach more data to user collection


I am creating an app where users can create groups. group collection is stored inside each user, and if owner of the group ads members corresponding users id and role only saved inside group collection. So when owner visits group members i wish to show full info of users which is in another collection out side groups.

these are two collections in my firestore database

this.afs.collection(`users/${ownerId}/groups/${gid}/users`)
this.afs.doc(`users/${ownerId}`) //full user data

here is how i access users in my services

getGroupUsers(gid, ownerId) {
return this.afs.collection(`users/${ownerId}/groups/${gid}/users`).snapshotChanges().pipe(
    map(actions => actions.map(a => {
      const data = a.payload.doc.data();
      const userId = a.payload.doc.id;
      return { userId, ...data };
    })
    )
  );
}

here userId is each users unique id and i wish to add more data to ...data object. I tried many ways and failed, here is what i try to achive

getGroupUsers(gid, ownerId) {
return this.afs.collection(`users/${ownerId}/groups/${gid}/users`).snapshotChanges().pipe(
  map(actions => actions.map(a => {
    const data = a.payload.doc.data();
    const userId = a.payload.doc.id;
    //return { userId, ...data };
    return this.afs.doc(`users/${userId}`).valueChanges().pipe(
      map(userData => {
        return {userId, ...data, ...userData}
      })
    )
  })
  )
);
}

I use angular 8.1.2 and Rxjs 6.4.0. Please help.


Solution

  • Not tested, but you can use a combination of mergeMap or switchMap and combineLatest. switchMap to switch to the inner observable and combineLatest to perform the nested requests.

    getGroupUsers(gid, ownerId) {
      return this.afs.collection(`users/${ownerId}/groups/${gid}/users`).snapshotChanges().pipe(
        switchMap(actions => combineLatest(
          actions.map(a => {
            const data = a.payload.doc.data();
            const userId = a.payload.doc.id;
            return this.afs.doc(`users/${userId}`).valueChanges().pipe(
              map(userData => {
                return { userId, ...data, ...userData }
              })
            )
          })
        ))
      );
    }