skip to Main Content

I’m trying to implement a chat functionality using Angular Firestore and Firebase in an app and I get all the messages using an observable. Getting all the messages works fine but as soon as I send a new message or receive a message in the chat the screen goes all the way up and gets locked there.

This is the code in my chat service to get the messages:

  getMessages(id){
    return this.afs.collection<any>(`chats/${id}/messages`,   ref => ref.orderBy('createdAt','asc').limitToLast(20)).valueChanges()
  }

This is the TS:
getMessages(){this.user$ = this.cs.getMessages(this.chatID)}

And it’s displayed in the HTML using an async pipe:

<ion-row class="ion-align-items-center" *ngFor="let message of user$ | async;">
....
</ion-row>

This is how it looks in the app when sending a message

I made a function to scroll down the view when entering the view or sending a message:

  sendChatMessage(msg){
    return this.afs.collection(`chats/${this.chatID}/messages`).add({
      msg: msg,
      from: this.uid,
      fromName: this.myName,
      createdAt: firebase.firestore.FieldValue.serverTimestamp()
      
    })
  }


  submit() {
    this.sendChatMessage(this.newMsg).then(()=>{
      this.newMsg = '';
     this.scrollToBottom(100,100)
    });
  }


  scrollToBottom(delay, time){
    setTimeout(() => {
      this.myContent.scrollToBottom(time);
   }, delay);
  }

This is what it looks like with the scrollToBottom function

I would like it so that the view is stuck on where the user was when submitting the message or that it only scrolls down to latest message without scrolling up first. Any ideas how to fix this?

This is also what it looks like when receiving message from others(no scrolldown)

This makes the whole receiving of new messages messy because if you are scrolling through the chat and receive a new one the user will be transported automatically to the top of the screen.

I’ve tried changing the way I get the message from Firebase ( removing limit of 20), changing from valuechanges etc. I’m not sure what it is that’s causing the behaviour.

I’ve also tried locking the view but it only works for one message then it goes back to previous behaviour.

2

Answers


  1. Chosen as BEST ANSWER

    I got some help from a user on reddit:

    I think what might be happening is that when a new message is sent, the value of user$ is a new array reference -- which causes the list to scroll up while all of the message items are recreated. To avoid this you can define a TrackByFunction so that Angular only creates items that are new.

    I added a TrackByFunction to my code:

      <ion-row class="ion-align-items-center" *ngFor="let message of user$ | async; trackBy: trackByFn">
        ....
      </ion-row>  
    
    
      trackByFn(message) {
        return message.id;
    

    This solved my issue on this project.


  2. How is your CSS? It seems me you have some CSS activating the scroll to up. Please, try to change your CSS from the messages container like this:

    .messages-container {
        width: 100%;
        display: flex;
        min-height: 100%;        
        position: relative;        
        overflow: hidden;
        margin: 0 auto;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search