将文档与其子集合中的文档合并

时间:2018-07-14 12:12:58

标签: angular typescript google-cloud-firestore

我在firestore下有一个具有以下结构的数据库:

->聊天室    ->用户

我有一个“聊天室”(ChatRoom)集合,其中包含一个“用户”(Users)集合。在用户集合中,每个文档都包含“ read:true / false”字段,以了解用户是否已阅读会议室中的消息。

要检索当前用户的房间,请使用以下代码:

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$;
 }

要从“用户”子集合中恢复数据,我使用以下代码行:

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

我想检索一个包含房间数据和每个房间“ read:true / false”的对象,我认为使用可观察对象是可行的,但我不知道该怎么做。您有解决方案的想法吗?

1 个答案:

答案 0 :(得分:0)

我终于明白了。为了将用户子集合链接到会议室文档,链接到CombineLatest运算符的mergeMap运算符允许知道相关用户是否阅读了会议室消息。

   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;
            })
          );
        })
        );
      })
    );