Swift使用firebase在聊天中显示上次发送的消息

我试图在聊天信使的主屏幕上显示我上次发送的消息,从故事板看起来像: 在此处输入图像描述

我使用的代码是:

func getAllMsg() { self.users = [] let fromId = Auth.auth().currentUser!.uid let ref = Database.database().reference().child("privateMessages").child(fromId) ref.observeSingleEvent(of: .value) { (snapshot) in for snap in snapshot.children.allObjects as! [DataSnapshot] { // retrieving receiver's ID let chatUserID = snap.key let ref2 = Database.database().reference().child("users").child(chatUserID) // to retrieve message ID ref2.observeSingleEvent(of: .value, with: { (snapshot2) in let newUser = User(dictionary: snapshot2.value as! [String: AnyObject]) // to get the last message ref.child(chatUserID).queryLimited(toLast: 1).observeSingleEvent(of: .value, with: { (snapshot3) in let value = snapshot3.children while let rest = value.nextObject() as? DataSnapshot { newUser.lastMessage = (rest.value as! [String: AnyObject])["textMessages"] as? String self.users.append(newUser) DispatchQueue.main.async { self.tableView.reloadData() } break } }) }) } } } 

我已对我的数据库进行了一些更改,上面的代码可以正常工作,但是在我更改了我的数据库的方式后,它再也无法工作了,我的firebase看起来像

在此处输入图像描述

现在我的火力架看起来像: 在此处输入图像描述

我使用发送和接收者ID进行了chatRoomId。 但是我现在无法显示我上次发送的消息,该消息应该显示在我的主屏幕上。 我有什么方法可以解决这个问题? 或者我获取数据库的方式是错误的?

根据您的数据库结构,您的查询是错误的。 也不要在其他查询的块内执行lastMessage查询,因为这是完全独立的查询而与任何查询无关。 下面的代码将适合您。

 let ref = kFirDefaultDatabase.reference().child("yourChatRoomId").queryOrdered(byChild: "fromId").queryEqual(toValue: "0YfqnPIOYFYKb8cYZMHnSYti62i2").queryLimited(toLast: 1) ref.observeSingleEvent(of: DataEventType.value) { (snapshot) in if snapshot.exists() { print(snapshot.value) } } 

这将获取fromId为请求的chatRoomId发送的最后一条消息。 有关详细信息,请查看Firebase查询文档。

如果你想在桌面上为WhatsApp或其他聊天应用程序中的所有用户执行此操作,那么您需要创建一个额外的表LastMessages并在此处保存与每个chatRoomId相对应的最后消息信息,或者如果可能的话,将此详细信息保存在您可以获取的地方tableData这样您就不需要在循环中查询每个chatRoom

你可以做一些更好的东西来加快速度。 每当您发送或接收任何消息时,使用CoreDataSqlite并将lastMessage信息保存/更新到local db ,其中chatRoomId将成primary key并首先从local db获取信息并立即显示在table ,这意味着您可以获取数据从服务器并更新您的local db并刷新table

编辑:用于评论to get the last message regardless I send to recipient or recipient send to me

删除orderBy查询,只使用limitToLast 。 见下面的代码:

 let ref = kFirDefaultDatabase.reference().child("yourChatRoomId").queryLimited(toLast: 1) ref.observeSingleEvent(of: DataEventType.value) { (snapshot) in if snapshot.exists() { print(snapshot.value) } } 

您需要以不同方式设置房间。

如果你在一个房间里有3个人,那么RoomID会是什么? 如果有人离开房间,你怎么知道房间的历史?