【问题标题】:Update number of unread messages in Firebase using Swift使用 Swift 更新 Firebase 中未读消息的数量
【发布时间】:2018-09-02 07:33:52
【问题描述】:

我正在尝试在我的应用中实现聊天。 当一个用户向另一个用户发送消息时,我想将 1 添加到 Firebase 中保存的“未读消息数”的计数器中。

这是我的 Firebase 树:

“newMessage”字段是我有多少未读消息的计数器。 在“消息”之后,有联系人 ID(发送消息的对象),然后是发件人 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。它读取了错误的信息,如下所示:

在聊天中按下“发送”按钮后激活的功能:

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)
    }

实现此功能的正确方法是什么?非常感谢您的帮助。

【问题讨论】:

  • 尝试使用 .childChanged 代替 .value,根据定义 - 对于 .childChanged 位置处的子节点发生更改。
  • 但是 .childChanged 会在孩子更改时启动,我想更改现有的
  • 你试过了吗???因为文档清楚地告诉firebase.google.com/docs/database/ios/lists-of-data
  • 我不懂你。它清楚地表明它倾听变化,这不是我想要做的。我想自己改,改了就不干了。
  • 我可以毫不犹豫地这么说 - 我只是试了一下,它根本没有给我我需要的值。

标签: ios swift firebase chat


【解决方案1】:

像这样重构你的 CreateChatRoom 函数:

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

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

ref.observeSingleEvent

【讨论】:

  • 添加到帖子:)
  • 这不是答案。应该是评论。
  • 抱歉,以后会使用cmets
  • 是的。但是您将 newMessage 计数保存为 String,但试图将其解包为 Int。试试我编辑的答案。
  • @Ofri 不幸的是,这个答案将您送错了方向,并且没有解决最初的问题,即 我想将 1 添加到保存在Firebase。 如果您在上面提到此答案不正确,请不要接受。
【解决方案2】:

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

假设一个 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 的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-05
    • 1970-01-01
    相关资源
    最近更新 更多