使用 Swift 更新 Firebase 中未读消息的数量

Update number of unread messages in Firebase using Swift

我正在尝试在我的应用程序中实现聊天功能。 当一个用户向另一个用户发送消息时,我想将 1 添加到 Firebase 中保存的 "unread number of messages" 的计数器。

这是我的 Firebase 树:

字段 "newMessage" 是我有多少未读消息的计数器。 在 "Messages" 之后是 Contact ID(消息被发送到的那个),然后是 Sender ID(向此联系人发送消息的那个),然后 "newMessage" 是多少条未读消息有发件人到联系人。

我写了这个函数来添加一个新的未读消息:

private func AddNewMsgTick(contactID: String)
    {
        let ref = Constants.refs.databaseChats.child(contactID).child(senderId)

        ref.observe( .value, with: {(snapshot) in

            let dataDic = snapshot.value as? NSDictionary

            if let currentNewMsgs = dataDic!["newMessage"] as? Int
            {
                let newIntMsg = currentNewMsgs + 1
                ref.setValue(newIntMsg) // This isn't right and should be updated
            }

        })
    }

而且这段代码似乎不能正常工作。我已经尝试了几次迭代,使用 ref.observeSingleEvent,也尝试使用 .ChildAdd,现在我已经进行了一次迭代,我试图将快照转换为字典并获取那里的价值。

我所有的函数迭代都失败了。我无法正确读取值并将其解析为 Int。它读取了错误的信息,如下所示:

在聊天中按下"Send"按钮一次激活的功能:

override func didPressSend(_ button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: Date!)
    {
        Constants.refs.databaseChats.child(senderId).observeSingleEvent(of: .value, with: {(snapshot) in

            if !snapshot.hasChild(self.contactID!)
            {
                self.CreateChatRoom(creatorID: senderId, creatorName: senderDisplayName, contactID: self.contactID!, contactName: self.contactDisplayName!)
            }

            let stringMsgPostedOn = Constants.GetCurrentDateTimeString()
            let senderRef = Constants.refs.databaseChats.child(senderId).child(self.contactID!).child("Messages").child(stringMsgPostedOn)
            let contactRef = Constants.refs.databaseChats.child(self.contactID!).child(senderId).child("Messages").child(stringMsgPostedOn)

            let senderRefLite = Constants.refs.databaseChatsLite.child(senderId).child(self.contactID!)
            let contactRefLite = Constants.refs.databaseChatsLite.child(self.contactID!).child(senderId)

            let message = ["userID": senderId, "userName": senderDisplayName, "text": text]
            let messageLite = ["userName": self.contactDisplayName, "lastMessage": text]

            // Make all this one transaction
            senderRef.setValue(message)
            senderRefLite.setValue(messageLite)

            contactRef.setValue(message)
            contactRefLite.setValue(messageLite)
            self.AddNewMsgTick(contactID: self.contactID!)
            self.finishSendingMessage()


        })


    }

聊天室初始化:

private func CreateChatRoom(creatorID: String, creatorName: String ,contactID: String, contactName: String)
    {
        let infoForCreator = ["userName": contactName, "newMessage" : String(0)]
        let infoForContact = ["userName": creatorName, "newMessage" : String(0)]



        let childUpdates = ["Messages/\(creatorID)/\(contactID)/": infoForCreator,
                            "Messages/\(contactID)/\(creatorID)/": infoForContact,
                            "ChatRoomsLite/\(creatorID)/\(contactID)/": infoForCreator,
                            "ChatRoomsLite/\(contactID)/\(creatorID)/": infoForContact
                            ]

        Constants.refs.databaseRoot.updateChildValues(childUpdates)
    }

实现此功能的正确方法是什么?将不胜感激。

像这样重构您的 CreateChatRoom 函数:

    let infoForCreator = ["userName": contactName, "newMessage" : 0]
    let infoForContact = ["userName": creatorName, "newMessage" : 0]

并且,尝试将您的 AddNewMsgTick 更改为使用:

ref.observeSingleEvent

我建议简化您的代码。您拥有的结构很好,因为您知道需要更新的数据的具体路径,请使用它。

假设一个 Firebase 结构

messages
   contact_0
      sender_0
         messages
            ...
         newMessage: 0
      sender_1
         messages
            ..
         newMessage: 5

如果我们想增加 sender_0 的消息计数器,只需像这样访问并更新它的路径:

let contactRef = self.ref.child("messages").child("contact_0")
let newMessagesRef = contactRef.child("sender_0").child("newMessage")
newMessagesRef.observeSingleEvent(of: .value, with: { snapshot in
    if let currentValue = snapshot.value as! Int? {
        let updatedValue = currentValue + 1
        ref.setValue(updatedValue)
    }
})

非常重要请注意,在您的问题中,newMessage 被存储为字符串“0”(不是零,它是一个字符串),如果您想要要存储值,请将它们存储为 Int。