@cerebral/firebase-admin
Install
NPM
npm install @cerebral/firebase-admin
Description
The firebase admin package for function-tree allows you to easily handle Firebase Queues. With the Cerebral debugger you will even be able to merge execution data cross client/server. This package helps you set up a QueueHandler which registers your specs with queues and lets you know when new tasks are ready to be run.
provider
First you create a function tree with the Firebase provider. You will need to add the Devtools with the same port as the client to merge execution.
const FunctionTree = require('function-tree').FunctionTree
const Devtools = require('function-tree/devtools')
const FirebaseProvider = require('@cerebral/firebase-admin').Provider
const devtools = Devtools({
host: 'localhost:8787'
})
const runTask = new FunctionTree([
devtools.Provider(),
FirebaseProvider({
serviceAccount: {}
databaseURL: '',
})
])
devtools.watchExecution(runTask)
module.exports = runTask
createKey
Create a new Firebase key at some path.
function authenticate (context) {
const newKey = context.firebase.createKey('some/path')
}
listUsers
Lists all users from Firebase authentication. Responds with "{users: [], nextPageToken: 'token'}".
function listAllUsers (context) {
return context.firebase.listUsers(context.props.maxResults, context.props.nextPageToken)
}
createUser
Create a user from Firebase. All properties are optional. Responds with "user".
function createUser (context) {
return context.firebase.createUser({
uid: context.props.uid,
email: context.props.email,
emailVerified: context.props.emailVerified,
phoneNumber: context.props.phoneNumber,
password: context.props.password,
displayName: context.props.displayName,
photoURL: context.props.photoURL,
disabled: context.props.disabled
})
}
deleteUser
Delete a user from Firebase. Outputs nothing.
function deleteUser (context) {
return context.firebase.deleteUser(context.props.uid)
}
push
Push new data. Outputs {key: 'keyAdded'}.
function addItem (context) {
return context.firebase.push('items', context.props.data.item)
}
remove
Remove key. Outputs nothing.
function removeItem (context) {
return context.firebase.remove(`items/${context.props.itemKey}`)
}
set
Set new data. Output nothing.
function addItem (context) {
return context.firebase.set(`items/${context.props.data.itemKey}`, context.props.data.item)
}
transaction
Run a transaction. Outputs nothing.
function updateItems (context) {
return context.firebase.transaction('some/path', (maybeValue) => {
if (!maybeValue) {
return 'bar'
}
return context.props.data.foo
})
}
update
Update multiple paths from top level or at specific path. Outputs nothing.
function updateItems (context) {
return context.firebase.update({
'items/1': context.props.data.item1Data,
'items/2': context.props.data.item2Data
})
}
function updateItems (context) {
return context.firebase.update('items', {
'1': context.props.data.item1Data,
'2': context.props.data.item2Data
})
}
value
Get value. Outputs {key: 'theKey', value: 'theValue'}.
function updateItems (context) {
return context.firebase.value('some/path')
}
task
Run a task
function runTask (context) {
return context.firebase.task('someTask', {
})
}
queueHandler
The QueueHandler is responsible for registering Firebase Queues with your defined specs and what trees should run when new tasks arrive in Firebase. The QueueHandler also automatically authenticates the tasks using verifyIdToken.
const runTask = require('./runTask')
const firebase = require('firebase-admin')
const username = require('username')
const QueueHandler = require('@cerebral/firebase-admin').QueueHandler
module.exports = new QueueHandler({
specPrefix: username.sync(),
authenticate: true,
tasks: [{
specId: 'some_spec_name',
numWorkers: 100,
tree: [
]
}],
queueRef: firebase.database().ref('queue')
}, (specId, tree, payload) => {
runTask.run(specId, tree, payload)
.catch((error) => {
runTask.run('ERROR', [], error.payload)
})
});
When a task runs you have access to the following props:
function someFunc (context) {
context.props.uid
context.props.data
context.props.task.resolve
context.props.task.reject
}
task
If you are using the firebase-queue and need to create tasks, you can do that with:
action
function someAction({ firebase, state }) {
return firebase.task('create_post', {
uid: state.get('app.user.uid'),
text: state.get('posts.newPostText')
})
}
This will add a task at queue/tasks
. There is no output from a resolved task, it just resolves when the action has been processed.
testTasks
You can easily test tasks. The TestTasks includes a local firebase-server and allows you to define a state of your Firebase instance before running tasks and assert its state after the tasks are run.
const TestTasks = require('@cerebral/firebase-admin').TestTasks
const testTasks = new TestTasks([
])
module.exports = testTasks
In your test framework of choice:
const someTreeToRun = require('./someTreeToRun')
const test = require('./testTasks');
const assert = require('assert');
describe('example', () => {
it('should test for foo', (done) => {
const runTest = test.create({
foo: 'bar'
}, {
task: someTreeToRun,
data: {
bip: 'bop'
}
}, (data) => {
assert.equal(data.foo, 'bar')
});
runTest(done)
})
})
Run multiple tasks:
const someTreeToRun = require('./someTreeToRun')
const test = require('./testTasks');
const assert = require('assert');
describe('example', () => {
it('should test for foo', (done) => {
const runTest = test.create({
foo: 'bar'
}, [{
task: someTreeToRun,
data: {
foo: 'bop'
},
assert (data) {
assert.equal(data.foo, 'bop')
}
}, {
task: someTreeToRun,
data: {
foo: 'bap'
}
}], (data) => {
assert.equal(data.foo, 'bap')
});
runTest(done)
})
})