Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mattdanielbrown/00236e5ebafa5cce52751549e33b01d1 to your computer and use it in GitHub Desktop.
Save mattdanielbrown/00236e5ebafa5cce52751549e33b01d1 to your computer and use it in GitHub Desktop.
//This sets up listeners to listen to data in this structure: https://gist.github.com/davidgilbertson/283581dd10013848b0e7037e308db113
const db = firebase.database().ref('test');
const userId = firebase.auth().currentUser.uid;
const userRef = db.child('users').child(userId);
// a mock store
const store = {
dispatch: (action) => {
console.log(action);
}
}
const objectsToListenTo = [
{
dbRef: db.child('data/schools'),
keyPath: 'schoolKeys',
actions: {
upsert: item => store.dispatch({type: 'UPSERT_SCHOOL', item}),
remove: key => store.dispatch({type: 'REMOVE_SCHOOL', key}),
},
},
{
dbRef: db.child('data/courses'),
keyPath: 'courseKeys',
actions: {
upsert: item => store.dispatch({type: 'UPSERT_COURSE', item}),
remove: key => store.dispatch({type: 'REMOVE_COURSE', key}),
},
},
{
dbRef: db.child('data/students'),
keyPath: 'studentKeys',
actions: {
upsert: item => store.dispatch({type: 'UPSERT_STUDENT', item}),
remove: key => store.dispatch({type: 'REMOVE_STUDENT', key}),
},
},
];
class ObjectWatcher {
constructor(snapshot, type) {
this.type = type;
this.key = snapshot.key;
this.ref = type.dbRef.child(this.key);
this.ref.on('value', this.onChange.bind(this));
}
onChange(snapshot) {
if (!snapshot) return; // this fires when the object is removed. But the child_removed event handles the removal
this.type.actions.upsert({
[this.key]: snapshot.val(),
});
}
remove() {
this.type.actions.remove(this.key);
this.ref.off('value', this.onChange);
}
}
class ListWatcher {
constructor() {
this.cache = {};
}
watchList(ref, type) {
ref.on('child_added', snap => this.onChildAdded(snap, type));
ref.on('child_removed', snap => this.onChildRemoved(snap));
}
onChildAdded(snapshot, type) {
this.cache[snapshot.key] = new ObjectWatcher(snapshot, type);
}
onChildRemoved(snapshot) {
this.cache[snapshot.key].remove();
delete this.cache[snapshot.key];
}
}
const listWatcher = new ListWatcher();
objectsToListenTo.forEach(objectToListenTo => {
listWatcher.watchList(userRef.child(objectToListenTo.keyPath), objectToListenTo);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment