I'm currently building a chat app and when I click on a user, it takes me to the chat log controller. Here I call a function fetchChatMessages() in viewdidload() that essentially fetches the conversation from firestore. Problem is, whenever I go to the previous controller and open the chat again, it again fetches the messages.
Not sure if it's fetching from cache or from the server itself. But I did write a print statement under the firestore fetch code that prints every time.
Now I'm new to swift so my question is, in other chat apps, you can see that messages seemed to be fetched just once from the server and after that you add a listener and update the collection view to display the new messages. In my case, it seems like everything is fetched over and over again. Even though I have added a listener and followed a highly acclaimed tutorial.
Also, I added a scroll to bottom code whenever messages are fetched, so every time a new message is fetched, the controller automatically scrolls to the bottom. But this happens every time I open the chat. I was trying to fix this bug where the controller keeps scrolling every time the view appears which made me wonder, am I contacting firebase again and again when the controller is opened?
override func viewDidLoad() {
super.viewDidLoad()
fetchCurrentUser()
fetchMessages()
setupLoadView()
}
//MARK: Fetch Messages
var listener: ListenerRegistration?
fileprivate func fetchMessages(){
print("Fetching Messages")
guard let cUid = Auth.auth().currentUser?.uid else {return}
let query = Firestore.firestore().collection("matches").document(cUid).collection(connect.uid).order(by: "Timestamp")
listener = query.addSnapshotListener { (querySnapshot, error) in
if let error = error{
print("There was an error fetching messages", error.localizedDescription)
return
}
querySnapshot?.documentChanges.forEach({ (change) in
if change.type == .added{
let dictionary = change.document.data()
self.items.append(.init(dictionary: dictionary))
print("FIRESTORE HAS BEEN CONTACTED FETCHING MESSAGES")
}
})
self.collectionView.reloadData()
self.collectionView.scrollToItem(at: [0, self.items.count - 1], at: .bottom, animated: true)
print("Fetched messages")
}
}
//MARK: View Disappears
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if isMovingFromParent{
listener?.remove()
}
}
I want the controller to remember its state. Like if I scroll the messages, exit the controller and enter it again, it stays at the scrolled position like in whatsapp.