skip to Main Content

I am struggling to understand why my event listener that I initialize on a document is not being triggered whenever I update the document within the app in a different UIViewController. If I update it manually in Google firebase console, the listener event gets triggered successfully. I am 100% updating the correct document too because I see it get updated when I update it in the app. What I am trying to accomplish is have a running listener on the current user that is logged in and all of their fields so i can just use 1 global singleton variable throughout my app and it will always be up to date with their most current fields (name, last name, profile pic, bio, etc.). One thing I noticed is when i use setData instead of updateData, the listener event gets triggered. For some reason it doesn’t with updateData. But i don’t want to use setData because it will wipe all the other fields as if it is a new doc. Is there something else I should be doing?

Below is the code that initializes the Listener at the very beginning of the app after the user logs in.

    static func InitalizeWhistleListener() {
        let currentUser = Auth.auth().currentUser?.uid

        let userDocRef = Firestore.firestore().collection("users").document(currentUser!)
        WhistleListener.shared.listener = userDocRef.addSnapshotListener { documentSnapshot, error in
            guard let document = documentSnapshot else {
                print("Error fetching document: (error!)")
                return
            }
            guard let data = document.data() else {
                print("Document data was empty.")
                return
            }

            print("INSIDE LISTENER")
        }
    }

Below is the code that update’s this same document in a different view controller whenever the user updates their profile pic

    func uploadProfilePicture(_ image: UIImage) {

        guard let uid = currentUser!.UID else { return }
        let filePath = "user/(uid).jpg"
        let storageRef = Storage.storage().reference().child(filePath)

        guard let imageData = image.jpegData(compressionQuality: 0.75) else { return }

        storageRef.putData(imageData) { metadata, error in
            if error == nil && metadata != nil {
                self.userProfileDoc!.updateData([
                    "profilePicURL": filePath
                ]) { err in
                    if let err = err {
                        print("Error updating document: (err)")
                    } else {
                        print("Document successfully updated")
                    }
                }
            }
        }
    }

2

Answers


  1. Chosen as BEST ANSWER

    The answer is pretty obvious (and sad at the same time). I was constantly updating the filepath to be the user's UID therefore, it would always be the same and the snapshot wouldn't recognize a difference in the update. It had been some time since I had looked at this code so i forgot this is what it was doing. I was looking past this and simply thinking an update (no matter if it was different from the last or not) would trigger an event. That is not the case! So what I did was append an additional UUID to the user's UID so that it changed.


  2. You can use set data with merge true it doesn’t wipe any other property only merge to specific one that you declared as like I am only update the name of the user without wiping the age or address

    db.collection("User")
                .document(id)
                .setData(["name":"Zeeshan"],merge: true)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search