Angular Firebase监听foreach的更改并订阅

时间:2019-02-05 02:34:14

标签: 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(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>

这是有效的,但是最后一个聊天消息不会在前端自动更新,我理解为什么它不起作用,我将观察者推入一个数组,该数组失去了侦听更改的功能,但是我无法没有弄清楚如何在不从两个不同的订户推送对象并正确显示它们的情况下侦听更改。我基本上必须每次都重新加载聊天列表才能看到更改。

最好用图片来解释:

霍莉的最新信息是“ a” Last message for Holly is a

我再次向Holly发送了一条消息,最后一条消息现在应该是“ B” I send another message, the last message should now be B

但是如果不刷新页面,最后一条消息将不会更新,因为我将可观察对象推送到数组中,所以它没有监听更改 But last message won't update without refreshing the page

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

用户1: enter image description here

用户2: enter image description here

聊天室: enter image description here

1 个答案:

答案 0 :(得分:1)

我强烈建议在Firestore中将每个聊天室建模为一个集合。这样,如果您有一个聊天室/收藏夹来与Brendan和Holly之间的聊天,则您只会从单个收藏夹中读取,而不是从两个收藏夹中读取。这也使将消息保持正确顺序变得容易得多,因为您可以使用单个查询来获取消息。

有关此示例,请参见Best way to manage Chat channels in Firebase。尽管此问题与实时数据库有关,但可以将相同的逻辑应用于Cloud Firestore。