Dimitri
Dimitri

Reputation: 2308

Firebase DB: how to resolve a Promise and keep listening to Firebase DB changes

I've got 2 functions as following, we 1 does some logic and the other reading a Firebase DB, and continues to listen to changes via using the .on() method.

  readDB(path): Promise<any>  {
    return new Promise((resolve, reject) => {
      firebase.database().ref(path).on('value', (snapshot) => {
      return resolve(snapshot);
        });
      });
    }

NgOnInit() {
  this.readDB(path).then((snap) => {
    this.viewVariable = snap.val().
  });
}
manipulationMethod(newData, path) {
  firebase.database().ref(path).update(newData);
}

The goal is to read and listen to Firebase DB changes and in real-time update the Interface when new data is written via the 2nd method.

PROBLEM: when I return a resolved promise, .on() listening is killed and it no longer listens to DB changes. I must use Promises (as I have a lot of async functions).

QUESTION: is there a way to resolve a promise and keep the listening functionality? Like, return a "subscription" or something alike?

Upvotes: 0

Views: 813

Answers (2)

kuzyn
kuzyn

Reputation: 1995

Once your Firebase object is initialized, simply attach a listener to the ref that you need to observe, and put it outside of your function. It should be something like:

// fb listener

// where to watch
const myRef = 'ressource/path'
const myDb = firebase.database()
const refToWatch = myDb.ref(myRef)

// the actual listener
refToWatch.on('child_changed', snapshot => {
  const s = snapshot.val()
  console.log(JSON.stringify(s))
})

See the official docs for more details

Upvotes: 2

Frank van Puffelen
Frank van Puffelen

Reputation: 598728

Promises by definition resolve only once. This when you want to return a promise with data from Firebase, you'll use once() instead of on().

If you on the other hand want to return a stream of values, you'll use on and return a stream oriented data type. The typical type for this these days is an RxJS Observable. For a single example of turning an on() into an observable, see this gist from Chris Esplin.

Rx.Observable.fromEvent(ref, 'child_added').subscribe(function (snap) {
  console.log('child_added', snap.key);
});

So this creates an observable of child_added events, then subscribes to that observable, and print each event it gets.

Upvotes: 1

Related Questions