我一直在应用的聊天部分中使用“MessengerKit”。我可以从firebase编写和准备消息,但是当聊天更新时,消息将按顺序重复(一次,两次,三次等)。我将下面的chatViewController代码与应用程序上的消息视图一起附加。
chatViewController代码:
class chatViewController: MSGMessengerViewController {
// Users in the chat
var nameOfHirer : String = ""
var nameofSeeker : String = ""
var seekerData = User(displayName: "", avatar: nil, isSender: false)
var hirerData = User(displayName: "", avatar: nil, isSender: true)
var id = 100
// Messages
lazy var messages: [[MSGMessage]] = []
func retrieveSeeker() {
let db = Firestore.firestore()
db.collection("Posts").document(jobID).collection("Applications").whereField("ID", isEqualTo: userID).getDocuments { (document, error) in
for document in document!.documents {
if error != nil {
}else {
let Name = document.get("Name") as! String
self.nameofSeeker = Name
let seeker = User(displayName: Name, avatar: nil, isSender: false)
self.seekerData = seeker
}
}
}
}
func retrieveHirer() {
let db = Firestore.firestore()
db.collection("Posts").document(jobID).getDocument { (document, error) in
if error != nil {
}else {
let Hirer = document?.get("Company Name") as! String
self.nameOfHirer = Hirer
let hirer = User(displayName: Hirer, avatar: nil, isSender: true)
self.hirerData = hirer
}
}
}
var uniqueID : String = ""
var messageBody : String = ""
var jobID : String = ""
var userID : String = ""
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
delegate = self
retrieveHirer()
retrieveSeeker()
// retrieveMessages()
print(messageBody)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.tabBar.isHidden = true
}
override var style: MSGMessengerStyle {
var style = MessengerKit.Styles.travamigos
style.inputPlaceholder = "Type your message here"
return style
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
collectionView.scrollToBottom(animated: false)
}
override func inputViewPrimaryActionTriggered(inputView: MSGInputView) {
id += 1
var newMessage : String = ""
let messageDictionary = ["Sender": userID, "MessageBody": inputView.message, "JobID": jobID]
// let body = MSGMessageBody.text(newMessage)
//
// let message = MSGMessage(id: id, body: body, user: hirerData, sentAt: Date())
inputView.resignFirstResponder()
let messageDB = Database.database().reference().child("Messages").child(jobID).child(userID)
messageDB.childByAutoId().setValue(messageDictionary) { (error, reference) in
if error != nil {
}else {
retrievemess()
}
}
func retrievemess() {
let messageDB = Database.database().reference().child("Messages").child(jobID).child(userID).queryLimited(toLast: 1)
messageDB.observe(.childAdded) { (snapshot) in
let value = snapshot.value as? [String: AnyObject]
let allmessage = value!["MessageBody"]
let body = MSGMessageBody.text(allmessage as! String)
let newmessage = MSGMessage(id: self.id, body: body, user: self.hirerData, sentAt: Date())
self.insert(newmessage)
}
}
}
override func insert(_ message: MSGMessage) {
collectionView.performBatchUpdates({
if let lastSection = self.messages.last, let lastMessage = lastSection.last, lastMessage.user.displayName == message.user.displayName {
self.messages[self.messages.count - 1].append(message)
let sectionIndex = self.messages.count - 1
let itemIndex = self.messages[sectionIndex].count - 1
self.collectionView.insertItems(at: [IndexPath(item: itemIndex, section: sectionIndex)])
} else {
print(messages.count)
self.messages.append([message])
let sectionIndex = self.messages.count - 1
self.collectionView.insertSections([sectionIndex])
}
}, completion: { (_) in
self.collectionView.scrollToBottom(animated: true)
self.collectionView.layoutTypingLabelIfNeeded()
})
}
override func insert(_ messages: [MSGMessage], callback: (() -> Void)? = nil) {
collectionView.performBatchUpdates({
for message in messages {
if let lastSection = self.messages.last, let lastMessage = lastSection.last, lastMessage.user.displayName == message.user.displayName {
self.messages[self.messages.count - 1].append(message)
let sectionIndex = self.messages.count - 1
let itemIndex = self.messages[sectionIndex].count - 1
self.collectionView.insertItems(at: [IndexPath(item: itemIndex, section: sectionIndex)])
} else {
self.messages.append([message])
let sectionIndex = self.messages.count - 1
self.collectionView.insertSections([sectionIndex])
}
}
}, completion: { (_) in
self.collectionView.scrollToBottom(animated: false)
self.collectionView.layoutTypingLabelIfNeeded()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
callback?()
}
})
}
}
// MARK: - MSGDataSource
extension chatViewController: MSGDataSource {
func numberOfSections() -> Int {
return messages.count
}
func numberOfMessages(in section: Int) -> Int {
return messages[section].count
}
func message(for indexPath: IndexPath) -> MSGMessage {
return messages[indexPath.section][indexPath.item]
}
func footerTitle(for section: Int) -> String? {
return "Just now"
}
func headerTitle(for section: Int) -> String? {
return messages[section].first?.user.displayName
}
}
// MARK: - MSGDelegate
extension chatViewController: MSGDelegate {
func linkTapped(url: URL) {
print("Link tapped:", url)
}
func avatarTapped(for user: MSGUser) {
print("Avatar tapped:", user)
}
func tapReceived(for message: MSGMessage) {
print("Tapped: ", message)
}
func longPressReceieved(for message: MSGMessage) {
print("Long press:", message)
}
func shouldDisplaySafari(for url: URL) -> Bool {
return true
}
func shouldOpen(url: URL) -> Bool {
return true
}
}
我正在使用的Pod是-https://github.com/steve228uk/MessengerKit
屏幕截图:
最佳答案
好了,我明白了。问题是
.queryLimited(toLast: 1).observe(.childAdded)
第一次触发后会返回多个条目。解决方案是将
.observe
更改为.observeSingleEvent