1
votes

I have a database under firestore with the following structure:

-> Chat Room -> Users

I have a "ChatRoom" collection that contains a "Users" collection. In the users collection each document contains the field "read: true/false" in order to know if the user has read the messages that are in the room.

To retrieve the rooms of the current user I use this code:

getRoomFromUserId(userId: string) {
    let rooms$: Observable<any>;
    let rooms: AngularFirestoreCollection<any>;

    rooms = this.afs.collection('ChatRoom', ref => {
      return ref.where('Chatter.' + userId, '==', true);
    });


    rooms$ = rooms.snapshotChanges().map(changes => {
      return changes.map(a => {
        const data = a.payload.doc.data();
        const id = a.payload.doc.id;
        return {id, ...data};
      });
    });

    return rooms$;
 }

To recover data from the "Users" subcollection I use this line of code:

this.afs.collection('ChatRoom').doc(RoomID).collection('Users').doc(UserId);

I'd like to retrieve an object that contains the room data and the "read: true/false" for each room I think it's possible with observables but I don't know how to do it. Do you have any ideas for a solution?

1

1 Answers

0
votes

I finally figured it out. To link the users sub-collections to the room document the mergeMap operator linked to the combineLatest operator allows to know if the user in question read the room messages.

   let rooms: AngularFirestoreCollection<any>;

    rooms = this.afs.collection('ChatRoom', ref => {
      return ref.where('Chatter.' + userId, '==', true);
    });

    let readRoom$: Observable<any>;
    let readRoom: AngularFirestoreCollection<any>;

    return rooms.snapshotChanges().pipe(
      mergeMap(changes => {
        return Observable.combineLatest(changes.map(a => {
          const data = a.payload.doc.data();
          const id = a.payload.doc.id;
          let roomReturn = {id, readMessage: '', photoProfile: '', ...data};

          readRoom = this.afs.collection('ChatRoom').doc(id).collection('Users');
          readRoom$ = readRoom.snapshotChanges();

          return readRoom$.pipe(
            map(userInRoom => {
              userInRoom.map(userList => {
                if (userList.payload.doc.id === userId) {
                  roomReturn.readMessage = userList.payload.doc.data().ReadMessage;
                } else {
                  roomReturn.photoProfile = userList.payload.doc.data().PhotoProfile;
                }
              });

              return roomReturn;
            })
          );
        })
        );
      })
    );