Home > Back-end >  Repeated messages in chatView. how to clear view?
Repeated messages in chatView. how to clear view?

Time:10-13

  • I have a chatView with a list of chatRow Views (messages)
  • each chatView has a snapshot listener with firebase, so I should get real time updates if I add a new message to the conversation

The problem I have is: when I add a new message my chatView shows ALL the messages I added before plus the new message, PLUS the same list again....if I add another message then the list repeats again

I assume I need to drop/refresh the previous views shown in the Foreach loop...how can I drop/refresh the view so it can receive refreshed NON repeated data?

struct ChatView: View {
    
    @EnvironmentObject var chatModel: ChatsViewModel
    
    let chat: Conversation
    let user = UserService.shared.user
    @State var messagesSnapshot = [Message]()
    
    @State var newMessageInput = ""
    
    var body: some View {
        NavigationView {
            VStack {
                ScrollViewReader { scrollView in
                    ScrollView {
                        
                        ForEach(chat.messages, id: \.id) { message in
                            if user.name == message.createdBy {
                                ChatRow(message: message, isMe: true)
                            } else {
                                ChatRow(message: message, isMe: false)
                            }
                        }
                        .onAppear(perform: {scrollView.scrollTo(chat.messages.count-1)})
                    }
                    
                }
                Spacer()
                
                //send a new message
                ZStack {
                    Rectangle()
                        .foregroundColor(.white)
                    
                    RoundedRectangle(cornerRadius: 20)
                        .stroke(Color("LightGrayColor"), lineWidth: 2)
                        .padding()
                    
                    HStack {
                        TextField("New message...", text: $newMessageInput, onCommit: {
                            print("Send Message")
                        })
                        .padding(30)
                        
                        Button(action: {
                            chatModel.sendMessageChat(newMessageInput, in: chat, chatid: chat.id ?? "")
                            print("Send message.")
                        }) {
                            Image(systemName: "paperplane")
                                .imageScale(.large)
                                .padding(30)
                        }
                    }
                }
                .frame(height: 70)
            }
            .navigationTitle("Chat")
        }
        
    }
}

function to add message to the conversation

func addMessagesToConv(conversation: Conversation, index: Int) {
        var mensajesTotal = [Message]()
        
        let ref = self.db.collection("conversations").document(conversation.id!).collection("messages")
            .order(by: "date")
            .addSnapshotListener { querySnapshotmsg, error in
            
            if error == nil {
                //loop throug the messages/docs
                for msgDoc in querySnapshotmsg!.documents {
                    var m = Message() //emtpy struc message
                    m.createdBy = msgDoc["created_by"] as? String ?? ""
                    m.date = msgDoc["date"] as? Timestamp ?? Timestamp()
                    m.msg = msgDoc["msg"] as? String ?? ""
                    m.id = msgDoc.documentID //firebase auto id
                    
                    mensajesTotal.append(m) //append this message to the total of messages
                    self.chats[index].messages.removeAll()
                    self.chats[index].messages = mensajesTotal
                }
            } else {
                print("error: \(error!.localizedDescription)")
            }
        }
    }

CodePudding user response:

You've defined mensajesTotal outside of your snapshot listener. So, it's getting appended to every time.

To fix this, move this line:

var mensajesTotal = [Message]()

to inside the addSnapshotListener closure.

CodePudding user response:

You have two options:

  1. Clear mensajesTotal each time you get an update from the database, as @jnpdx's answer shows.

  2. Process the more granular updates in querySnapshotmsg.documentChanges to perform increment updates in your UI, as also shown in the documentation on detecting changes between snapshots.

There is no difference in the data transferred between client and server between these approaches, so use whatever is easiest (that'd typically be #1) or most efficient on the UI (that's usually #2).

  • Related