Hello, I'm working on this chat app and I have a snapshot listener to keep track the number of messages (with a badge) each user receives. I'm using a table view with pagination. The problem I'm having that I can't figure out is when a user gets a message, the table view duplicates the user, increases the badge number every time a message is received. Then, if i open the messages and then i go back to the first VC, there is another duplicate of the user but with no badge number because it was cleared. Any help is greatly appreciated.
VC
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
fetchMatches()
}
func fetchMatches() {
fetchInfo { matches in
self.match = matches
self.matchedMessagesTV.reloadData()
}
}
func fetchInfo(completion: @escaping([Match]) -> Void) {
if lastDocument == nil {
let query = MATCH_INFO_COLLECTION.document(currentUID!)
.collection("info").order(by: MATCH_TIMESTAMP, descending: false)
query.limit(to: 10).addSnapshotListener { (snapshot, error) in
guard let last = snapshot?.documents.last else { return }
guard let snap = snapshot else { return }
snap.documentChanges.forEach({ diff in
let dictionary = diff.document.data()
let memberId = dictionary[DOCUMENT_ID] as? String ?? ""
let memberAge = dictionary[AGE] as? Int ?? 0
let memberName = dictionary[FIRST_NAME] as? String ?? ""
let memberImageUrl = dictionary[PROFILE_IMAGE_URL] as? String ?? ""
let memberCurrentCity = dictionary[CURRENT_CITY] as? String ?? ""
let matchTimestamp = dictionary[MATCH_TIMESTAMP] as? Double ?? 0.0
let messageCounter = dictionary[MESSAGE_COUNTER] as? Int ?? 0
let matches = Match(memberId: memberId, memberAge: memberAge ,memberName: memberName, memberImageUrl: memberImageUrl, memberCurrentCity: memberCurrentCity, matchTimestamp: Date(timeIntervalSince1970: matchTimestamp), messageCounter: messageCounter)
self.match.append(matches)
self.memberId = matches.memberId
self.lastDocument = last
completion(self.match)
})
}
} else {
matchedMessagesTV.tableFooterView = createSpinnerFooter()
let query = MATCH_INFO_COLLECTION.document(currentUID!)
.collection("info").order(by: MATCH_TIMESTAMP, descending: false)
DispatchQueue.main.async {
self.matchedMessagesTV.tableFooterView = nil
}
query.start(afterDocument: self.lastDocument!)
.limit(to: 10).addSnapshotListener { (snapshot, error) in
guard let last = snapshot?.documents.last else { return }
guard let snap = snapshot else { return }
snap.documentChanges.forEach({ diff in
let dictionary = diff.document.data()
let memberId = dictionary[DOCUMENT_ID] as? String ?? ""
let memberAge = dictionary[AGE] as? Int ?? 0
let memberName = dictionary[FIRST_NAME] as? String ?? ""
let memberImageUrl = dictionary[PROFILE_IMAGE_URL] as? String ?? ""
let memberCurrentCity = dictionary[CURRENT_CITY] as? String ?? ""
let matchTimestamp = dictionary[MATCH_TIMESTAMP] as? Double ?? 0.0
let messageCounter = dictionary[MESSAGE_COUNTER] as? Int ?? 0
let matches = Match(memberId: memberId, memberAge: memberAge ,memberName: memberName, memberImageUrl: memberImageUrl, memberCurrentCity: memberCurrentCity, matchTimestamp: Date(timeIntervalSince1970: matchTimestamp), messageCounter: messageCounter)
self.match.append(matches)
self.memberId = matches.memberId
self.lastDocument = last
completion(self.match)
})
}}
}
class Match {
var memberId: String
let memberAge: Int
let memberName: String
let memberImageUrl: String
let memberCurrentCity: String
let matchTimestamp: Date!
let messageCounter: Int
init(memberId: String, memberAge: Int, memberName: String, memberImageUrl: String, memberCurrentCity: String, matchTimestamp: Date, messageCounter: Int) {
self.memberId = memberId
self.memberAge = memberAge
self.memberName = memberName
self.memberImageUrl = memberImageUrl
self.memberCurrentCity = memberCurrentCity
self.matchTimestamp = matchTimestamp
self.messageCounter = messageCounter
}
}
Can you tell us what is snapshot? I cannot find a method named
addSnapshotListener
in the Apple's frameworks.My apologies, thats part of the Firebase Framework, but, basically my issue is when a field is updated tableView.reloadData() repeats the cell many times.
Thanks for clarifying. I have never worked with Firebase, so I am not sure, but your issue may be caused by the behavior of Firebase snapshot. You would get better responses sooner if you visit a site where more experienced developers of Firebase are watching.