Search code examples
angularfirebasegoogle-cloud-firestoreangularfire2

Join with object from a collection array result


I have 2 collections:

Users: uid, displayName.

Activities: documents that the user can create. It also contains userUid with their references to the Users collection

I get the activities like that:

this.activities = this.afs.collection<Activity>('activities')
 .snapshotChanges()
 .pipe(
   map((actions) => {
    return actions.map((a) => {
      const data = a.payload.doc.data();
      data.uid = a.payload.doc.id;
      return data;
    })
  }));

So, my question is how is the best way to join and get also the user data?

I tried like that:

actReference.snapshotChanges().pipe(
  map((actions) => {
    return actions.map((a) => {
      const actData = a.payload.doc.data();
      actData.uid = a.payload.doc.id;

      return this.userService.getUserDocById(actData.userUid).snapshotChanges()
        .pipe(
          map((userActions) => {
            const userData = userActions.payload.data();
            return { user: { uid: userData.uid, displayName: userData.displayName }, ...actData };
          }))
    })
  }));

But it returns me an

 Observable<Observable<Activity>[]>>

Solution

  • You need to apply rxjs pipe operator chaining.

    actReference.snapshotChanges().pipe(
      map((actions) => {
        actions.map((a) => ({
          let actData = a.payload.doc.data();
          actData.uid = a.payload.doc.id;
          actData.displayName = a.payload.doc.name;
          return actData;
        });
      }),
      map((userData) => {
          return this.userService.getUserDocById(actData.userUid).snapshotChanges()
            .pipe(
              map((userActions) => {
                const userData = userActions.payload.data();
                return { user: { uid: userData.uid, displayName: userData.displayName }, ...actData };
              }))
        })
      }));