Skip to content

Instantly share code, notes, and snippets.

@gsoltis
Last active May 6, 2024 03:17
Show Gist options
  • Save gsoltis/ee20138502a4764650f2 to your computer and use it in GitHub Desktop.
Save gsoltis/ee20138502a4764650f2 to your computer and use it in GitHub Desktop.
Quick Firebase / RxJS binding prototype
(function () {
var makeCallback = function(eventType, observer) {
if (eventType === 'value') {
return function(snap) {
observer.onNext(snap);
};
} else {
return function(snap, prevName) {
// Wrap into an object, since we can only pass one argument through.
observer.onNext({snapshot: snap, prevName: prevName});
}
}
};
Firebase.prototype.__proto__.observe = function(eventType) {
var query = this;
return Rx.Observable.create(function(observer) {
var listener = query.on(eventType, makeCallback(eventType, observer), function(error) {
observer.onError(error);
});
return function() {
query.off(eventType, listener);
}
}).publish().refCount();
};
})();
/**
* Usage:
*
* var source = new Firebase("https://<your firebase>.firebaseio.com").observe('<event type>');
* console.log(source instanceof Rx.Observable);
* source.subscribe(function(changeData) {
* // If event type is 'value', changeData is a DataSnapshot
* // Otherwise, changeData is {snapshot: DataSnapshot, prevName: optional string of previous child location}
* });
*
*/
@gsoltis
Copy link
Author

gsoltis commented May 14, 2014

Depends on the Firebase library, as well as rx.lite.js.

@mattpodwysocki
Copy link

You will also want to use .publish().refCount() in this situation to keep the number of handlers to a minimum, eg:

  Firebase.prototype.__proto__.observe = function(eventType) {
    var query = this;
    return Rx.Observable.create(function(observer) {
      var listener = query.on(eventType, makeCallback(eventType, observer), function(error) {
        observer.onError(error);
      });
      return function() {
        query.off(eventType, listener);
      }
    }).publish().refCount(); // Ensures this event handler is shared instead of creating a new one each time
  };

@gsoltis
Copy link
Author

gsoltis commented May 16, 2014

Thanks! I added the reference counting.

It's worth noting that Firebase already handles the case of multiple listeners being added for a single query fairly gracefully. It does not result in any extra network overhead, just a little extra bookkeeping. Happy to let RxJS do it though!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment