@cerebral/firebase
Advanced tools
Comparing version 2.0.0 to 2.1.0-1504939819809
@@ -15,16 +15,6 @@ 'use strict'; | ||
(0, _helpers.listenTo)((0, _helpers.createRef)(path, options), path, 'child_added', signal, function (data) { | ||
var initialPayload = { | ||
controller.getSignal(signal)(Object.assign({ | ||
key: data.key, | ||
value: data.val() | ||
}; | ||
var payload = initialPayload; | ||
if (options.payload) { | ||
payload = Object.keys(options.payload).reduce(function (payload, key) { | ||
payload[key] = options.payload[key]; | ||
return payload; | ||
}, initialPayload); | ||
} | ||
controller.getSignal(signal)(payload); | ||
}, options.payload || {})); | ||
}); | ||
@@ -31,0 +21,0 @@ }; |
@@ -15,16 +15,6 @@ 'use strict'; | ||
(0, _helpers.listenTo)((0, _helpers.createRef)(path, options), path, 'child_changed', signal, function (data) { | ||
var initialPayload = { | ||
controller.getSignal(signal)(Object.assign({ | ||
key: data.key, | ||
value: data.val() | ||
}; | ||
var payload = initialPayload; | ||
if (options.payload) { | ||
payload = Object.keys(options.payload).reduce(function (payload, key) { | ||
payload[key] = options.payload[key]; | ||
return payload; | ||
}, initialPayload); | ||
} | ||
controller.getSignal(signal)(payload); | ||
}, options.payload || {})); | ||
}); | ||
@@ -31,0 +21,0 @@ }; |
@@ -21,5 +21,3 @@ 'use strict'; | ||
var payload = Object.assign({ value: data.val() }, options.payload || {}); | ||
controller.getSignal(signal)(payload); | ||
controller.getSignal(signal)(Object.assign({ value: data.val() }, options.payload || {})); | ||
}); | ||
@@ -26,0 +24,0 @@ }; |
@@ -6,3 +6,3 @@ 'use strict'; | ||
}); | ||
exports.default = deleteOp; | ||
exports.default = deleteFile; | ||
@@ -13,3 +13,3 @@ var _helpers = require('./helpers'); | ||
function deleteOp(path, filename) { | ||
function deleteFile(path, filename) { | ||
var ref = (0, _helpers.createStorageRef)(path).child(filename); | ||
@@ -16,0 +16,0 @@ |
@@ -126,2 +126,6 @@ 'use strict'; | ||
var _linkWithFacebook = require('./linkWithFacebook'); | ||
var _linkWithFacebook2 = _interopRequireDefault(_linkWithFacebook); | ||
var _linkWithGithub = require('./linkWithGithub'); | ||
@@ -131,2 +135,6 @@ | ||
var _linkWithGoogle = require('./linkWithGoogle'); | ||
var _linkWithGoogle2 = _interopRequireDefault(_linkWithGoogle); | ||
var _onDisconnect = require('./onDisconnect'); | ||
@@ -147,29 +155,32 @@ | ||
context.firebase = cachedProvider = { | ||
cancelOnDisconnect: _onDisconnect.cancelOnDisconnect, | ||
createUserWithEmailAndPassword: _createUserWithEmailAndPassword2.default, | ||
delete: _delete2.default, | ||
deleteFile: _delete2.default, | ||
deleteUser: _deleteUser2.default, | ||
getUser: _getUser2.default, | ||
signInAnonymously: _signInAnonymously2.default, | ||
signInWithFacebook: _signInWithFacebook2.default, | ||
signInWithGoogle: _signInWithGoogle2.default, | ||
signInWithGithub: _signInWithGithub2.default, | ||
signInWithCustomToken: _signInWithCustomToken2.default, | ||
linkWithFacebook: _linkWithFacebook2.default, | ||
linkWithGithub: _linkWithGithub2.default, | ||
linkWithGoogle: _linkWithGoogle2.default, | ||
off: _helpers.stopListening, | ||
onChildAdded: (0, _createOnChildAdded2.default)(context.controller), | ||
onChildChanged: (0, _createOnChildChanged2.default)(context.controller), | ||
onChildRemoved: (0, _createOnChildRemoved2.default)(context.controller), | ||
onChildChanged: (0, _createOnChildChanged2.default)(context.controller), | ||
onValue: (0, _createOnValue2.default)(context.controller), | ||
value: _value2.default, | ||
push: _push2.default, | ||
put: _put2.default, | ||
linkWithGithub: _linkWithGithub2.default, | ||
delete: _delete2.default, | ||
update: _update2.default, | ||
remove: _remove2.default, | ||
sendPasswordResetEmail: _sendPasswordResetEmail2.default, | ||
set: _set2.default, | ||
remove: _remove2.default, | ||
transaction: _transaction2.default, | ||
createUserWithEmailAndPassword: _createUserWithEmailAndPassword2.default, | ||
setOnDisconnect: _onDisconnect.setOnDisconnect, | ||
signInAnonymously: _signInAnonymously2.default, | ||
signInWithCustomToken: _signInWithCustomToken2.default, | ||
signInWithEmailAndPassword: _signInWithEmailAndPassword2.default, | ||
signInWithFacebook: _signInWithFacebook2.default, | ||
signInWithGithub: _signInWithGithub2.default, | ||
signInWithGoogle: _signInWithGoogle2.default, | ||
signOut: _signOut2.default, | ||
deleteUser: _deleteUser2.default, | ||
sendPasswordResetEmail: _sendPasswordResetEmail2.default, | ||
setOnDisconnect: _onDisconnect.setOnDisconnect, | ||
cancelOnDisconnect: _onDisconnect.cancelOnDisconnect | ||
transaction: _transaction2.default, | ||
update: _update2.default, | ||
value: _value2.default | ||
}; | ||
@@ -176,0 +187,0 @@ } |
@@ -7,2 +7,11 @@ 'use strict'; | ||
var _cancelOnDisconnect = require('./cancelOnDisconnect'); | ||
Object.defineProperty(exports, 'cancelOnDisconnect', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_cancelOnDisconnect).default; | ||
} | ||
}); | ||
var _createUserWithEmailAndPassword = require('./createUserWithEmailAndPassword'); | ||
@@ -17,134 +26,140 @@ | ||
var _getUser = require('./getUser'); | ||
var _delete = require('./delete'); | ||
Object.defineProperty(exports, 'getUser', { | ||
Object.defineProperty(exports, 'delete', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_getUser).default; | ||
return _interopRequireDefault(_delete).default; | ||
} | ||
}); | ||
Object.defineProperty(exports, 'deleteFile', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_delete).default; | ||
} | ||
}); | ||
var _off = require('./off'); | ||
var _deleteUser = require('./deleteUser'); | ||
Object.defineProperty(exports, 'off', { | ||
Object.defineProperty(exports, 'deleteUser', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_off).default; | ||
return _interopRequireDefault(_deleteUser).default; | ||
} | ||
}); | ||
var _onChildAdded = require('./onChildAdded'); | ||
var _getUser = require('./getUser'); | ||
Object.defineProperty(exports, 'onChildAdded', { | ||
Object.defineProperty(exports, 'getUser', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_onChildAdded).default; | ||
return _interopRequireDefault(_getUser).default; | ||
} | ||
}); | ||
var _onChildChanged = require('./onChildChanged'); | ||
var _linkWithFacebook = require('./linkWithFacebook'); | ||
Object.defineProperty(exports, 'onChildChanged', { | ||
Object.defineProperty(exports, 'linkWithFacebook', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_onChildChanged).default; | ||
return _interopRequireDefault(_linkWithFacebook).default; | ||
} | ||
}); | ||
var _onChildRemoved = require('./onChildRemoved'); | ||
var _linkWithGithub = require('./linkWithGithub'); | ||
Object.defineProperty(exports, 'onChildRemoved', { | ||
Object.defineProperty(exports, 'linkWithGithub', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_onChildRemoved).default; | ||
return _interopRequireDefault(_linkWithGithub).default; | ||
} | ||
}); | ||
var _onValue = require('./onValue'); | ||
var _linkWithGoogle = require('./linkWithGoogle'); | ||
Object.defineProperty(exports, 'onValue', { | ||
Object.defineProperty(exports, 'linkWithGoogle', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_onValue).default; | ||
return _interopRequireDefault(_linkWithGoogle).default; | ||
} | ||
}); | ||
var _signInAnonymously = require('./signInAnonymously'); | ||
var _off = require('./off'); | ||
Object.defineProperty(exports, 'signInAnonymously', { | ||
Object.defineProperty(exports, 'off', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_signInAnonymously).default; | ||
return _interopRequireDefault(_off).default; | ||
} | ||
}); | ||
var _signInWithEmailAndPassword = require('./signInWithEmailAndPassword'); | ||
var _onChildAdded = require('./onChildAdded'); | ||
Object.defineProperty(exports, 'signInWithEmailAndPassword', { | ||
Object.defineProperty(exports, 'onChildAdded', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_signInWithEmailAndPassword).default; | ||
return _interopRequireDefault(_onChildAdded).default; | ||
} | ||
}); | ||
var _signInWithCustomToken = require('./signInWithCustomToken'); | ||
var _onChildChanged = require('./onChildChanged'); | ||
Object.defineProperty(exports, 'signInWithCustomToken', { | ||
Object.defineProperty(exports, 'onChildChanged', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_signInWithCustomToken).default; | ||
return _interopRequireDefault(_onChildChanged).default; | ||
} | ||
}); | ||
var _signInWithFacebook = require('./signInWithFacebook'); | ||
var _onChildRemoved = require('./onChildRemoved'); | ||
Object.defineProperty(exports, 'signInWithFacebook', { | ||
Object.defineProperty(exports, 'onChildRemoved', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_signInWithFacebook).default; | ||
return _interopRequireDefault(_onChildRemoved).default; | ||
} | ||
}); | ||
var _signInWithGoogle = require('./signInWithGoogle'); | ||
var _onValue = require('./onValue'); | ||
Object.defineProperty(exports, 'signInWithGoogle', { | ||
Object.defineProperty(exports, 'onValue', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_signInWithGoogle).default; | ||
return _interopRequireDefault(_onValue).default; | ||
} | ||
}); | ||
var _signInWithGithub = require('./signInWithGithub'); | ||
var _push = require('./push'); | ||
Object.defineProperty(exports, 'signInWithGithub', { | ||
Object.defineProperty(exports, 'push', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_signInWithGithub).default; | ||
return _interopRequireDefault(_push).default; | ||
} | ||
}); | ||
var _signOut = require('./signOut'); | ||
var _put = require('./put'); | ||
Object.defineProperty(exports, 'signOut', { | ||
Object.defineProperty(exports, 'put', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_signOut).default; | ||
return _interopRequireDefault(_put).default; | ||
} | ||
}); | ||
var _task = require('./task'); | ||
var _remove = require('./remove'); | ||
Object.defineProperty(exports, 'task', { | ||
Object.defineProperty(exports, 'remove', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_task).default; | ||
return _interopRequireDefault(_remove).default; | ||
} | ||
}); | ||
var _value = require('./value'); | ||
var _sendPasswordResetEmail = require('./sendPasswordResetEmail'); | ||
Object.defineProperty(exports, 'value', { | ||
Object.defineProperty(exports, 'sendPasswordResetEmail', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_value).default; | ||
return _interopRequireDefault(_sendPasswordResetEmail).default; | ||
} | ||
@@ -162,102 +177,111 @@ }); | ||
var _update = require('./update'); | ||
var _setOnDisconnect = require('./setOnDisconnect'); | ||
Object.defineProperty(exports, 'update', { | ||
Object.defineProperty(exports, 'setOnDisconnect', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_update).default; | ||
return _interopRequireDefault(_setOnDisconnect).default; | ||
} | ||
}); | ||
var _push = require('./push'); | ||
var _signInAnonymously = require('./signInAnonymously'); | ||
Object.defineProperty(exports, 'push', { | ||
Object.defineProperty(exports, 'signInAnonymously', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_push).default; | ||
return _interopRequireDefault(_signInAnonymously).default; | ||
} | ||
}); | ||
var _put = require('./put'); | ||
var _signInWithCustomToken = require('./signInWithCustomToken'); | ||
Object.defineProperty(exports, 'put', { | ||
Object.defineProperty(exports, 'signInWithCustomToken', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_put).default; | ||
return _interopRequireDefault(_signInWithCustomToken).default; | ||
} | ||
}); | ||
var _delete = require('./delete'); | ||
var _signInWithEmailAndPassword = require('./signInWithEmailAndPassword'); | ||
Object.defineProperty(exports, 'delete', { | ||
Object.defineProperty(exports, 'signInWithEmailAndPassword', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_delete).default; | ||
return _interopRequireDefault(_signInWithEmailAndPassword).default; | ||
} | ||
}); | ||
var _remove = require('./remove'); | ||
var _signInWithFacebook = require('./signInWithFacebook'); | ||
Object.defineProperty(exports, 'remove', { | ||
Object.defineProperty(exports, 'signInWithFacebook', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_remove).default; | ||
return _interopRequireDefault(_signInWithFacebook).default; | ||
} | ||
}); | ||
var _transaction = require('./transaction'); | ||
var _signInWithGithub = require('./signInWithGithub'); | ||
Object.defineProperty(exports, 'transaction', { | ||
Object.defineProperty(exports, 'signInWithGithub', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_transaction).default; | ||
return _interopRequireDefault(_signInWithGithub).default; | ||
} | ||
}); | ||
var _deleteUser = require('./deleteUser'); | ||
var _signInWithGoogle = require('./signInWithGoogle'); | ||
Object.defineProperty(exports, 'deleteUser', { | ||
Object.defineProperty(exports, 'signInWithGoogle', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_deleteUser).default; | ||
return _interopRequireDefault(_signInWithGoogle).default; | ||
} | ||
}); | ||
var _sendPasswordResetEmail = require('./sendPasswordResetEmail'); | ||
var _signOut = require('./signOut'); | ||
Object.defineProperty(exports, 'sendPasswordResetEmail', { | ||
Object.defineProperty(exports, 'signOut', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_sendPasswordResetEmail).default; | ||
return _interopRequireDefault(_signOut).default; | ||
} | ||
}); | ||
var _linkWithGithub = require('./linkWithGithub'); | ||
var _task = require('./task'); | ||
Object.defineProperty(exports, 'linkWithGithub', { | ||
Object.defineProperty(exports, 'task', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_linkWithGithub).default; | ||
return _interopRequireDefault(_task).default; | ||
} | ||
}); | ||
var _setOnDisconnect = require('./setOnDisconnect'); | ||
var _transaction = require('./transaction'); | ||
Object.defineProperty(exports, 'setOnDisconnect', { | ||
Object.defineProperty(exports, 'transaction', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_setOnDisconnect).default; | ||
return _interopRequireDefault(_transaction).default; | ||
} | ||
}); | ||
var _cancelOnDisconnect = require('./cancelOnDisconnect'); | ||
var _update = require('./update'); | ||
Object.defineProperty(exports, 'cancelOnDisconnect', { | ||
Object.defineProperty(exports, 'update', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_cancelOnDisconnect).default; | ||
return _interopRequireDefault(_update).default; | ||
} | ||
}); | ||
var _value = require('./value'); | ||
Object.defineProperty(exports, 'value', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_value).default; | ||
} | ||
}); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -6,3 +6,8 @@ Object.defineProperty(exports, "__esModule", { | ||
}); | ||
var _helpers = require('../helpers'); | ||
function onValueFactory(path, signal) { | ||
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
function onValue(_ref) { | ||
@@ -12,3 +17,3 @@ var firebase = _ref.firebase, | ||
firebase.onValue(resolve.value(path), resolve.path(signal)); | ||
firebase.onValue(resolve.value(path), resolve.path(signal), (0, _helpers.convertObjectWithTemplates)(options, resolve)); | ||
} | ||
@@ -15,0 +20,0 @@ |
@@ -28,3 +28,3 @@ 'use strict'; | ||
uploadTask.on('state_changed', function (snapshot) { | ||
progress({ | ||
progress(Object.assign({}, options.payload || {}, { | ||
progress: snapshot.bytesTransferred / snapshot.totalBytes, | ||
@@ -34,3 +34,3 @@ bytesTransferred: snapshot.bytesTransferred, | ||
state: snapshot.state // 'paused', 'running' | ||
}); | ||
})); | ||
}, function (error) { | ||
@@ -37,0 +37,0 @@ reject(new _errors.FirebaseProviderError(error)); |
{ | ||
"name": "@cerebral/firebase", | ||
"version": "2.0.0", | ||
"version": "2.1.0-1504939819809", | ||
"description": "Firebase provider for Cerebral", | ||
@@ -29,7 +29,7 @@ "main": "lib/index.js", | ||
"peerDependencies": { | ||
"cerebral": "^2.1.0" | ||
"cerebral": "^2.2.0-1504939819809" | ||
}, | ||
"devDependencies": { | ||
"cerebral": "^2.1.0" | ||
"cerebral": "^2.2.0-1504939819809" | ||
} | ||
} |
1018
README.md
# @cerebral/firebase | ||
## install | ||
## Install | ||
**NPM** | ||
@@ -8,7 +8,7 @@ | ||
## description | ||
## Description | ||
The Firebase provider is a Cerebral friendly wrapper around the Firebase client. By default the Firebase client is heavily event based, even just getting some value, handling authentication etc. This is useful in some types of apps, but Cerebral has a very straight forward way of thinking about side effects. You will find that a lot of the API exposed by the Firebase client is simplified! | ||
## instantiate | ||
## Instantiate | ||
@@ -44,144 +44,35 @@ ```javascript | ||
## error | ||
The Firebase errors are passed to signal and global catch handlers, or `.catch` handler in your actions. | ||
## cancelOnDisconnect | ||
Cancel setting a value when Firebase detects disconnect. | ||
### FirebaseProviderError (base) | ||
### action | ||
```js | ||
import {FirebaseProviderError} from '@cerebral/firebase' | ||
// Error structure | ||
{ | ||
name: 'HttpProviderError', | ||
message: 'Some firebase error message' | ||
stack: '...' | ||
function someAction({ firebase, state }) { | ||
firebase.cancelOnDisconnect() | ||
} | ||
``` | ||
### FirebaseProviderAuthenticationError | ||
```js | ||
import {FirebaseProviderAuthenticationError} from '@cerebral/firebase' | ||
// Error structure | ||
{ | ||
name: 'HttpProviderError', | ||
message: 'Some firebase error message' | ||
code: 10 // firebase auth error code | ||
stack: '...' | ||
} | ||
``` | ||
## set | ||
Write data to this database location. This will overwrite any data at this location and all child locations. Passing **null** for the new value is equivalent to calling remove(); all data at this location or any child location will be deleted. | ||
### action | ||
```javascript | ||
function someAction({firebase}) { | ||
return firebase.set('foo.bar', 'baz') | ||
.then(() => { | ||
// No output | ||
}) | ||
} | ||
``` | ||
### operator | ||
```javascript | ||
import {props} from 'cerebral/tags' | ||
import {set} from '@cerebral/firebase/operators' | ||
import {state} from 'cerebral/tags' | ||
import {cancelOnDisconnect} from '@cerebral/firebase/operators' | ||
export default [ | ||
set('foo.bar', props`foo`), | ||
// No output | ||
cancelOnDisconnect() | ||
] | ||
``` | ||
### operator with paths | ||
```javascript | ||
import {props} from 'cerebral/tags' | ||
import {set} from '@cerebral/firebase/operators' | ||
## createUserWithEmailAndPassword | ||
Register a new user with email and password. | ||
export default [ | ||
set('foo.bar', props`foo`), { | ||
success: [ | ||
// No output | ||
], | ||
error: [ | ||
/* PROPS: { error: {...} } */ | ||
] | ||
} | ||
] | ||
``` | ||
## update | ||
As opposed to the set() method, update() can be use to selectively update only the referenced properties at the current location (instead of replacing all the child properties at the current location). | ||
### action | ||
```javascript | ||
function someAction({firebase}) { | ||
return firebase.update('some.path', { | ||
'foo': 'bar', | ||
'items.item1.isAwesome': true | ||
}) | ||
.then(() => { | ||
// No output | ||
}) | ||
} | ||
``` | ||
```js | ||
function someAction({ firebase, state }) { | ||
const email = state.get('register.email') | ||
const password = state.get('register.password') | ||
### operator | ||
```javascript | ||
import {props} from 'cerebral/tags' | ||
import {update} from '@cerebral/firebase/operators' | ||
export default [ | ||
update('some.path', { | ||
'foo.bar': props`bar`, | ||
'foo.baz': props`baz` | ||
}), | ||
// No output | ||
// Alternatively with explicit paths | ||
update('some.path', { | ||
'foo.bar': props`bar`, | ||
'foo.baz': props`baz` | ||
}), { | ||
success: [], | ||
error: [] | ||
} | ||
] | ||
``` | ||
### operator with paths | ||
```javascript | ||
import {props} from 'cerebral/tags' | ||
import {update} from '@cerebral/firebase/operators' | ||
export default [ | ||
update('some.path', { | ||
'foo.bar': props`bar`, | ||
'foo.baz': props`baz` | ||
}), { | ||
success: [ | ||
// No output | ||
], | ||
error: [ | ||
/* PROPS: { error: {...} } */ | ||
] | ||
} | ||
] | ||
``` | ||
## push | ||
Generates a new child location using a unique key and returns its reference from the action. An example being `{key: "-KWKImT_t3SLmkJ4s3-w"}`. | ||
### action | ||
```javascript | ||
function someAction({firebase}) { | ||
return firebase.push('users', { | ||
name: 'Bob' | ||
}) | ||
return firebase.createUserWithEmailAndPassword(email, password) | ||
.then((response) => { | ||
/* | ||
{ | ||
key: 'someKey' | ||
} | ||
user: { uid: 'someuid', ... } | ||
*/ | ||
@@ -195,9 +86,9 @@ }) | ||
import {state} from 'cerebral/tags' | ||
import {push} from '@cerebral/firebase/operators' | ||
import {createUserWithEmailAndPassword} from '@cerebral/firebase/operators' | ||
export default [ | ||
push('users', state`newUser`), | ||
createUserWithEmailAndPassword(state`newUser.email`, state`newUser.password`), | ||
/* | ||
PROPS: { | ||
response: {...} | ||
response: { user: {} } | ||
} | ||
@@ -211,6 +102,6 @@ */ | ||
import {state} from 'cerebral/tags' | ||
import {push} from '@cerebral/firebase/operators' | ||
import {createUserWithEmailAndPassword} from '@cerebral/firebase/operators' | ||
export default [ | ||
push('users', state`newUser`), { | ||
createUserWithEmailAndPassword(state`newUser.email`, state`newUser.password`), { | ||
success: [ | ||
@@ -226,14 +117,10 @@ /* PROPS: { response: {...} } */ | ||
*output* | ||
```javascript | ||
{key: 'theAddedKey'} | ||
``` | ||
## deleteFile | ||
## remove | ||
Remove the data at this database location. | ||
Use `deleteFile` to remove an uploaded file. Specify the containing folder and filename. | ||
### action | ||
```javascript | ||
function someAction({ firebase}) { | ||
return firebase.remove('foo.bar') | ||
```js | ||
function someAction({ firebase, props }) { | ||
return firebase.deleteFile('folderName', props.fileName) | ||
.then(() => { | ||
@@ -246,9 +133,21 @@ // No output | ||
### operator | ||
```javascript | ||
import {props, string} from 'cerebral/tags' | ||
import {remove} from '@cerebral/firebase/operators' | ||
```js | ||
import {props, state, string} from 'cerebral/tags' | ||
import {deleteFile} from '@cerebral/firebase/operators' | ||
export default [ | ||
remove(string`users.${props`userKey`}`), | ||
deleteFile( | ||
string`posts.all.${props`postId`}`, | ||
state`posts.all.${props`postId`}.imageName` | ||
), | ||
// No output | ||
// Alternatively with explicit paths | ||
deleteFile( | ||
string`posts.all.${props`postId`}`, | ||
state`posts.all.${props`postId`}.imageName` | ||
), { | ||
success: [], | ||
error: [] | ||
} | ||
] | ||
@@ -258,8 +157,11 @@ ``` | ||
### operator with paths | ||
```javascript | ||
import {props, string} from 'cerebral/tags' | ||
import {remove} from '@cerebral/firebase/operators' | ||
```js | ||
import {props, state, string} from 'cerebral/tags' | ||
import {deleteFile} from '@cerebral/firebase/operators' | ||
export default [ | ||
remove(string`users.${props`userKey`}`), { | ||
deleteFile( | ||
string`posts.all.${props`postId`}`, | ||
state`posts.all.${props`postId`}.imageName` | ||
), { | ||
success: [ | ||
@@ -275,37 +177,43 @@ // No output | ||
## transaction | ||
Atomically modifies the data at the provided location. | ||
## error | ||
The Firebase errors are passed to signal and global catch handlers, or `.catch` handler in your actions. | ||
Unlike a normal set(), which just overwrites the data regardless of its previous value, transaction() is used to modify the existing value to a new value, ensuring there are no conflicts with other clients writing to the same location at the same time. | ||
### FirebaseProviderError (base) | ||
```js | ||
import {FirebaseProviderError} from '@cerebral/firebase' | ||
To accomplish this, you pass transaction() an update function which is used to transform the current value into a new value. If another client writes to the location before your new value is successfully written, your update function will be called again with the new current value, and the write will be retried. This will happen repeatedly until your write succeeds without conflict or you abort the transaction by not returning a value from your update function. | ||
// Error structure | ||
{ | ||
name: 'HttpProviderError', | ||
message: 'Some firebase error message' | ||
stack: '...' | ||
} | ||
``` | ||
### action | ||
```javascript | ||
function someAction({firebase}) { | ||
### FirebaseProviderAuthenticationError | ||
```js | ||
import {FirebaseProviderAuthenticationError} from '@cerebral/firebase' | ||
function transactionFunction(currentData){ | ||
if (currentData === null) { | ||
return { foo: 'bar' } | ||
} | ||
// Error structure | ||
{ | ||
name: 'HttpProviderError', | ||
message: 'Some firebase error message' | ||
code: 10 // firebase auth error code | ||
stack: '...' | ||
} | ||
``` | ||
return // Abort the transaction. | ||
} | ||
## getUser | ||
Will resolve to `{user: {}}` if user exists. If user was redirected from Facebook/Google etc. as part of first sign in, this method will handle the confirmed registration of the user. | ||
return firebase.transaction('some.transaction.path', transactionFunction) | ||
.then((result) => { | ||
if(result.committed){ | ||
return {result: result.value} | ||
} else { | ||
throw new Error('Transaction failed') | ||
} | ||
### action | ||
```js | ||
function someAction({ firebase }) { | ||
return firebase.getUser() | ||
.then((response) => { | ||
/* | ||
user: {...}, | ||
isRedirected: false | ||
*/ | ||
}) | ||
.then((response) => { | ||
/* | ||
{ | ||
committed: true, | ||
value: 'new value' | ||
} | ||
*/ | ||
}) | ||
} | ||
@@ -316,8 +224,6 @@ ``` | ||
```javascript | ||
import {transaction} from '@cerebral/firebase/operators' | ||
import {getUser} from '@cerebral/firebase/operators' | ||
function transactionFunction() {...} | ||
export default [ | ||
transaction('foo.bar', transactionFunction), | ||
getUser(), | ||
/* | ||
@@ -333,8 +239,6 @@ PROPS: { | ||
```javascript | ||
import {transaction} from '@cerebral/firebase/operators' | ||
import {getUser} from '@cerebral/firebase/operators' | ||
function transactionFunction() {...} | ||
export default [ | ||
transaction('foo.bar', transactionFunction), { | ||
getUser(), { | ||
success: [ | ||
@@ -350,18 +254,16 @@ /* PROPS: { response: {...} } */ | ||
Note: Modifying data with set() will cancel any pending transactions at that location, so extreme care should be taken if mixing set() and transaction() to update the same data. | ||
## linkWith{PROVIDER} | ||
Link an anonymous account with Facebook, Google or Github. | ||
Note: When using transactions with Security and Firebase Rules in place, be aware that a client needs .read access in addition to .write access in order to perform a transaction. This is because the client-side nature of transactions requires the client to read the data in order to transactionally update it. | ||
## value | ||
### action | ||
```js | ||
function someAction({ firebase }) { | ||
return firebase.value('someKey.foo') | ||
function someAction({ firebase, state }) { | ||
return firebase.linkWithFacebook({ | ||
redirect: false, // Use popup or redirect. Redirect typically for mobile | ||
scopes: [] // Facebook scopes to access | ||
}) | ||
.then((response) => { | ||
/* | ||
{ | ||
key: 'foo', | ||
value: 'some value' | ||
} | ||
name: 'Bob', | ||
... | ||
*/ | ||
@@ -374,7 +276,9 @@ }) | ||
```javascript | ||
import {value} from '@cerebral/firebase/operators' | ||
import {state} from 'cerebral/tags' | ||
import {linkWithFacebook} from '@cerebral/firebase/operators' | ||
export default [ | ||
value('foo.bar'), | ||
linkWithFacebook({ | ||
redirect: state`useragent.media.small` | ||
}), | ||
/* | ||
@@ -385,7 +289,2 @@ PROPS: { | ||
*/ | ||
// Alternatively with explicit paths | ||
value('foo.bar'), { | ||
success: [], | ||
error: [] | ||
} | ||
] | ||
@@ -396,6 +295,9 @@ ``` | ||
```javascript | ||
import {value} from '@cerebral/firebase/operators' | ||
import {state} from 'cerebral/tags' | ||
import {linkWithFacebook} from '@cerebral/firebase/operators' | ||
export default [ | ||
value('foo.bar'), { | ||
linkWithFacebook({ | ||
redirect: state`useragent.media.small` | ||
}), { | ||
success: [ | ||
@@ -411,18 +313,23 @@ /* PROPS: { response: {...} } */ | ||
## onValue | ||
Similar you can sign in with Google or GitHub. | ||
Just use `linkWithGoogle` or `linkWithGithub` instead of `linkWithFacebook`. | ||
## off | ||
### action | ||
```js | ||
function someAction({ firebase }) { | ||
firebase.onValue('someKey.foo', 'someModule.fooUpdated', { | ||
payload: {}, // Merged with the payload passed on new data | ||
}); | ||
} | ||
``` | ||
This will **NOT** immediately grab the value and trigger the signal passed, the first event is discarded for more predictable behaviour. To grab existing value, just use `value`. | ||
// Turn off listener at specific path and | ||
// specific event | ||
firebase.off('posts', 'onChildChanged') | ||
To stop listening for updates to the value: | ||
```js | ||
function someAction({ firebase }) { | ||
firebase.off('someKey.foo', 'onValue'); | ||
// Turn off all listeners at specific path | ||
firebase.off('posts') | ||
// Turn off all listeners of specific event at wildcard path | ||
firebase.off('posts.*', 'onChildChanged') | ||
// Turn off all listeners at wildcard path | ||
firebase.off('posts.*') | ||
} | ||
@@ -433,7 +340,11 @@ ``` | ||
```javascript | ||
import {onValue} from '@cerebral/firebase/operators' | ||
import {string, signal} from 'cerebral/tags' | ||
import {string} from 'cerebral/tags' | ||
import {off} from '@cerebral/firebase/operators' | ||
export default [ | ||
onValue(string`foo.bar`, signal`some.signal`) | ||
// Same API as in actions, also wildcard | ||
off('posts', 'onChildChanged'), | ||
// Compose using string tag | ||
off(string`posts.${state`selectedPostKey`}`) | ||
] | ||
@@ -448,14 +359,18 @@ ``` | ||
firebase.onChildAdded('posts', 'posts.postAdded', { | ||
payload: {}, // Merged with the payload passed on new data | ||
limitToFirst: 5, // Read Firebase docs | ||
limitToLast: 5, // Read Firebase docs | ||
startAt: 5, // Read Firebase docs | ||
endAt: 5, // Read Firebase docs | ||
equalTo: 5, // Read Firebase docs | ||
orderByChild: 'count', // Read Firebase docs | ||
orderByKey: true, // Read Firebase docs | ||
orderByValue: true // Read Firebase docs | ||
}); | ||
// Merged with the payload passed on new data | ||
payload: {}, | ||
// Read Firebase docs for these options | ||
endAt: 5, | ||
equalTo: 5, | ||
limitToFirst: 5, | ||
limitToLast: 5, | ||
orderByChild: 'count', | ||
orderByKey: true, | ||
orderByValue: true, | ||
startAt: 5, | ||
}) | ||
// posts.postAdded called with { key, value, ...payload } | ||
} | ||
``` | ||
This will immediately grab and trigger the signal `posts.postAdded` for every post grabbed. Note this is just registering a listener, not returning a value from the action. The signal is triggered with the payload: `{ key: 'someKey', value: {} }`. | ||
@@ -483,3 +398,3 @@ | ||
## onChildRemoved | ||
## onChildChanged | ||
@@ -489,8 +404,9 @@ ### action | ||
function someAction({ firebase }) { | ||
firebase.onChildRemoved('posts', 'posts.postRemoved', { | ||
firebase.onChildChanged('posts', 'posts.postChanged', { | ||
// Same options as above | ||
}); | ||
}) | ||
// posts.postChanged called with { key, value, ...payload } | ||
} | ||
``` | ||
This will trigger the signal `posts.postRemoved` whenever a post is removed from the selection. The signal is triggered with the payload: `{ key: 'someKey' }`. | ||
This will trigger the signal `posts.postChanged` whenever a post is changed in the selection. The signal is triggered with the payload: `{ key: 'someKey', value: {} }`. | ||
@@ -500,3 +416,3 @@ To stop listening: | ||
function someAction({ firebase }) { | ||
firebase.off('posts', 'onChildRemoved'); | ||
firebase.off('posts', 'onChildChanged'); | ||
} | ||
@@ -507,7 +423,7 @@ ``` | ||
```javascript | ||
import {onChildRemoved} from '@cerebral/firebase/operators' | ||
import {onChildChanged} from '@cerebral/firebase/operators' | ||
import {string, signal} from 'cerebral/tags' | ||
export default [ | ||
onChildRemoved(string`foo.bar`, signal`some.signal`, { | ||
onChildChanged(string`foo.bar`, signal`some.signal`, { | ||
// Same options as above | ||
@@ -518,3 +434,3 @@ }) | ||
## onChildChanged | ||
## onChildRemoved | ||
@@ -524,8 +440,9 @@ ### action | ||
function someAction({ firebase }) { | ||
firebase.onChildChanged('posts', 'posts.postChanged', { | ||
firebase.onChildRemoved('posts', 'posts.postRemoved', { | ||
// Same options as above | ||
}); | ||
}) | ||
// posts.postRemoved called with { key, ...payload } | ||
} | ||
``` | ||
This will trigger the signal `posts.postChanged` whenever a post is changed in the selection. The signal is triggered with the payload: `{ key: 'someKey', value: {} }`. | ||
This will trigger the signal `posts.postRemoved` whenever a post is removed from the selection. The signal is triggered with the payload: `{ key: 'someKey' }`. | ||
@@ -535,3 +452,3 @@ To stop listening: | ||
function someAction({ firebase }) { | ||
firebase.off('posts', 'onChildChanged'); | ||
firebase.off('posts', 'onChildRemoved'); | ||
} | ||
@@ -542,7 +459,7 @@ ``` | ||
```javascript | ||
import {onChildChanged} from '@cerebral/firebase/operators' | ||
import {onChildRemoved} from '@cerebral/firebase/operators' | ||
import {string, signal} from 'cerebral/tags' | ||
export default [ | ||
onChildChanged(string`foo.bar`, signal`some.signal`, { | ||
onChildRemoved(string`foo.bar`, signal`some.signal`, { | ||
// Same options as above | ||
@@ -553,3 +470,3 @@ }) | ||
## off | ||
## onValue | ||
@@ -559,14 +476,15 @@ ### action | ||
function someAction({ firebase }) { | ||
// Turn off listener at specific path and | ||
// specific event | ||
firebase.off('posts', 'onChildChanged') | ||
firebase.onValue('someKey.foo', 'someModule.fooUpdated', { | ||
payload: {}, // Merged with the payload passed on new data | ||
}) | ||
// someModule.fooUpdate called with { value, ...payload } | ||
} | ||
``` | ||
// Turn off all listeners at specific path | ||
firebase.off('posts') | ||
This will **NOT** immediately grab the value and trigger the signal passed, the first event is discarded for more predictable behaviour. To grab existing value, just use `value`. | ||
// Turn off all listeners of specific event at wildcard path | ||
firebase.off('posts.*', 'onChildChanged') | ||
// Turn off all listeners at wildcard path | ||
firebase.off('posts.*') | ||
To stop listening for updates to the value: | ||
```js | ||
function someAction({ firebase }) { | ||
firebase.off('someKey.foo', 'onValue'); | ||
} | ||
@@ -577,26 +495,25 @@ ``` | ||
```javascript | ||
import {string} from 'cerebral/tags' | ||
import {off} from '@cerebral/firebase/operators' | ||
import {onValue} from '@cerebral/firebase/operators' | ||
import {string, signal} from 'cerebral/tags' | ||
export default [ | ||
// Same API as in actions, also wildcard | ||
off('posts', 'onChildChanged'), | ||
// Compose using string tag | ||
off(string`posts.${state`selectedPostKey`}`) | ||
onValue(string`foo.bar`, signal`some.signal`) | ||
] | ||
``` | ||
## task | ||
If you are using the [firebase-queue](https://github.com/firebase/firebase-queue) and need to create tasks, you can do that with: | ||
## push | ||
Generates a new child location using a unique key and returns its reference from the action. An example being `{key: "-KWKImT_t3SLmkJ4s3-w"}`. | ||
### action | ||
```js | ||
function someAction({ firebase, state }) { | ||
return firebase.task('create_post', { | ||
uid: state.get('app.user.uid'), | ||
text: state.get('posts.newPostText') | ||
```javascript | ||
function someAction({firebase}) { | ||
return firebase.push('users', { | ||
name: 'Bob' | ||
}) | ||
.then(() => { | ||
// No output | ||
.then((response) => { | ||
/* | ||
{ | ||
key: 'someKey' | ||
} | ||
*/ | ||
}) | ||
@@ -606,24 +523,14 @@ } | ||
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. | ||
### operator | ||
```javascript | ||
import {state, props} from 'cerebral/tags' | ||
import {task} from '@cerebral/firebase/operators' | ||
import {state} from 'cerebral/tags' | ||
import {push} from '@cerebral/firebase/operators' | ||
export default [ | ||
task('some_task', { | ||
uid: state`user.uid`, | ||
data: props`data` | ||
}), | ||
// No output | ||
// Alternatively with explicit paths | ||
task('some_task', { | ||
uid: state`user.uid`, | ||
data: props`data` | ||
}), { | ||
success: [], | ||
error: [] | ||
} | ||
push('users', state`newUser`), | ||
/* | ||
PROPS: { | ||
response: {...} | ||
} | ||
*/ | ||
] | ||
@@ -634,15 +541,12 @@ ``` | ||
```javascript | ||
import {state, props} from 'cerebral/tags' | ||
import {task} from '@cerebral/firebase/operators' | ||
import {state} from 'cerebral/tags' | ||
import {push} from '@cerebral/firebase/operators' | ||
export default [ | ||
task('some_task', { | ||
uid: state`user.uid`, | ||
data: props`data` | ||
}), { | ||
push('users', state`newUser`), { | ||
success: [ | ||
// No output | ||
/* PROPS: { response: {...} } */ | ||
], | ||
error: [ | ||
// No output | ||
/* PROPS: { error: {...} } */ | ||
] | ||
@@ -653,13 +557,33 @@ } | ||
## getUser | ||
Will resolve to `{user: {}}` if user exists. If user was redirected from Facebook/Google etc. as part of first sign in, this method will handle the confirmed registration of the user. | ||
*output* | ||
```javascript | ||
{key: 'theAddedKey'} | ||
``` | ||
## put | ||
Upload a new file at the given location. Please note that the file is **not** stored inside the realtime database but into Google Cloud Storage (please consult filrebase documentation). This means that you need to take care of storage security as well. | ||
Note that `put` expects a folder as first argument and will use the name of the provided file. If you want to control the filename, add this in the options. In this case, make sure to respect file type and extension... | ||
### action | ||
```js | ||
function someAction({ firebase }) { | ||
return firebase.getUser() | ||
function someAction({ firebase, props }) { | ||
return firebase.put('folderName', props.file, { | ||
progress({progress, bytesTransferred, totalBytes, state}) { | ||
/* do whatever */ | ||
}, | ||
// Override name, make sure you set same extension | ||
filename: 'customName.png' | ||
// optional payload added to progress callback | ||
{ type: 'avatar' | ||
} | ||
}) | ||
.then((response) => { | ||
/* | ||
user: {...}, | ||
isRedirected: false | ||
{ | ||
url: 'urlToFile', | ||
filename: 'nameOfFile' | ||
... payload | ||
} | ||
*/ | ||
@@ -671,7 +595,15 @@ }) | ||
### operator | ||
```javascript | ||
import {getUser} from '@cerebral/firebase/operators' | ||
```js | ||
import {props, signal, string, state} from 'cerebral/tags' | ||
import {put} from '@cerebral/firebase/operators' | ||
// we expect props.file to contain a file provided by | ||
// a user in an <input type='file' /> | ||
export default [ | ||
getUser(), | ||
put(string`posts.all.${props`postId`}`, props`file`, { | ||
// Trigger a signal which receives payload | ||
progress: signal`gallery.progress` | ||
// Set progress on a state value | ||
progress: state`gallery.progress` | ||
}), | ||
/* | ||
@@ -686,7 +618,13 @@ PROPS: { | ||
### operator with paths | ||
```javascript | ||
import {getUser} from '@cerebral/firebase/operators' | ||
```js | ||
import {props, signal, string, state} from 'cerebral/tags' | ||
import {put} from '@cerebral/firebase/operators' | ||
// we expect props.file to contain a file provided by | ||
// a user in an <input type='file' /> | ||
export default [ | ||
getUser(), { | ||
put(string`posts.all.${props`postId`}`, props`file`, { | ||
progress: signal`gallery.progress` | ||
progress: state`gallery.progress` | ||
}), { | ||
success: [ | ||
@@ -702,14 +640,11 @@ /* PROPS: { response: {...} } */ | ||
## signInAnonymously | ||
This login will method will resolve to existing anonymous or create a new one for you. | ||
## remove | ||
Remove the data at this database location. | ||
### action | ||
```js | ||
function someAction({ firebase }) { | ||
return firebase.signInAnonymously() | ||
.then((user) => { | ||
/* | ||
name: 'Bob', | ||
... | ||
*/ | ||
```javascript | ||
function someAction({ firebase}) { | ||
return firebase.remove('foo.bar') | ||
.then(() => { | ||
// No output | ||
}) | ||
@@ -721,11 +656,8 @@ } | ||
```javascript | ||
import {signInAnonymously} from '@cerebral/firebase/operators' | ||
import {props, string} from 'cerebral/tags' | ||
import {remove} from '@cerebral/firebase/operators' | ||
export default [ | ||
signInAnonymously(), | ||
/* | ||
PROPS: { | ||
response: {...} | ||
} | ||
*/ | ||
remove(string`users.${props`userKey`}`), | ||
// No output | ||
] | ||
@@ -736,8 +668,9 @@ ``` | ||
```javascript | ||
import {signInAnonymously} from '@cerebral/firebase/operators' | ||
import {props, string} from 'cerebral/tags' | ||
import {remove} from '@cerebral/firebase/operators' | ||
export default [ | ||
signInAnonymously(), { | ||
remove(string`users.${props`userKey`}`), { | ||
success: [ | ||
/* PROPS: { response: {...} } */ | ||
// No output | ||
], | ||
@@ -751,4 +684,3 @@ error: [ | ||
## createUserWithEmailAndPassword | ||
Register a new user with email and password. | ||
## sendPasswordResetEmail | ||
@@ -758,11 +690,5 @@ ### action | ||
function someAction({ firebase, state }) { | ||
const email = state.get('register.email') | ||
const password = state.get('register.password') | ||
return firebase.createUserWithEmailAndPassword(email, password) | ||
.then((response) => { | ||
/* | ||
name: 'Bob', | ||
... | ||
*/ | ||
return firebase.sendPasswordResetEmail(state.get('user.email')) | ||
.then(() => { | ||
// No output | ||
}) | ||
@@ -775,11 +701,7 @@ } | ||
import {state} from 'cerebral/tags' | ||
import {createUserWithEmailAndPassword} from '@cerebral/firebase/operators' | ||
import {sendPasswordResetEmail} from '@cerebral/firebase/operators' | ||
export default [ | ||
createUserWithEmailAndPassword(state`newUser.email`, state`newUser.password`), | ||
/* | ||
PROPS: { | ||
response: {...} | ||
} | ||
*/ | ||
sendPasswordResetEmail(state`user.email`), | ||
// No output | ||
] | ||
@@ -791,8 +713,8 @@ ``` | ||
import {state} from 'cerebral/tags' | ||
import {createUserWithEmailAndPassword} from '@cerebral/firebase/operators' | ||
import {sendPasswordResetEmail} from '@cerebral/firebase/operators' | ||
export default [ | ||
createUserWithEmailAndPassword(state`newUser.email`, state`newUser.password`), { | ||
sendPasswordResetEmail(state`user.email`), { | ||
success: [ | ||
/* PROPS: { response: {...} } */ | ||
// No output | ||
], | ||
@@ -806,17 +728,11 @@ error: [ | ||
## signInWithEmailAndPassword | ||
Sign in a user with email and password. | ||
## set | ||
Write data to this database location. This will overwrite any data at this location and all child locations. Passing **null** for the new value is equivalent to calling remove(); all data at this location or any child location will be deleted. | ||
### action | ||
```js | ||
function someAction({ firebase, state }) { | ||
const email = state.get('register.email') | ||
const password = state.get('register.password') | ||
return firebase.signInWithEmailAndPassword(email, password) | ||
.then((response) => { | ||
/* | ||
name: 'Bob', | ||
... | ||
*/ | ||
```javascript | ||
function someAction({firebase}) { | ||
return firebase.set('foo.bar', 'baz') | ||
.then(() => { | ||
// No output | ||
}) | ||
@@ -829,11 +745,7 @@ } | ||
import {props} from 'cerebral/tags' | ||
import {signInWithEmailAndPassword} from '@cerebral/firebase/operators' | ||
import {set} from '@cerebral/firebase/operators' | ||
export default [ | ||
signInWithEmailAndPassword(props`email`, props`password`), | ||
/* | ||
PROPS: { | ||
response: {...} | ||
} | ||
*/ | ||
set('foo.bar', props`foo`), | ||
// No output | ||
] | ||
@@ -845,8 +757,8 @@ ``` | ||
import {props} from 'cerebral/tags' | ||
import {signInWithEmailAndPassword} from '@cerebral/firebase/operators' | ||
import {set} from '@cerebral/firebase/operators' | ||
export default [ | ||
signInWithEmailAndPassword(props`email`, props`password`), { | ||
set('foo.bar', props`foo`), { | ||
success: [ | ||
/* PROPS: { response: {...} } */ | ||
// No output | ||
], | ||
@@ -860,4 +772,4 @@ error: [ | ||
## signInWith{PROVIDER} | ||
Sign in a user with Facebook, Google or Github. | ||
## setOnDisconnect | ||
Sets a value when Firebase detects user has disconnected. | ||
@@ -867,7 +779,24 @@ ### action | ||
function someAction({ firebase, state }) { | ||
return firebase.signInWithFacebook({ | ||
redirect: false, // Use popup or redirect. Redirect typically for mobile | ||
scopes: [] // Facebook scopes to access | ||
}) | ||
.then((response) => { | ||
firebase.setOnDisconnect(`activeUsers.${state.get('app.user.uid')}`, 'someValue') | ||
} | ||
``` | ||
### operator | ||
```javascript | ||
import {state} from 'cerebral/tags' | ||
import {setOnDisconnect} from '@cerebral/firebase/operators' | ||
export default [ | ||
setOnDisconnect(string`activeUsers.${state`app.user.uid`}`, null) | ||
] | ||
``` | ||
## signInAnonymously | ||
This login will method will resolve to existing anonymous or create a new one for you. | ||
### action | ||
```js | ||
function someAction({ firebase }) { | ||
return firebase.signInAnonymously() | ||
.then((user) => { | ||
/* | ||
@@ -883,9 +812,6 @@ name: 'Bob', | ||
```javascript | ||
import {state} from 'cerebral/tags' | ||
import {signInWithFacebook} from '@cerebral/firebase/operators' | ||
import {signInAnonymously} from '@cerebral/firebase/operators' | ||
export default [ | ||
signInWithFacebook({ | ||
redirect: state`useragent.media.small` | ||
}), | ||
signInAnonymously(), | ||
/* | ||
@@ -901,9 +827,6 @@ PROPS: { | ||
```javascript | ||
import {state} from 'cerebral/tags' | ||
import {signInWithFacebook} from '@cerebral/firebase/operators' | ||
import {signInAnonymously} from '@cerebral/firebase/operators' | ||
export default [ | ||
signInWithFacebook({ | ||
redirect: state`useragent.media.small` | ||
}), { | ||
signInAnonymously(), { | ||
success: [ | ||
@@ -919,5 +842,2 @@ /* PROPS: { response: {...} } */ | ||
Similar you can sign in with Google or GitHub. | ||
Just use `signInWithGoogle` or `signInWithGithub` instead of `signInWithFacebook`. | ||
## signInWithCustomToken | ||
@@ -954,4 +874,4 @@ Sign in a custom token. | ||
## linkWithFacebook{PROVIDER} | ||
Link an anonymous account with Facebook, Google or Github. | ||
## signInWithEmailAndPassword | ||
Sign in a user with email and password. | ||
@@ -961,3 +881,54 @@ ### action | ||
function someAction({ firebase, state }) { | ||
return firebase.linkWithFacebook({ | ||
const email = state.get('register.email') | ||
const password = state.get('register.password') | ||
return firebase.signInWithEmailAndPassword(email, password) | ||
.then((response) => { | ||
/* | ||
name: 'Bob', | ||
... | ||
*/ | ||
}) | ||
} | ||
``` | ||
### operator | ||
```javascript | ||
import {props} from 'cerebral/tags' | ||
import {signInWithEmailAndPassword} from '@cerebral/firebase/operators' | ||
export default [ | ||
signInWithEmailAndPassword(props`email`, props`password`), | ||
/* | ||
PROPS: { | ||
response: {...} | ||
} | ||
*/ | ||
] | ||
``` | ||
### operator with paths | ||
```javascript | ||
import {props} from 'cerebral/tags' | ||
import {signInWithEmailAndPassword} from '@cerebral/firebase/operators' | ||
export default [ | ||
signInWithEmailAndPassword(props`email`, props`password`), { | ||
success: [ | ||
/* PROPS: { response: {...} } */ | ||
], | ||
error: [ | ||
/* PROPS: { error: {...} } */ | ||
] | ||
} | ||
] | ||
``` | ||
## signInWith{PROVIDER} | ||
Sign in a user with Facebook, Google or Github. | ||
### action | ||
```js | ||
function someAction({ firebase, state }) { | ||
return firebase.signInWithFacebook({ | ||
redirect: false, // Use popup or redirect. Redirect typically for mobile | ||
@@ -978,6 +949,6 @@ scopes: [] // Facebook scopes to access | ||
import {state} from 'cerebral/tags' | ||
import {linkWithFacebook} from '@cerebral/firebase/operators' | ||
import {signInWithFacebook} from '@cerebral/firebase/operators' | ||
export default [ | ||
linkWithFacebook({ | ||
signInWithFacebook({ | ||
redirect: state`useragent.media.small` | ||
@@ -996,6 +967,6 @@ }), | ||
import {state} from 'cerebral/tags' | ||
import {linkWithFacebook} from '@cerebral/firebase/operators' | ||
import {signInWithFacebook} from '@cerebral/firebase/operators' | ||
export default [ | ||
linkWithFacebook({ | ||
signInWithFacebook({ | ||
redirect: state`useragent.media.small` | ||
@@ -1014,3 +985,3 @@ }), { | ||
Similar you can sign in with Google or GitHub. | ||
Just use `linkWithGoogle` or `linkWithGithub` instead of `linkWithFacebook`. | ||
Just use `signInWithGoogle` or `signInWithGithub` instead of `signInWithFacebook`. | ||
@@ -1056,3 +1027,4 @@ ## signOut | ||
## sendPasswordResetEmail | ||
## task | ||
If you are using the [firebase-queue](https://github.com/firebase/firebase-queue) and need to create tasks, you can do that with: | ||
@@ -1062,3 +1034,6 @@ ### action | ||
function someAction({ firebase, state }) { | ||
return firebase.sendPasswordResetEmail(state.get('user.email')) | ||
return firebase.task('create_post', { | ||
uid: state.get('app.user.uid'), | ||
text: state.get('posts.newPostText') | ||
}) | ||
.then(() => { | ||
@@ -1070,10 +1045,24 @@ // No output | ||
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. | ||
### operator | ||
```javascript | ||
import {state} from 'cerebral/tags' | ||
import {sendPasswordResetEmail} from '@cerebral/firebase/operators' | ||
import {state, props} from 'cerebral/tags' | ||
import {task} from '@cerebral/firebase/operators' | ||
export default [ | ||
sendPasswordResetEmail(state`user.email`), | ||
task('some_task', { | ||
uid: state`user.uid`, | ||
data: props`data` | ||
}), | ||
// No output | ||
// Alternatively with explicit paths | ||
task('some_task', { | ||
uid: state`user.uid`, | ||
data: props`data` | ||
}), { | ||
success: [], | ||
error: [] | ||
} | ||
] | ||
@@ -1084,7 +1073,10 @@ ``` | ||
```javascript | ||
import {state} from 'cerebral/tags' | ||
import {sendPasswordResetEmail} from '@cerebral/firebase/operators' | ||
import {state, props} from 'cerebral/tags' | ||
import {task} from '@cerebral/firebase/operators' | ||
export default [ | ||
sendPasswordResetEmail(state`user.email`), { | ||
task('some_task', { | ||
uid: state`user.uid`, | ||
data: props`data` | ||
}), { | ||
success: [ | ||
@@ -1094,3 +1086,3 @@ // No output | ||
error: [ | ||
/* PROPS: { error: {...} } */ | ||
// No output | ||
] | ||
@@ -1101,65 +1093,92 @@ } | ||
## setOnDisconnect | ||
Sets a value when Firebase detects user has disconnected. | ||
## transaction | ||
Atomically modifies the data at the provided location. | ||
Unlike a normal set(), which just overwrites the data regardless of its previous value, transaction() is used to modify the existing value to a new value, ensuring there are no conflicts with other clients writing to the same location at the same time. | ||
To accomplish this, you pass transaction() an update function which is used to transform the current value into a new value. If another client writes to the location before your new value is successfully written, your update function will be called again with the new current value, and the write will be retried. This will happen repeatedly until your write succeeds without conflict or you abort the transaction by not returning a value from your update function. | ||
### action | ||
```js | ||
function someAction({ firebase, state }) { | ||
firebase.setOnDisconnect(`activeUsers.${state.get('app.user.uid')}`, 'someValue') | ||
```javascript | ||
function someAction({firebase}) { | ||
function transactionFunction(currentData){ | ||
if (currentData === null) { | ||
return { foo: 'bar' } | ||
} | ||
return // Abort the transaction. | ||
} | ||
return firebase.transaction('some.transaction.path', transactionFunction) | ||
.then((result) => { | ||
if(result.committed){ | ||
return {result: result.value} | ||
} else { | ||
throw new Error('Transaction failed') | ||
} | ||
}) | ||
.then((response) => { | ||
/* | ||
{ | ||
committed: true, | ||
value: 'new value' | ||
} | ||
*/ | ||
}) | ||
} | ||
``` | ||
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. | ||
### operator | ||
```javascript | ||
import {state} from 'cerebral/tags' | ||
import {setOnDisconnect} from '@cerebral/firebase/operators' | ||
import {transaction} from '@cerebral/firebase/operators' | ||
function transactionFunction() {...} | ||
export default [ | ||
setOnDisconnect(string`activeUsers.${state`app.user.uid`}`, null) | ||
transaction('foo.bar', transactionFunction), | ||
/* | ||
PROPS: { | ||
response: {...} | ||
} | ||
*/ | ||
] | ||
``` | ||
## cancelOnDisconnect | ||
Cancel setting a value when Firebase detects disconnect. | ||
### operator with paths | ||
```javascript | ||
import {transaction} from '@cerebral/firebase/operators' | ||
### action | ||
```js | ||
function someAction({ firebase, state }) { | ||
firebase.cancelOnDisconnect() | ||
} | ||
``` | ||
function transactionFunction() {...} | ||
### operator | ||
```javascript | ||
import {state} from 'cerebral/tags' | ||
import {cancelOnDisconnect} from '@cerebral/firebase/operators' | ||
export default [ | ||
cancelOnDisconnect() | ||
transaction('foo.bar', transactionFunction), { | ||
success: [ | ||
/* PROPS: { response: {...} } */ | ||
], | ||
error: [ | ||
// No output | ||
] | ||
} | ||
] | ||
``` | ||
## put | ||
Note: Modifying data with set() will cancel any pending transactions at that location, so extreme care should be taken if mixing set() and transaction() to update the same data. | ||
Upload a new file at the given location. Please note that the file is **not** stored inside the realtime database but into Google Cloud Storage (please consult filrebase documentation). This means that you need to take care of storage security as well. | ||
Note: When using transactions with Security and Firebase Rules in place, be aware that a client needs .read access in addition to .write access in order to perform a transaction. This is because the client-side nature of transactions requires the client to read the data in order to transactionally update it. | ||
Note that `put` expects a folder as first argument and will use the name of the provided file. If you want to control the filename, add this in the options. In this case, make sure to respect file type and extension... | ||
## update | ||
As opposed to the set() method, update() can be use to selectively update only the referenced properties at the current location (instead of replacing all the child properties at the current location). | ||
### action | ||
```js | ||
function someAction({ firebase, props }) { | ||
return firebase.put('folderName', props.file, { | ||
progress({progress, bytesTransferred, totalBytes, state}) { | ||
/* do whatever */ | ||
}, | ||
// Override name, make sure you set same extension | ||
filename: 'customName.png' | ||
```javascript | ||
function someAction({firebase}) { | ||
return firebase.update('some.path', { | ||
'foo': 'bar', | ||
'items.item1.isAwesome': true | ||
}) | ||
.then((response) => { | ||
/* | ||
{ | ||
url: 'urlToFile', | ||
filename: 'nameOfFile' | ||
} | ||
*/ | ||
.then(() => { | ||
// No output | ||
}) | ||
@@ -1170,20 +1189,21 @@ } | ||
### operator | ||
```js | ||
import {props, signal, string, state} from 'cerebral/tags' | ||
import {put} from '@cerebral/firebase/operators' | ||
```javascript | ||
import {props} from 'cerebral/tags' | ||
import {update} from '@cerebral/firebase/operators' | ||
// we expect props.file to contain a file provided by | ||
// a user in an <input type='file' /> | ||
export default [ | ||
put(string`posts.all.${props`postId`}`, props`file`, { | ||
// Trigger a signal which receives payload | ||
progress: signal`gallery.progress` | ||
// Set progress on a state value | ||
progress: state`gallery.progress` | ||
update('some.path', { | ||
'foo.bar': props`bar`, | ||
'foo.baz': props`baz` | ||
}), | ||
/* | ||
PROPS: { | ||
response: {...} | ||
} | ||
*/ | ||
// No output | ||
// Alternatively with explicit paths | ||
update('some.path', { | ||
'foo.bar': props`bar`, | ||
'foo.baz': props`baz` | ||
}), { | ||
success: [], | ||
error: [] | ||
} | ||
] | ||
@@ -1193,15 +1213,13 @@ ``` | ||
### operator with paths | ||
```js | ||
import {props, signal, string, state} from 'cerebral/tags' | ||
import {put} from '@cerebral/firebase/operators' | ||
```javascript | ||
import {props} from 'cerebral/tags' | ||
import {update} from '@cerebral/firebase/operators' | ||
// we expect props.file to contain a file provided by | ||
// a user in an <input type='file' /> | ||
export default [ | ||
put(string`posts.all.${props`postId`}`, props`file`, { | ||
progress: signal`gallery.progress` | ||
progress: state`gallery.progress` | ||
update('some.path', { | ||
'foo.bar': props`bar`, | ||
'foo.baz': props`baz` | ||
}), { | ||
success: [ | ||
/* PROPS: { response: {...} } */ | ||
// No output | ||
], | ||
@@ -1215,12 +1233,15 @@ error: [ | ||
## delete | ||
## value | ||
Use `delete` to remove an uploaded file. Specify the containing folder and filename. | ||
### action | ||
```js | ||
function someAction({ firebase, props }) { | ||
return firebase.delete('folderName', props.fileName) | ||
.then(() => { | ||
// No output | ||
function someAction({ firebase }) { | ||
return firebase.value('someKey.foo') | ||
.then((response) => { | ||
/* | ||
{ | ||
key: 'foo', | ||
value: 'some value' | ||
} | ||
*/ | ||
}) | ||
@@ -1231,18 +1252,15 @@ } | ||
### operator | ||
```js | ||
import {props, state, string} from 'cerebral/tags' | ||
import {delete as firebaseDelete} from '@cerebral/firebase/operators' | ||
```javascript | ||
import {value} from '@cerebral/firebase/operators' | ||
import {state} from 'cerebral/tags' | ||
export default [ | ||
firebaseDelete( | ||
string`posts.all.${props`postId`}`, | ||
state`posts.all.${props`postId`}.imageName` | ||
), | ||
// No output | ||
value('foo.bar'), | ||
/* | ||
PROPS: { | ||
response: {...} | ||
} | ||
*/ | ||
// Alternatively with explicit paths | ||
firebaseDelete( | ||
string`posts.all.${props`postId`}`, | ||
state`posts.all.${props`postId`}.imageName` | ||
), { | ||
value('foo.bar'), { | ||
success: [], | ||
@@ -1255,13 +1273,9 @@ error: [] | ||
### operator with paths | ||
```js | ||
import {props, state, string} from 'cerebral/tags' | ||
import {delete as firebaseDelete} from '@cerebral/firebase/operators' | ||
```javascript | ||
import {value} from '@cerebral/firebase/operators' | ||
export default [ | ||
firebaseDelete( | ||
string`posts.all.${props`postId`}`, | ||
state`posts.all.${props`postId`}.imageName` | ||
), { | ||
value('foo.bar'), { | ||
success: [ | ||
// No output | ||
/* PROPS: { response: {...} } */ | ||
], | ||
@@ -1268,0 +1282,0 @@ error: [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
183451
131
1851
1224
2