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

时间:2018-05-03 07:39:39

标签: ios swift firebase firebase-realtime-database

我试图在聊天信使的主屏幕上显示我上次发送的消息,从故事板看起来像: enter image description here

我使用的代码是:

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看起来像

enter image description here

现在我的firebase看起来像: enter image description here

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

2 个答案:

答案 0 :(得分:1)

根据您的数据库结构,您的查询错误。也不要在其他查询的块内执行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 Queries doc。

如果您想在表中为WhatsApp或其他聊天应用程序中的所有用户执行此操作,则需要创建一个额外的表LastMessages并在此处保存与每个chatRoomId对应的最后一条消息信息{1}}或者如果可能的话,可以使用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)
     }
}

答案 1 :(得分:0)

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

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