Jake Chasan
Jake Chasan

Reputation: 6560

Firebase 'Observe' called multiple times with Swift on iOS

When I start the observer on a Firebase database node, I notice that Firebase continues to call the method observer even when there is no data change.

Here is my setup:

FIRDatabase
    .database()
    .reference(withPath: "test")
    .observe(FIRDataEventType.value, with: { (snapshot) in
            print("Firebase Data Updated");
    }
);

When I make one change to the Firebase database, the observer calls its closure function more than one time.

Firebase Data Updated

Firebase Data Updated

Firebase Data Updated

Firebase Data Updated

Firebase Data Updated

Firebase Data Updated

Firebase Data Updated

...

Why does this occur? How can I stop this from occurring and get only one call to the observer after an update?

Upvotes: 3

Views: 4885

Answers (2)

Jignesh Patel
Jignesh Patel

Reputation: 101

Swift 4: 
If you want to remove all listeners registered with test node.
    Database.database().reference(withPath: "test").removeAllObservers()

If you want to remove particular listener then you need particular handler for observer. You can use following sample code.
    let ref = Database.database().reference(withPath: "test")
            let handler = ref.observe(.value) { (snapshot) in
            }
            ref.removeObserver(withHandle: handler)

Upvotes: 1

leonardloo
leonardloo

Reputation: 1803

It's likely this observer is being registered multiple times. When the user logs out, the listener block that you registered stays registered, such that when the user logs in again, you are registering a second listener.

It is often good practice to capture the ref and handle of observers, and remove the handles once you're done with them (i.e. when a user logs out). You can do so as such:

ref, handle = FIRDatabase
    .database()
    .reference(withPath: "test")
    .observe(FIRDataEventType.value, with: { (snapshot) in
            print("Firebase Data Updated");
    }
);

And at sign out:

ref.removeObserverWithHandle(handle)

Otherwise another possible solution to ensure it is only called once is to use .observeSingleEvent() instead of .observe().

Upvotes: 4

Related Questions