- 我有一个chatView与chatRow视图(消息)列表
- 每个chatView都有一个firebase快照监听器,所以我应该得到实时更新,如果我添加一个新的消息到对话
我遇到的问题是:当我添加新消息时,我的chatView显示我之前添加的所有消息,再加上新消息,再加上相同的列表....如果我添加另一条消息,那么列表将再次重复
我假设我需要删除/刷新Foreach循环中显示的先前视图…我怎么能下降/刷新视图,使其可以接收刷新的非重复数据?
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")
}
}
}
向对话中添加消息的函数
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)")
}
}
}
您已经在快照侦听器之外定义了mensajesTotal
。它每次都会被附加到
要解决这个问题,移动这一行:
var mensajesTotal = [Message]()
to insideaddSnapshotListener
闭包
您有两个选择:
-
每次从数据库获得更新时清除
mensajesTotal
,如@jnpdx的答案所示。 -
在
querySnapshotmsg.documentChanges
中处理更细粒度的更新,以在UI中执行增量更新,正如关于检测快照之间变化的文档中所示。
这些方法在客户端和服务器之间传输的数据没有区别,所以在UI上使用最简单的方法(通常是#1)或最有效的方法(通常是#2)。