附加Firebase聊天消息 [英] Append Firebase chat messages
问题描述
我正在创建一个聊天应用程序,并且我有一个表格视图单元格中两个用户之间发送的所有消息的列表。例如,我在两个用户之间共有四个文本,所以我有四个单元格。但是,我想将这些单元格分组,因此我只有一个单元格,因为我的loggedInUser只与一个人通信。不管我做什么,邮件都不会追加。
func loadData(){$ b $ if(FIRAuth.auth()?. currentUser)!= nil {
在
中记录了以下参数:{(snapshot:FIRDataSnapshot)快照
如果让postsDictionary =快照.value as?[String:AnyObject] {
在postsDictionary中发布{
let messages = post.value as![String:AnyObject]
让信息=值作为![字符串:AnyObject]
如果让receiver = info [ReceiverId] {
print( \(id):\(receiver))
self.messages.Array(value)
$ b self.MessageTableView .reloadData()
}
}})}
}
截至目前,我的应用程序正在像这样显示两个用户之间的消息:
我认为问题出在 self .messages.Array(value)
我只需要在相同的两个用户之间追加消息,但是我找不到正确的代码
我想要在两个用户之间的对话在一个单元格(附加它)
这就是我的手机看起来像:
覆盖func tableView(_ tableView:UITableView,cellForRowAt indexPath:IndexPath) - > UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:MessageCell,for:indexPath)as! MessageTableViewCell
//配置单元格
print(messages [indexPath.row])
let message = self.messages [ indexPath.row]为! [字符串:AnyObject]
如果让秒=消息[时间戳]作为? Double {
let timeStampDate = NSDate(timeIntervalSince1970:seconds)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat =hh:mm a
cell.Time.text = dateFormatter .string(from:timeStampDate as Date)
}
cell.Message.text = message [text] as? String
// cell.SellerName.text = message [ReceiverId] as?字符串
如果让imageName = message [ReceiverId]为?字符串{
let ref = FIRDatabase.database()。reference()。child(posts)。child(imageName)
ref.observeSingleEvent(of:.value ,如下:{(snapshot)
in
如果让dictionary = snapshot.value as?[字符串:AnyObject] {
在字典中发布{
let message = post.value as![字符串:AnyObject]
为消息中的(id,value){
cell.SellerName.text = messages [username] as?String $ b $如果(message [uid] as?String)!= nil {
let uidPoster = messages [uid] as?String
let imageRef = FIRStorage.storage()。reference()。在$ b $中有void((uidPoster)!+/ profile_pic.jpg)
imageRef.data(withMaxSize:25 * 1024 * 1024,完成:{(data,error) - & b如果错误== nil {
let image = UII mage(data:data!)
cell.UserPic.image = image
cell.UserPic.layer.cornerRadius = 30
cell.UserPic.clipsToBounds = true
$ b} else {
print(Error download image:)
}})}
self.messages.add(value)
}
}
$ b}
})
}
返回单元格
}
消息是:
$ b
FIRDatabase.database()。reference()。child(messages)。child((self.convoId!))。childByAutoId()
以下是我的数据库结构: < img src =https://i.stack.imgur.com/kND2u.pngalt =在这里输入图片描述>
我会在我的答案中使用一个超级简单的例子。
$ b 给定一个结构
消息
msg_0
rec:uid_0
发送:uid_1
msg:msg from uid_0 to uid_1
msg_1
rec:uid_1
send:uid_0
msg:msg from uid_1 to uid_0
将一个查询观察者添加到消息节点,观察具有一个rec:uid_0的新消息(.childAdded) / p>
var messagesArray = [String]()
func watch(){
let messagesRef = self.ref.child(messages)
let queryRef = messagesRef.queryOrdered(byChild:rec)。queryEqual(toValue:uid_0)
queryRef.observe(。 childAdded:{快照
让msgDict = snapshot.value as! [字符串:任何]
让msg = msgDict [msg] as!字符串
self.messagesArray = [] //擦除数组
self.messagesArray.append(msg)//在索引0处添加新消息
print (self.messagesArray)//打印只是例如
//通常调用tableView.reloadData()将刷新
// tableView中的单元格,并显示一次
/ /
你可以从通过将快照或字典存储在数组中,以便知道消息文本,并可以使用send:user id来查找发送消息的人。
如果您运行这个代码,输出将被发送到uid_0的任何新消息;只会显示最新的信息。如果你有一个带有messagesArray的tableView,因为它是dataSource(这通常是如何完成的),那么tableView将刷新,并只显示uid_0的最新消息。
作为一个方面的说明,.queryLimited(toLast :)可以在这里使用得很好。
I am creating a chat app and I have a list of all the messages sent between two users in a table view cell. For example, I have four texts in total between the two users and so I have four cells. However, I would like to group the cells so that I only have one cell, because I the loggedInUser is only communicating with one person. No matter what I do, the messages will not append.
func loadData(){
if (FIRAuth.auth()?.currentUser) != nil{
FIRDatabase.database().reference().child("messages").observeSingleEvent(of: .value, with: { (snapshot:FIRDataSnapshot) in
let loggedInUserData = snapshot
if let postsDictionary = snapshot .value as? [String: AnyObject] {
for post in postsDictionary {
let messages = post.value as! [String: AnyObject]
for (id, value) in messages {
let info = value as! [String: AnyObject]
if let receiver = info["ReceiverId"] {
print("\(id): \(receiver)")
self.messages.Array(value)
}
}
self.MessageTableView.reloadData()
}
}})}
}
As of now my app is displaying messages between two users like this:
I think the issue is in the self.messages.Array(value)
I just need to append messages between the same two users but I can't find the right code
But I would like for a conversation between two users to be in one cell (append it)
This is what my cell looks like:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MessageCell", for: indexPath) as! MessageTableViewCell
//Configure the cell
print(messages[indexPath.row])
let message = self.messages[indexPath.row] as! [String: AnyObject]
if let seconds = message["timestamp"] as? Double {
let timeStampDate = NSDate(timeIntervalSince1970: seconds)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "hh:mm a"
cell.Time.text = dateFormatter.string(from: timeStampDate as Date)
}
cell.Message.text = message["text"] as? String
// cell.SellerName.text = message["ReceiverId"] as? String
if let imageName = message["ReceiverId"] as? String {
let ref = FIRDatabase.database().reference().child("posts").child(imageName)
ref.observeSingleEvent(of: .value, with: { (snapshot)
in
if let dictionary = snapshot.value as? [String: AnyObject]{
for post in dictionary {
let messages = post.value as! [String: AnyObject]
for (id, value) in messages {
cell.SellerName.text = messages["username"] as? String
if (messages["uid"] as? String) != nil {
let uidPoster = messages["uid"] as? String
let imageRef = FIRStorage.storage().reference().child((uidPoster)!+"/profile_pic.jpg")
imageRef.data(withMaxSize: 25 * 1024 * 1024, completion: { (data, error) -> Void in
if error == nil {
let image = UIImage(data: data!)
cell.UserPic.image = image
cell.UserPic.layer.cornerRadius = 30
cell.UserPic.clipsToBounds = true
}else {
print("Error downloading image:" )
}})}
self.messages.add(value)
}
}
}
})
}
return cell
}
my path to firebase message is:
FIRDatabase.database().reference().child("messages").child("(self.convoId!)").childByAutoId()
Here is my database structure:
解决方案 I will use a super simple example in my answer.
Given a structure
messages
msg_0
rec: "uid_0"
send: "uid_1"
msg: "msg from uid_0 to uid_1"
msg_1
rec: "uid_1"
send: "uid_0"
msg: "msg from uid_1 to uid_0"
Add a query observer to the messages node watching for any new messages (.childAdded) that have a rec: of uid_0.
var messagesArray = [String]()
func watch() {
let messagesRef = self.ref.child("messages")
let queryRef = messagesRef.queryOrdered(byChild: "rec").queryEqual(toValue: "uid_0")
queryRef.observe(.childAdded, with: { snapshot in
let msgDict = snapshot.value as! [String: Any]
let msg = msgDict["msg"] as! String
self.messagesArray = [] //erases the array
self.messagesArray.append(msg) //adds this new message at index 0
print(self.messagesArray) //print is just for example
//normally call tableView.reloadData() which will refresh
// the cells in the tableView and display just once cell with
// the latest message in it
})
}
You can extrapolate from this by storing the snapshot or the dictionary in the array so you know the message text and can use the send: user id to look up who sent the message.
If you run this code, the output will be any new message sent to uid_0; only the latest message will be displayed. If you have a tableView with the messagesArray as it's dataSource (which is normally how its done) then the tableView would be refreshed and only ever show the latest message for uid_0.
As a side note, .queryLimited(toLast:) could be leveraged here was well.
这篇关于附加Firebase聊天消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!