javascriptfirebasegoogle-cloud-firestore

Firebase Realtime Listener Concept - how to detach / unsubscribe from the listener?


Get realtime updates with Cloud Firestore shows how to subscribe to, or listen to, document changes.

db.collection("cities").doc("SF")
    .onSnapshot(function(doc) {
        console.log("Current data: ", doc.data());
    });

The example above makes sense. My question concerns detaching the listener. Is it accurate to say that when we want to detach / unsubscribe / unlisten to a document, we simply subscribe a second time to the same database reference?

...that's what it looks like, but I'm not crystal clear as to how/why?

var unsubscribe = db.collection("cities")
    .onSnapshot(function (){
      // Respond to data
      // ...
    });

// Later ...

// Stop listening to changes
unsubscribe();

This seems unnecessarily confusing. ...Why not simply have 2 methods, .onSnapshot and .offSnapshot? I supposed the only difference I see between the two provided examples is that the latter is assigned to a variable and that the method is called on the whole collection, rather than a single document.

So, is the bottom line: to unsubscribe, attach the .onSnapshot method to the parent collection and assign it to a variable?


Solution

  • My question concerns detaching the listener. Is it accurate to say that when we want to detach / unsubscribe / unlisten to a document, we simply subscribe a second time to the same database reference?

    You don't need to subscribe twice.

    The initial subscription you made returns a function which when called, unsubscribes you. You don't add that code a second time, instead store the return value from the initial call to the collection into a variable and invoke it when you intend to unsubscribe.

    Imagine something like this:

    function subscribe() {
      ... do things that subscribe me
      return function() {
        ... do things that unsubscribe me
      }
    }
    
    let unsubscribe = subscribe()
    
    // later when I want to unsubscribe
    unsubscribe()