Javascript Angular Firebase使用subscribe侦听foreach更改

Javascript Angular Firebase使用subscribe侦听foreach更改,javascript,firebase,firebase-realtime-database,observable,angularfire,Javascript,Firebase,Firebase Realtime Database,Observable,Angularfire,我订阅用户聊天,然后每次聊天,我订阅另外两个观察 get_user_chat(chat) { let user = this.firebase.get_user_by_uid(chat.key).snapshotChanges(); let chatInfo = this.firebase.get_single_chat(chat.payload.val()).snapshotChanges(); return Observable.forkJoin(user.take(

我订阅用户聊天,然后每次聊天,我订阅另外两个观察

get_user_chat(chat) {
    let user = this.firebase.get_user_by_uid(chat.key).snapshotChanges();
    let chatInfo = this.firebase.get_single_chat(chat.payload.val()).snapshotChanges();
    return Observable.forkJoin(user.take(1), chatInfo.take(1));
}

getChats() {
//start loading
let loading = this.loadingCtrl.create();
loading.present();

//get chats
this.firebase.get_user_chats().snapshotChanges().takeUntil(this.ngUnsubscribe).subscribe(chats => {
  chats.forEach(chat => {
    this.get_user_chat(chat).takeUntil(this.ngUnsubscribe).subscribe(userChat => {
      this.userChat = userChat;
      this.user = this.userChat[0];
      this.chat = this.userChat[1];

      this.chats.push({
        firstName: this.user.payload.val().firstName,
        imageUrl: this.user.payload.val().imageUrl,
        uid: this.user.key,
        chatId: chat.payload.val(),
        last_message: this.chat.payload.val().last_message.message,
        type: this.chat.payload.val().last_message.type
      })
    })
  })
  //dimiss loading
  loading.dismiss();
}, err => {
  //dimiss loading
  loading.dismiss();
})
}

现在对于前端,我显示如下数据:

<ion-content>
  <ion-list class="chat-list" *ngIf="(chats)?.length>0">
    <a ion-item detail-none *ngFor="let c of chats" (click)="toChat(c.chatId, c.uid)">
      <ion-thumbnail item-start>
        <img-loader class="img-logo" src={{c.imageUrl}} fallbackUrl="assets/img/placeholder-person.png" useImg></img-loader>
      </ion-thumbnail>
      <h2>{{c.firstName}}</h2>
      <h3 *ngIf="c.type!='img'">{{c.last_message}}</h3>
      <img class="img-placeholder" *ngIf="c.type=='img'" src="assets/img/placeholder-image.png">
      <!-- <ion-icon item-right name="ios-arrow-forward"></ion-icon> -->
    </a>
  </ion-list>
  <ion-card *ngIf="(chats)?.length==0">
    <ion-card-content>
      You don't have any chats.
    </ion-card-content>
  </ion-card>
</ion-content>

我给Holly发了另一条信息,最后一条信息现在应该是“B”

但最后一条消息不会在不刷新页面的情况下更新,它不会监听更改,因为我正在将可观察对象推入数组中

用于1:1聊天的Firebase实时数据库结构

用户1:

用户2:

聊天室:

我强烈建议将每个聊天室建模为Firestore中的一个集合。这样的话,如果你有一个聊天室/收藏用于Brendan和Holly之间的聊天,你只能阅读一个收藏,而不是两个。这也使得以正确的顺序保存消息变得更加容易,因为您可以使用单个查询来获取它们


有关此示例,请参见。这个问题是关于实时数据库的,同样的逻辑也可以应用到云Firestore。

我想我也做过类似的事情,用户聊天时使用聊天用户id作为键,聊天室键作为值,但是您仍然需要从“用户”获取用户信息,从“聊天室”获取聊天信息,因为这只是键和值,没有其他信息。否则,我必须将这些信息(聊天名字、最后一条消息)放入用户聊天中,当用户更改名字或最后一条消息时,我必须更新几个位置,这在firebase中很好,我理解,但它变得复杂得多,我已经更新了我的问题。这种结构实际上让我很困惑,你如何在不打另一个电话获取用户名、性别等用户信息的情况下获取用户信息,列表中只包含以true为值的用户ID。如果你有用户信息和聊天信息,您通常会保留两个顶级列表:一个用于用户信息,另一个用于聊天信息。您需要进行客户端连接,以获取用户信息。您还可以将一些用户信息复制到每个聊天信息中,或者在另一个顶级列表中设置一个单独的节点,其中包含聊天室的所有元数据。但最重要的是,您的聊天信息存储为单个列表,这样您就不会试图分别加载来自每个用户的信息。从扫描数据模型来看,您似乎在试图显示每个聊天室中的最新信息。这应该通过每个聊天室上的
limitToLast()
侦听器来完成,或者将每个聊天室的最后一条消息也保留在“聊天室元数据”中。后者在写操作上更复杂,但使读取更简单,因为您只需要一个侦听器,因此不需要(失败的)合并两个列表。推荐非现场资源无论如何都是离题的,这就是为什么我在上一篇评论中给了您最常用的选项。