As easy as 6 files and < 200 lines of code.
Created
March 7, 2017 13:05
-
-
Save Villanuevand/2407dab04cf958e7975b7afcabd6d0b1 to your computer and use it in GitHub Desktop.
Firebase + Algolia Search Integration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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>>" | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var config = require('./util/config'); | |
var pathObserver = require('./pathObserver'); | |
exports.init = function() { | |
pathObserver.process(config.PATHS); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
}); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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