我有一个会话节点,内部是简单的子节点,例如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()
}
}
答案 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]