如何通过一次调用更新Firebase中的多种类型的节点(Swift)

时间:2018-08-02 00:58:40

标签: swift firebase firebase-realtime-database

我有一个会话节点,内部是简单的子节点,例如displayMessage,conversationName,imageUrl等,但是还有一个消息节点,其中包含其他子节点,这些子节点描述了在会话内部发送的所有消息,其中包含senderID,文本和时间戳。当按下发送消息按钮时,我正在尝试使用其他消息子节点以及诸如displayMessage和lastMessageTime之类的简单子节点来更新message节点。但是,我编写的代码仅用新的消息节点完全替换了“消息”中的所有节点。

 fileprivate func sendMessage(uid: String, convoId: String) {


    let ref = Database.database().reference().child("conversations").child(convoId)

    let messageTime = NSDate().timeIntervalSince1970
    let messageInfo : [String:Any] = ["text":containerView.chatTextView.text, "senderId":uid, "timestamp": messageTime]
    let randomMessageId = NSUUID().uuidString
    let messageDict = [randomMessageId:messageInfo]

    let values = ["displayMessage":containerView.chatTextView.text, "lastMessageTime": messageTime, "messages":messageDict] as [String : Any]

    ref.updateChildValues(values) { (error, ref) in

        if error != nil {
            print (error as Any)
            return
        }

        self.containerView.clearChatTextField()

                }

}

Database Structure

1 个答案:

答案 0 :(得分:0)

当您使用updateChildValues时,Firebase服务器将遍历字典中的每个键,并使用您指定的值在每个键上调用setValue

这意味着它仅在字典的顶层进行合并;在每个孩子身上,它仍然会替换现有的值。

如果要在较低级别的JSON上执行更新/追加,则需要将这些子级的路径编码为字典的键。因此,要将新消息添加到对话的messages子级,您需要将新消息的路径作为键。您已经在生成自己的消息ID,因此只需将其包含在密钥中,而不是在字典的值中,即可将其包含在密钥中:

let randomMessageId = NSUUID().uuidString

let values = ["displayMessage": containerView.chatTextView.text,
              "lastMessageTime": messageTime, 
              "messages/"+randomMessageId: messageInfo] as [String: Any]