Skip to content

Commit aa8d75b

Browse files
authored
* display name logic is now internal (eliminates dependency) * `try/catch` added around usage of profileFactory (incase provided `profileFactory` function throws an error) * Fix possibility of race condition with `uniqueSet` - prescottprue#207 * Fix issue using storeAs with populates - prescottprue#216 * Profile docs improved for clarity * `.eslintrc` added to tests folder (extends base`.eslintrc`) * `PULL_REQUEST_TEMPLATE` simplified * `ISSUE_TEMPLATE` simplified and includes link to [codesandbox](https://codesandbox.io/) instead of [codepen](http://codepen.io) * Lint removed from tests
1 parent 747a117 commit aa8d75b

27 files changed

+259
-357
lines changed

.eslintignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
examples/**
22
coverage/**
33
node_modules/**
4-
*.spec.js

.github/ISSUE_TEMPLATE.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
**Do you want to request a *feature* or report a *bug*?**
22

3-
(If this is a *usage question*, please **do not post it here**—post it on [gitter](https://gitter.im/redux-firebase/Lobby) or [Stack Overflow](http://stackoverflow.com/questions/tagged/react-redux-firebase) instead. If this is not a “feature” or a “bug”, or the phrase “How do I...?” applies, then it's probably a usage question.)
3+
(If this is a *usage question*, please **do not post it here**—post it on [gitter](https://gitter.im/redux-firebase/Lobby). If this is not a “feature” or a “bug”, or the phrase “How do I...?” applies, then it's probably a usage question.)
44

55

66
**What is the current behavior?**
77

88

99

10-
**If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar.**
10+
**If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via [codesandbox](https://codesandbox.io/) or similar.**
1111

1212

1313

@@ -18,4 +18,4 @@
1818
**Which versions of dependencies, and which browser and OS are affected by this issue? Did this work in previous versions or setups?**
1919

2020
<!-- Love react-redux-firebase? Please consider supporting our collective:
21-
👉 https://opencollective.com/react-redux-firebase/donate -->
21+
👉 https://opencollective.com/react-redux-firebase/donate -->

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
### Description
22

3-
<!-- Write Your Description Here ^ -->
4-
<!-- Some things that may be of interest to address:
5-
- Will a new version need to be released or is this a docs change?
6-
- Which version should this be published as a part of? ("ASAP", "no idea", and specific version number)
7-
- Does this impact the external API?
8-
- Will it need to be a breaking change? -->
93

104
### Check List
115
If not relevant to pull request, check off as complete
126

137
- [ ] All tests passing
14-
- [ ] Docs updated with any changes or examples
15-
- [ ] Added tests to ensure feature(s) work properly
8+
- [ ] Docs updated with any changes or examples if applicable
9+
- [ ] Added tests to ensure new feature(s) work properly
1610

1711
### Relevant Issues
18-
<!-- List Relevant Issues here -->
1912
<!-- * #1 -->

docs/auth.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,31 @@ export default firebaseConnect()(SomeComponent)
7878
```
7979

8080

81+
After logging in, profile and auth are available in redux state:
82+
83+
```js
84+
import { connect } from 'react-redux'
85+
86+
connect(() => ({
87+
auth: pathToJS(firebase, 'auth'),
88+
profile: pathToJS(firebase, 'profile')
89+
}))(SomeComponent)
90+
```
91+
92+
For more information on how best to use these methods, visit the [auth recipes](/docs/recipes/auth.md)
93+
8194
##### Returns
82-
[**Promise**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) with an object containing profile, user, (also credential if using oAuth provider) in case of success or the error otherwise.
95+
[**Promise**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) with an object (or a string, see note) containing profile, user, (also credential if using oAuth provider) in case of success or the error otherwise.
96+
97+
**NOTE**: For email authentication in `v1.4.*` and earlier - The user's UID (a [**String**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)) is returned instead of an object. This will change in `v1.5.0` for consistency across all auth types.
8398
8499
##### Examples
85100
101+
For complete usage examples visit the [auth recipes](/docs/recipes/auth.md)
102+
86103
*Email*
87104
```js
88-
// Call with info
105+
// NOTE: Account is not created during login for email auth. Use createUser
89106
this.props.firebase.login({
90107
email: 'test@test.com',
91108
password: 'testest1'

docs/queries.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# Queries
22

3-
When listening to paths, it is possible to modify the query with any of [Firebase's included query methods](https://firebase.google.com/docs/reference/js/firebase.database.Query). Below are examples using Firebase query methods as well as other methods that are included (such as 'populate').
3+
Query listeners are attached by using the `firebaseConnect` higher order component. `firebaseConnect` accepts an array of paths for which to create queries. When listening to paths, it is possible to modify the query with any of [Firebase's included query methods](https://firebase.google.com/docs/reference/js/firebase.database.Query).
4+
5+
**NOTE:**
6+
By default the results of queries are stored in redux under the path of the query. If you would like to change where the query results are stored in redux, use [`storeAs` (more below)](#storeAs).
7+
8+
Below are examples using Firebase query methods as well as other methods that are included (such as 'populate').
49

510
## once
611
To load a firebase location once instead of binding, the once option can be used:
@@ -195,6 +200,41 @@ Can be used to keep internal parsing from happening. Useful when attempting to s
195200
])
196201
```
197202

203+
204+
## storeAs {#populate}
205+
206+
By default the results of queries are stored in redux under the path of the query. If you would like to change where the query results are stored in redux, use `storeAs`:
207+
208+
#### Examples
209+
1. Querying the same path with different query parameters
210+
211+
```js
212+
@firebaseConnect(props => [
213+
{ path: 'projects' }
214+
{ path: 'projects', storeAs: 'myProjects', queryParams: ['orderByChild=uid', '123'] }
215+
])
216+
@connect(({ firebase }, props) => ({
217+
projects: populatedDataToJS(firebase, 'projects'),
218+
myProjects: populatedDataToJS(firebase, 'myProjects'), // use storeAs path to gather from redux
219+
}))
220+
```
221+
222+
## ordered {#ordered}
223+
224+
In order to get ordered data, use `orderedToJS`
225+
226+
#### Examples
227+
1. Get list of projects ordered by key
228+
229+
```js
230+
@firebaseConnect(props => [
231+
{ path: 'projects', queryParams: ['orderByKey'] }
232+
])
233+
@connect(({ firebase }, props) => ({
234+
projects: orderedToJS(firebase, 'projects'),
235+
}))
236+
```
237+
198238
## Populate {#populate}
199239

200240
Populate allows you to replace IDs within your data with other data from Firebase. This is very useful when trying to keep your data flat. Some would call it a _join_, but it was modeled after [the mongo populate method](http://mongoosejs.com/docs/populate.html).

docs/recipes/profile.md

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,50 @@
1-
### Change Profile
2-
When signing up, you can modify how user profiles written to the database.
1+
# Profile
2+
3+
Profile object is used to store data associated with a user.
4+
5+
## Basic
6+
Include the `userProfile` parameter in config when setting up store middleware:
7+
8+
```js
9+
const config = {
10+
userProfile: 'users', // where profiles are stored in database
11+
}
12+
reactReduxFirebase(fbConfig, config)
13+
```
14+
15+
Then later wrap a component with connect:
16+
17+
```js
18+
import { connect } from 'react-redux'
19+
import { pathToJS } from 'react-redux-firebase'
20+
21+
// grab profile from redux with connect
22+
connect((state) => {
23+
return {
24+
profile: pathToJS(state.firebase, 'profile') // profile passed as props.profile
25+
}
26+
}))(SomeComponent) // pass component to be wrapped
27+
28+
// or with some shorthand:
29+
connect(({ firebase }) => ({
30+
profile: pathToJS(state.firebase, 'profile') // profile passed as props.profile
31+
}))(SomeComponent) // pass component to be wrapped
32+
```
33+
34+
## Update Profile
35+
36+
**NOTE:** This feature is only available in [`v1.5.*`](http://docs.react-redux-firebase.com/history/v1.5.0/docs/recipes/profile.html)
37+
38+
The current users profile can be updated by using the `updateProfile` method, which is [only available in `v1.5.*`](http://docs.react-redux-firebase.com/history/v1.5.0/docs/recipes/profile.html).
39+
40+
## Change How Profiles Are Stored
41+
The way user profiles are written to the database can be modified by passing the `profileFactory` parameter.
342

443
```js
544
// within your createStore.js or store.js file include the following config
645
const config = {
746
userProfile: 'users', // where profiles are stored in database
8-
profileFactory: (userData) => { // how profiles are stored in database
47+
profileFactory: (userData, profileData) => { // how profiles are stored in database
948
const { user } = userData
1049
return {
1150
email: user.email
@@ -14,7 +53,13 @@ const config = {
1453
}
1554
```
1655

17-
### Populate Parameters
56+
## List Online Users
57+
58+
**NOTE:** This feature is only available in [`v2.0.0-*`](http://docs.react-redux-firebase.com/history/v2.0.0/)
59+
60+
To list online users and/or track sessions, view the [presence recipe](http://docs.react-redux-firebase.com/history/v2.0.0/docs/recipes/auth.html#list-of-online-users-presence)
61+
62+
## Populate Parameters
1863
If profile object contains an key or a list of keys as parameters, you can populate those parameters with the matching value from another location on firebase.
1964

2065
#### List

examples/complete/material/src/routes/Home/containers/HomeContainer.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import {
66
firebaseConnect,
77
isLoaded,
88
pathToJS,
9-
dataToJS // needed for full list and once
10-
// orderedToJS // needed for ordered list
9+
dataToJS, // needed for full list and once
10+
// orderedToJS, // needed for ordered list
1111
// populatedDataToJS // needed for populated list
1212
} from 'react-redux-firebase'
1313
import CircularProgress from 'material-ui/CircularProgress'
@@ -19,19 +19,22 @@ import TodoItem from '../components/TodoItem'
1919
import NewTodoPanel from '../components/NewTodoPanel'
2020
import classes from './HomeContainer.scss'
2121

22-
// const populates = [{ child: 'owner', root: 'users', keyProp: 'uid' }]
22+
const populates = [{ child: 'owner', root: 'users', keyProp: 'uid' }]
2323

2424
@firebaseConnect([
2525
// 'todos' // sync full list of todos
2626
// { path: 'todos', type: 'once' } // for loading once instead of binding
2727
{ path: 'todos', queryParams: ['orderByKey', 'limitToLast=5'] } // 10 most recent
2828
// { path: 'todos', populates } // populate
29+
// { path: 'todos', storeAs: 'myTodos' } // store elsewhere in redux
2930
])
3031
@connect(({ firebase }) => ({
3132
auth: pathToJS(firebase, 'auth'),
3233
account: pathToJS(firebase, 'profile'),
33-
todos: dataToJS(firebase, 'todos')
34-
// todos: populatedDataToJS(firebase, '/todos', populates), // if populating
34+
todos: dataToJS(firebase, 'todos'),
35+
// todos: orderedToJS(firebase, 'todos') // if looking for array
36+
// todos: dataToJS(firebase, 'myTodos'), // if using storeAs
37+
// todos: populatedDataToJS(firebase, 'todos', populates), // if populating
3538
// todos: orderedToJS(firebase, '/todos') // if using ordering such as orderByChild
3639
}))
3740
export default class Home extends Component {

package.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
{
22
"name": "react-redux-firebase",
3-
"version": "1.4.4",
3+
"version": "1.4.5",
44
"description": "Redux integration for Firebase. Comes with a Higher Order Component for use with React.",
55
"browser": "dist/react-redux-firebase.js",
66
"main": "lib/index.js",
77
"module": "es/index.js",
88
"jsnext:main": "es/index.js",
99
"scripts": {
1010
"clean": "rimraf dist",
11-
"lint": "eslint src/** test/**",
11+
"lint": "eslint src/** tests/**/**",
1212
"lint:fix": "npm run lint -- --fix",
1313
"test": "mocha -R spec --compilers js:babel-core/register ./tests/setup.js ./tests/**/*.spec.js",
1414
"test:cov": "istanbul cover ./node_modules/mocha/bin/_mocha -- ./tests/** --recursive --report lcov --compilers js:babel-register --require babel-polyfill",
@@ -32,11 +32,10 @@
3232
"dependencies": {
3333
"es6-promise": "^4.1.0",
3434
"firebase": "^3.9.0",
35-
"hoist-non-react-statics": "^1.2.0",
35+
"hoist-non-react-statics": "^2.2.0",
3636
"immutable": "^3.8.1",
3737
"jwt-decode": "^2.2.0",
38-
"lodash": "^4.17.4",
39-
"react-display-name": "^0.2.0"
38+
"lodash": "^4.17.4"
4039
},
4140
"peerDependencies": {
4241
"react": "^0.14.6 || ^15.0.0"

src/actions/auth.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -198,14 +198,17 @@ export const createUserProfile = (dispatch, firebase, userData, profile) => {
198198
return Promise.resolve(userData)
199199
}
200200
const { database, _: { config } } = firebase
201-
if (isFunction(config.profileFactory)) {
202-
profile = config.profileFactory(userData, profile)
203-
}
204-
if (isFunction(config.profileDecorator)) {
205-
if (isFunction(console.warn)) { // eslint-disable-line no-console
201+
try {
202+
if (isFunction(config.profileFactory)) {
203+
profile = config.profileFactory(userData, profile)
204+
}
205+
if (isFunction(config.profileDecorator)) {
206206
console.warn('profileDecorator is Depreceated and will be removed in future versions. Please use profileFactory.') // eslint-disable-line no-console
207+
profile = config.profileDecorator(userData, profile)
207208
}
208-
profile = config.profileDecorator(userData, profile)
209+
} catch (err) {
210+
console.error('Error occured within profileFactory function:', err.toString ? err.toString() : err) // eslint-disable-line no-console
211+
return Promise.reject(err)
209212
}
210213
// Check for user's profile at userProfile path if provided
211214
return database()

src/actions/query.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ export const watchEvent = (firebase, dispatch, { type, path, populates, queryPar
148148
})
149149
dispatch({
150150
type: SET,
151-
path: resultPath,
151+
path: storeAs || resultPath,
152152
data,
153153
timestamp: Date.now(),
154154
requesting: false,

0 commit comments

Comments
 (0)