Skip to content

Instantly share code, notes, and snippets.

@Villanuevand
Created March 7, 2017 13:05
Show Gist options
  • Save Villanuevand/2407dab04cf958e7975b7afcabd6d0b1 to your computer and use it in GitHub Desktop.
Save Villanuevand/2407dab04cf958e7975b7afcabd6d0b1 to your computer and use it in GitHub Desktop.
Firebase + Algolia Search Integration

Firebase + Algolia Search Integration

As easy as 6 files and < 200 lines of code.

var config = require('config');
console.log(config);
var fbConfig = config.get('Services.firebase');
var alConfig = config.get('Services.algolia');
exports.FB_URL = `https://${process.env.FB_NAME || fbConfig.applicationId}.firebaseio.com`;
exports.FB_KEY = process.env.FB_KEY || fbConfig.key;
exports.AL_APPLICATION_ID = process.env.AL_APPLICATION_ID || alConfig.applicationId;
exports.AL_KEY = process.env.AL_KEY || alConfig.key;
exports.PATHS = process.env.PATHS || fbConfig.paths;
{
"Services": {
"firebase": {
"applicationId": "<<YOUR_FIREBASE_ID>>",
"key": "<<YOUR_FIREBASE_KEY>>",
"paths": [{
"path": "<<PATH_ONE>>"
}, {
"path": "<<PATH_TWO>>"
}]
},
"algolia": {
"applicationId": "<<YOUR_ALGOLIA_ID>>",
"key": "<<YOUR_ALGOLIA_KEY>>"
}
}
}
var Firebase = require('firebase');
var Promise = require('promise');
var config = require('../util/config');
var instance = null;
var exports = module.exports = {};
function initialize() {
if (!config.FB_URL) throw new Error('Firebase url is required');
if (!config.FB_KEY) throw new Error('Firebase key is required');
console.log('creating firebase instnce');
instance = new Firebase(config.FB_URL);
console.log('successfully created firebase instance');
var promise = new Promise(function(resolve, reject) {
instance.authWithCustomToken(config.FB_KEY, function(err) {
if (err) {
console.log('failed to authenticate firebase: ', err);
reject(err);
} else {
console.log('successfully authenticated firebase');
resolve(instance);
}
});
});
return promise;
}
function getInstance(){
if(!instance){
return new initialize();
}
console.log('firebase instance exists');
return Promise.resolve(instance);
}
exports.getInstance = getInstance;
var config = require('./util/config');
var pathObserver = require('./pathObserver');
exports.init = function() {
pathObserver.process(config.PATHS);
};
var db = require('./data/db');
var search = require('./data/search');
var searchContext = search.getInstanceSync();
function PathObserver(options) {
console.log(`creating index for path ${options.path}`);
var index = searchContext.initIndex(options.path);
db.getInstance().then(instance => {
console.log(`monitoring ${options.path} path for changes`);
var ref = instance.child(options.path);
ref.on('value', snap => reindexIndex(snap, options.path, index));
ref.on('child_added', snap => addOrUpdateObject(snap, index));
ref.on('child_changed', snap => addOrUpdateObject(snap, index));
ref.on('child_removed', snap => removeIndex(snap, index));
});
}
function reindexIndex(dataSnapshot, path, index) {
var objectsToIndex = [];
var tempIndexName = `${path}_temp`;
searchContext.initIndex(tempIndexName);
var values = dataSnapshot.val();
for (var key in values) {
if (values.hasOwnProperty(key)) {
var firebaseObject = values[key];
firebaseObject.objectID = key;
objectsToIndex.push(firebaseObject);
}
}
index.saveObjects(objectsToIndex, err => {
if (err) throw err;
searchContext.moveIndex(tempIndexName, path, err => {
if (err) throw err;
console.log('Database<>Search reimport done');
});
});
}
function addOrUpdateObject(dataSnapshot, index){
var firebaseObject = dataSnapshot.val();
firebaseObject.objectID = dataSnapshot.key();
index.saveObject(firebaseObject, err => {
if(err) throw err;
console.log('Database<>Search object saved');
});
}
function removeIndex(dataSnapshot, index){
var objectID = dataSnapshot.key();
index.deleteObject(objectID, err => {
if (err) throw err;
console.log('Database<>Search object removed');
});
}
exports.process = function(paths){
paths && paths.forEach(options => {
new PathObserver(options);
});
};
var algoliasearch = require('algoliasearch');
var config = require('../util/config');
var instance = null;
var exports = module.exports = {};
function initialize() {
console.log('initializing algoliasearch');
try {
instance = algoliasearch(config.AL_APPLICATION_ID, config.AL_KEY);
} catch (e) {
console.error('attempt to initialize algoliasearch failed', e);
throw e;
}
console.log('successfully initialized algoliasearch');
return instance;
}
function getInstanceSync() {
if (!instance) {
return new initialize();
}
return instance;
}
exports.getInstanceSync = getInstanceSync;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment