12.8. Observing Firestore Updates: Updating the TableView

We need to update our local array of contacts if anything changes in Firestore, right? If the user adds or removes a contact, we need to update the TableView.

So we need to add an observer for Firestore contacts list updates when there is a logged-in user. The observer for Firestore data change is called a SnapshotListener. (https://firebase.google.com/docs/firestore/query-data/listen?hl=en&authuser=0#swift).

We need to update handleAuth (the handler to handle authentication state changes) in ViewController.swift to add an observer. Open ViewController.swift and add the following code:

//
//  ViewController.swift
//  App12
//
//  Created by Sakib Miazi on 6/1/23.
//

import UIKit
import FirebaseAuth
import FirebaseFirestore

class ViewController: UIViewController {

    //code omitted...
    let database = Firestore.firestore()
    
    override func loadView() {
        view = mainScreen
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        //MARK: handling if the Authentication state is changed (sign in, sign out, register)...
        handleAuth = Auth.auth().addStateDidChangeListener{ auth, user in
            if user == nil{
               //code omitted...
                
            }else{
                //code omitted...
                
                //MARK: Observe Firestore database to display the contacts list...
                self.database.collection("users")
                    .document((self.currentUser?.email)!)
                    .collection("contacts")
                    .addSnapshotListener(includeMetadataChanges: false, listener: {querySnapshot, error in
                        if let documents = querySnapshot?.documents{
                            self.contactsList.removeAll()
                            for document in documents{
                                do{
                                    let contact  = try document.data(as: Contact.self)
                                    self.contactsList.append(contact)
                                }catch{
                                    print(error)
                                }
                            }
                            self.contactsList.sort(by: {$0.name < $1.name})
                            self.mainScreen.tableViewContacts.reloadData()
                        }
                    })
                
            }
        }
    }
    
    //code omitted...
}

In the above code:

  • On line 10, we import FirebaseFirestore library.

  • On line 15, we create the instance of the Firestore database.

  • Inside the handleAuth's closure when a user is signed in, we add a SnapshotListener on lines 33 through 50.

    • Here we observe the "contacts" collection of the current user document. If anything is changed in that collection, the closure gets triggered and querySnapshot contains the updates.

    • Basically the querySnapshot contains all the current documents inside the collection we are observing.

    • We then empty our current local contacts array on line 38.

    • Then we append all the current contacts from the querySnapshot. in lines 39 through 47.

      • On line 41, we parse the received document and decode that according to the Contact struct (which is Codable).

    • On line 47, we sort the contacts in the alphabetic order of names.

    • Finally, on line 48, we reload the table view data.

Now let's run the app again.

YAY!!! We built our first app using Firebase!!!

Last updated

Was this helpful?