@eixox/jetfuel-firebase-react
Version:
Our jetfuel lib to connect react to firebase
144 lines (133 loc) • 3.85 kB
JavaScript
import firebase from "firebase";
import Xsettings from "Xsettings.js";
// Required for side-effects
require("firebase/firestore");
/**
* Holds a reference to the firestore;
*/
const firestore = Xsettings.firebase.firestore();
/**
* A generic firebase proxy class with helper methods;
*/
export default class Xfirestore {
constructor(name) {
this.name = name;
this.items = {};
this.collection = firestore.collection(name);
}
/**
* Adds a new document to this collection with the specific key;
* @param {*} key
* @param {*} document
*/
put(key, document) {
var dis = this;
var promisse =
key && key !== null && key !== undefined
? this.collection.doc(key).set(document)
: this.collection.add(document);
promisse
.then(function(docRef) {
var id = docRef ? docRef.id : key;
dis.items[id] = document;
if (dis.onChange) dis.onChange(dis.items, id, document);
})
.catch(function(error) {
console.error("Error writing document: ", error);
if (dis.onError) dis.onError(error);
});
}
/**
* Deletes an item from the database with the specified key;
* @param {*} key
* @param {*} onComplete
*/
delete(key, onComplete) {
var dis = this;
this.collection
.doc(key)
.delete()
.then(function() {
try {
var oldValue = dis.items[key];
delete dis.items[key];
if (dis.onChange) dis.onChange(dis.items, key, oldValue);
if (onComplete) onComplete(true);
} catch (e) {
console.log("Deleted from remote store but...", e);
if (onComplete) onComplete(false, e);
}
})
.catch(function(error) {
console.error("Error removing document: ", error);
if (dis.onError) dis.onError(error);
if (onComplete) onComplete(false, error);
});
}
/**
* Appends a where filter to this collection;
* @param {*} name
* @param {*} comparison
* @param {*} value
*/
where(name, comparison, value) {
this.collection = this.collection.where(name, comparison, value);
return this;
}
/**
* Retrieves the first element with the given key from the databse;
* @param {*} key
* @param {*} fn
*/
first(key, fn) {
var dis = this;
this.collection
.doc(key)
.get()
.then(function(doc) {
if (doc.exists) {
var docData = doc.data();
dis.items[doc.id] = docData;
if (fn) fn(docData, doc.id);
if (dis.onChange) dis.onChange(dis.items, doc.id, docData);
} else {
console.log("No such document:", key);
}
})
.catch(function(error) {
console.log("Error getting document:", error);
if (dis.onError) dis.onError(error);
});
}
/**
* Executes the query and loads the document onto the items array;
*/
load() {
var dis = this;
this.collection
.get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
var docData = doc.data();
dis.items[doc.id] = docData;
});
if (dis.onChange) dis.onChange(dis.items);
})
.catch(function(error) {
console.log("Error getting documents: ", error);
if (dis.onError) dis.onError(error);
});
}
/**
* Iterates over the items array and produces an array with the resulting calls to fn;
* Use the "caller" parameter to give meaning to the "this" keyword inside your function;
* For example, calling map (function(){}, myObject) will set this=myObject inside function();
* @param {*} fn
* @param {*} caller
*/
map(fn, caller) {
return Object.keys(this.items).map(function(key) {
return fn.call(caller, this.items[key], key);
}, this);
}
}