Angular Firebase listen to foreach changes with subscribe

爱⌒轻易说出口 提交于 2019-12-20 06:29:56

问题


I am subscribing to get user chats and then for each chat, I am subscribing to two other observables.

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

}

Now for the front end, I am displaying the data like this:

<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>

This is working except that chat last message won't update automatically in the front end, I understand why this isn't working, I am pushing the observer into an array which loses the function to listen to changes, but I couldn't figure out how I can listen to changes without pushing the objects from two different subscribers and display them correctly. I basically have to reload the chat list every time to see the change.

It's better explained with pictures:

Last message for Holly is 'a'

I send another message to Holly, the last message should now be 'B'

But last message won't update without refreshing the page, it's not listening to changes because I am pushing the observable into an array

Firebase realtime database structure for 1:1 chat

User 1:

User 2:

Chat Room:


回答1:


I highly recommend modeling each chat room as a collection in Firestore. That way, if you have a chat room/collection for the chat between Brendan and Holly, you're only reading from a single collection, instead of two. That also makes it much easier to keep the messages in the correct order, since you can use a single query to get them.

For an example of this see Best way to manage Chat channels in Firebase. While this question is about Realtime Database, the same logic can be applied to Cloud Firestore.



来源:https://stackoverflow.com/questions/54527049/angular-firebase-listen-to-foreach-changes-with-subscribe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!