SwiftUI中Firestore无法实时更新聊天消息问题求助
SwiftUI + Firestore 聊天消息无法实时更新问题
我在SwiftUI中通过Firestore获取聊天消息,发送或接收新消息后,必须重新加载ChatScreen才能看到更新。
试过两种方案:
- 用Realtime Database实现时,实时更新正常,但分页实现难度大且成本较高
- 将ChatViewModel的
@StateObject替换为@ObservedObject后,消息会在几秒后从滚动栏中消失
ChatViewModel 代码
class ChatViewModel: ObservableObject { @Published var messages: [Message] = [] let databaseRef = Database.database().reference() @Published var usersList: [userInfo] = [] func sendMessage(messageText: String, userId: String, userName: String, groupId: String) { let db = Firestore.firestore() let messageData: [String: Any] = [ "text": messageText, "userId": userId, "groupId": groupId, "userName": userName, "timestamp": Date().timeIntervalSince1970 * 1000 ] db.collection("groups") .document(groupId) .collection("messages") .addDocument(data: messageData) { error in if let error = error { print("Error adding message: \(error.localizedDescription)") } else { } } } func observeMessages(groupId: String) { let db = Firestore.firestore() let messagesRef = db.collection("groups").document(groupId).collection("messages").order(by: "timestamp", descending: true).limit(to: 25) messagesRef.addSnapshotListener{ querySnapshot, error in if let error = error { print(error) } DispatchQueue.main.async { querySnapshot?.documentChanges.forEach({ change in if change.type == .added { let data = change.document.data() self.messages.append(.init(documentId: change.document.documentID, data: data)) } }) } } } }
ChatScreen 代码
struct ChatScreen: View { @State private var message = "" var group: ChatGroup var userId: String @StateObject var chatViewModel = ChatViewModel() let db = Database.database().reference() @State private var goToUserListScreen = false init(group: ChatGroup, userId: String) { self.group = group self.userId = userId } var body: some View { ZStack{ VStack { ScrollView(.vertical, showsIndicators: true, content:{ LazyVStack{ ForEach(chatViewModel.messages) { message in MessageView(message: message, userId: userId).rotationEffect(Angle(degrees: 180)).scaleEffect(x: -1.0, y: 1.0, anchor: .center) } .padding(.horizontal) HStack{Spacer()} } }) .onAppear(){ chatViewModel.observeMessages(groupId: group.id) } .background(.opacity(0.05)) .frame(maxWidth: .infinity) .rotationEffect(Angle(degrees: 180)).scaleEffect(x: -1.0, y: 1.0, anchor: .center) .scrollDismissesKeyboard(.interactively) .toolbar(content: { ToolbarItem(placement: .principal) { Text(group.groupName) .bold() .onTapGesture { self.goToUserListScreen = true } } }) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Text("Test") } } HStack { TextField("Type your message here", text: $message) .textFieldStyle(RoundedBorderTextFieldStyle()) .controlSize(.large) Button { chatViewModel.sendMessage(messageText: message, userId: userId, userName: "Test", groupId: group.id) message = "" } label: { Image(systemName: "arrow.up.circle.fill") .foregroundStyle(message.isEmpty ? .gray : .blue) .font(.system(size: 30)) } .disabled(message.isEmpty) } .padding(.horizontal) .padding(.bottom, 7) .padding(.top, 1) } .navigationDestination(isPresented: $goToUserListScreen){ UserListScreen(group: group) } } } }
内容的提问来源于stack exchange,提问作者Deepanshu Kashyap
相关产品推荐
相关产品推荐

