Skip to content

Commit 10d5681

Browse files
authored
v2.0.0-beta.13 (#306)
* fix(reducers): add `EMPTY_AUTH_CHANGE` case to Profile Reducer - #305 * feat(constants): `enableEmptyAuthChanges` config option replaced by `preserveOnEmptyAuthChange` - #305 * feat(profile): `autoPopulateProfile` support for v2 (still `disabled` by default) * fix(presence): support presence option on `react-native-firebase` versions without `setPriority` on `RNFirebase.database.ThenableReference` - #267 * fix(core): withFirebase now works for all main methods * feat(examples): material example updated to be much more simple (uses mostly functional components over classes) * feat(docs): `promiseEvents` added to SSR docs - #299
1 parent 8265868 commit 10d5681

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+5749
-1171
lines changed

.codeclimate.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ languages:
33

44
exclude_paths:
55
- "lib/**"
6-
- "test/**"
6+
- "tests/**"
77
- "examples/**"
88
- "LICENSE"
99
- "LICENSE.md"

README.md

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,25 +36,20 @@ The [Material Example](https://github.com/prescottprue/react-redux-firebase/tree
3636
## Install
3737

3838
```bash
39-
npm install --save react-redux-firebase
39+
npm install --save react-redux-firebase@next
4040
```
4141

4242
## Use
4343

44-
Include `reactReduxFirebase` in your store compose function and `firebaseStateReducer` in your reducers:
44+
Include `reactReduxFirebase` in your store compose function and `firebaseReducer` in your reducers:
4545

4646
```javascript
4747
import { createStore, combineReducers, compose } from 'redux'
48-
import { reactReduxFirebase, firebaseStateReducer } from 'react-redux-firebase'
48+
import { reactReduxFirebase, firebaseReducer } from 'react-redux-firebase'
4949
import firebase from 'firebase'
5050
// import 'firebase/firestore' // <- needed if using firestore
5151

52-
const firebaseConfig = {
53-
apiKey: '<your-api-key>',
54-
authDomain: '<your-auth-domain>',
55-
databaseURL: '<your-database-url>',
56-
storageBucket: '<your-storage-bucket>'
57-
}
52+
const firebaseConfig = {}
5853

5954
// react-redux-firebase config
6055
const rrfConfig = {
@@ -279,8 +274,6 @@ Thank you to all our backers! 🙏
279274

280275
* [Reside Network Inc.](https://github.com/reside-eng)
281276

282-
<a href="https://opencollective.com/react-redux-firebase#backers" target="_blank"><img src="https://opencollective.com/react-redux-firebase/backers.svg?width=890"></a>
283-
284277
[npm-image]: https://img.shields.io/npm/v/react-redux-firebase.svg?style=flat-square
285278
[npm-url]: https://npmjs.org/package/react-redux-firebase
286279
[npm-downloads-image]: https://img.shields.io/npm/dm/react-redux-firebase.svg?style=flat-square

SUMMARY.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
* [Populate](/docs/recipes/populate.md)
1818
* [Upload](/docs/recipes/upload.md)
1919
* [Server Side Rendering](/docs/recipes/ssr.md)
20-
* [Performance](/docs/recipes/performance.md)
2120
* [Integrations](/docs/integrations/README.md)
2221
* [Redux Thunk](/docs/integrations/thunks.md)
2322
* [Redux Form](/docs/integrations/redux-form.md)

docs/api/constants.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,12 @@ Default configuration options
9292
- `preserveOnLogout` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object))** `null` Data parameters to
9393
preserve when logging out. If Array is passed, each item represents keys
9494
within state.firebase.data preserve. If an object is passed, Keys associate
95-
with parts of state to preserve, and the values are Arrays which
96-
associate with which keys to preserve form that section of state.
95+
with parts of state to preserve, and the values are Arrays contain keys
96+
for keys within that slice of state to preserve.
97+
- `preserveOnEmptyAuthChange` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** `null` Data parameters to
98+
preserve when logging out. Keys associate with parts of state to preserve,
99+
and the values are Arrays contain keys for keys within that slice of state
100+
to preserve.
97101
- `updateProfileOnLogin` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** `true` Whether or not to update
98102
user profile when logging in.
99103
- `resetBeforeLogin` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** `true` Whether or not to reset auth

docs/api/enhancer.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,14 @@ along side applyMiddleware.
3535
with parts of state to preserve, and the values are Arrays which
3636
associate with which keys to preserve form that section of state.
3737
(default: `null`)
38+
- `config.preserveOnEmptyAuthChange` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** `null` Data parameters to
39+
preserve when logging out. Keys associate with parts of state to preserve,
40+
and the values are Arrays contain keys for keys within that slice of state
41+
to preserve.
3842
- `config.enableRedirectHandling` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Whether or not to enable
3943
auth redirect handling listener. (default: `true`)
4044
- `config.onAuthStateChanged` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** Function run when auth state
4145
changes. Argument Pattern: `(authData, firebase, dispatch)`
42-
- `config.enableEmptyAuthChanges` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Whether or not to enable
43-
empty auth changes. When set to true, `onAuthStateChanged` will be fired with,
44-
empty auth changes such as undefined on initialization. See
45-
[#137](https://github.com/prescottprue/react-redux-firebase/issues/137) for
46-
more details. (default: `false`)
4746
- `config.onRedirectResult` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** Function run when redirect
4847
result is returned. Argument Pattern: `(authData, firebase, dispatch)`
4948
- `config.customAuthParameters` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object for setting which

docs/api/helpers.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ const defaultValue = {
6666
}
6767
}
6868
const enhance = compose(
69-
firebaseConnect(['/todos/user1'])
69+
firebaseConnect(['/todos/user1']),
7070
connect(({ firebase }) => ({
7171
// this.props.todos loaded from state.firebase.data.todos
7272
todos: getVal(firebase, 'data/todos/user1', defaultValue)

docs/integrations/redux-saga.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,4 @@ export default (initialState = {}, history) => {
4545

4646
// when calling saga, pass getFirebase
4747
sagaMiddleware.run(helloSaga, getFirebase)
48-
4948
```
File renamed without changes.

docs/populate.md

Lines changed: 61 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,31 @@
22

33
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).
44

5-
Initial data from populate is placed into redux in a normalized pattern [following defined redux practice of normalizing](http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html). `populatedDataToJS` helper used in the `connect` function then builds populated data out of normalized data within redux (**NOTE:** This does not apply if you are using `v1.1.5` or earlier).
5+
Initial data from populate is placed into redux in a normalized pattern [following defined redux practice of normalizing](http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html). `populate` helper used within the `connect` function then builds populated data out of normalized data within redux (**NOTE:** This does not apply if you are using `v1.1.5` or earlier).
66

77
A basic implementation can look like so:
88
```javascript
9+
import { compose } from 'redux'
10+
import { connect } from 'react-redux'
11+
import { firebaseConnect } from 'react-redux-firebase'
12+
913
const populates = [
1014
{ child: 'owner', root: 'users' } // replace owner with user object
1115
]
1216

13-
@firebaseConnect([
14-
// passing populates parameter also creates all necessary child queries
15-
{ path: 'todos', populates }
16-
])
17-
@connect(({ firebase }) => ({
18-
// populate original from data within separate paths redux
19-
todos: populate(firebase, 'todos', populates),
20-
// dataToJS(firebase, 'todos') for unpopulated todos
21-
}))
17+
const enhance = compose(
18+
firebaseConnect([
19+
// passing populates parameter also creates all necessary child queries
20+
{ path: 'todos', populates }
21+
]),
22+
connect(({ firebase }) => ({
23+
// populate original from data within separate paths redux
24+
todos: populate(firebase, 'todos', populates),
25+
// firebase.ordered.todos or firebase.data.todos for unpopulated todos
26+
}))
27+
)
28+
29+
export default enhance(SomeComponent)
2230
```
2331

2432
## Some Things To Note
@@ -73,14 +81,16 @@ When trying to replace the owner parameter with a string such as a displayName f
7381
const populates = [
7482
{ child: 'owner', root: 'displayNames' }
7583
]
76-
@firebaseConnect([
77-
{ path: '/todos', populates }
78-
// '/todos#populate=owner:displayNames', // equivalent string notation
79-
])
80-
@connect(
81-
({ firebase }) => ({
82-
todos: populate(firebase, 'todos', populates),
83-
})
84+
const enhance = compose(
85+
firebaseConnect([
86+
{ path: '/todos', populates }
87+
// '/todos#populate=owner:displayNames', // equivalent string notation
88+
]),
89+
connect(
90+
({ firebase }) => ({
91+
todos: populate(firebase, 'todos', populates),
92+
})
93+
)
8494
)
8595
```
8696

@@ -100,14 +110,16 @@ Population can also be used to populate a parameter with an object. An example o
100110
const populates = [
101111
{ child: 'owner', root: 'users' }
102112
]
103-
@firebaseConnect([
104-
{ path: '/todos', populates }
105-
// '/todos#populate=owner:users' // equivalent string notation
106-
])
107-
@connect(
108-
({ firebase }) => ({
109-
todos: populate(firebase, 'todos', populates),
110-
})
113+
const enhance = compose(
114+
firebaseConnect([
115+
{ path: '/todos', populates }
116+
// '/todos#populate=owner:users' // equivalent string notation
117+
]),
118+
connect(
119+
({ firebase }) => ({
120+
todos: populate(firebase, 'todos', populates),
121+
})
122+
)
111123
)
112124
```
113125

@@ -132,14 +144,16 @@ Often when populating, you will want to keep the key that was originally there (
132144
const populates = [
133145
{ child: 'owner', root: 'users', keyProp: 'key' }
134146
]
135-
@firebaseConnect([
136-
{ path: '/todos', populates }
137-
// '/todos#populate=owner:users' // equivalent string notation
138-
])
139-
@connect(
140-
({ firebase }) => ({
141-
todos: populatedDataToJS(firebase, 'todos', populates),
142-
})
147+
148+
const enhance = compose(
149+
firebaseConnect([
150+
{ path: '/todos', populates }
151+
]),
152+
connect(
153+
({ firebase }) => ({
154+
todos: populate(firebase, 'todos', populates),
155+
})
156+
)
143157
)
144158
```
145159

@@ -165,14 +179,17 @@ There is also the option to load a parameter from within a population object. An
165179
const populates = [
166180
{ child: 'owner', root: 'users', childParam: 'email' }
167181
]
168-
@firebaseConnect([
169-
{ path: '/todos', populates }
170-
// '/todos#populate=owner:users:email' // equivalent string notation
171-
])
172-
@connect(
173-
({ firebase }) => ({
174-
todos: populate(firebase, 'todos', populates),
175-
})
182+
183+
const enhance = compose(
184+
firebaseConnect([
185+
{ path: '/todos', populates }
186+
// '/todos#populate=owner:users:email' // equivalent string notation
187+
]),
188+
connect(
189+
({ firebase }) => ({
190+
todos: populate(firebase, 'todos', populates),
191+
})
192+
)
176193
)
177194
```
178195

@@ -197,8 +214,7 @@ Populating username with username from usernames ref.
197214
const config = {
198215
userProfile: 'users',
199216
profileParamsToPopulate: [
200-
'displayName:displayNames',
201-
// { child: 'displayName', root: 'displayNames' } // object notation
217+
{ child: 'displayName', root: 'displayNames' } // object notation
202218
]
203219
}
204220
```
@@ -215,6 +231,7 @@ const config = {
215231
}
216232
}
217233
```
234+
218235
##### Example Result
219236

220237
```javascript

docs/queries.md

Lines changed: 62 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,10 @@
44

55
Firebase Real Time Database queries can be created in two ways:
66

7-
* Automatically - Using `firebaseConnect` HOC (manages mounting/unmounting)
8-
* Manually - Using `watchEvents` or `watchEvent` (requires managing of listeners)
7+
* [Manually](#manual) - Using `watchEvents` or `watchEvent` (requires managing of listeners)
8+
* [Automatically](#auto) - Using `firebaseConnect` HOC (manages mounting/unmounting)
99

10-
### Automatically
11-
12-
`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).
13-
14-
**NOTE:**
15-
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).
16-
17-
Below are examples using Firebase query methods as well as other methods that are included (such as 'populate').
18-
19-
`firebaseConnect` is a Higher Order Component (wraps a provided component) that attaches listeners to relevant paths on Firebase when mounting, and removes them when unmounting.
20-
21-
**storeAs**
22-
23-
Data is stored in redux under the path of the query for convince. This means that two different queries to the same path (i.e. `todos`) will both place data into `state.data.todos` even if their query parameters are different. If you would like to store your query somewhere else in redux, use `storeAs`:
24-
25-
```js
26-
compose(
27-
firebaseConnect([
28-
{
29-
path: 'todos',
30-
storeAs: 'myTodos', // place in redux under "myTodos"
31-
queryParams: ['orderByChild=createdBy', 'equalTo=123someuid'],
32-
}
33-
{
34-
path: 'todos',
35-
queryParams: ['limitToFirst=20'],
36-
}
37-
]),
38-
connect((state) => ({
39-
myTodos: state.firebase.data.myTodos, // due to storeAs
40-
allTodos: state.firebase.data.todos // state.firebase.data.todos since no storeAs
41-
}))
42-
)
43-
```
44-
45-
### Manually
10+
### Manually {#manual}
4611

4712
Queries can be created manually by using `watchEvent` or `watchEvents`. This is useful to load data on some event such as a button click.
4813

@@ -88,6 +53,43 @@ export default compose(
8853

8954
**Fun Fact** - `firebaseConnect` actually calls `watchEvents` internally on component mount/unmount and when props change
9055

56+
Though doing things manually is great to understand what is going on, it comes with the need to manage these listeners yourself.
57+
58+
### Automatically {#auto}
59+
60+
`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).
61+
62+
**NOTE:**
63+
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).
64+
65+
Below are examples using Firebase query methods as well as other methods that are included (such as 'populate').
66+
67+
`firebaseConnect` is a Higher Order Component (wraps a provided component) that attaches listeners to relevant paths on Firebase when mounting, and removes them when unmounting.
68+
69+
**storeAs**
70+
71+
Data is stored in redux under the path of the query for convince. This means that two different queries to the same path (i.e. `todos`) will both place data into `state.data.todos` even if their query parameters are different. If you would like to store your query somewhere else in redux, use `storeAs`:
72+
73+
```js
74+
compose(
75+
firebaseConnect([
76+
{
77+
path: 'todos',
78+
storeAs: 'myTodos', // place in redux under "myTodos"
79+
queryParams: ['orderByChild=createdBy', 'equalTo=123someuid'],
80+
}
81+
{
82+
path: 'todos',
83+
queryParams: ['limitToFirst=20'],
84+
}
85+
]),
86+
connect((state) => ({
87+
myTodos: state.firebase.data.myTodos, // due to storeAs
88+
allTodos: state.firebase.data.todos // state.firebase.data.todos since no storeAs
89+
}))
90+
)
91+
```
92+
9193
## Ordered vs Data (by key)
9294

9395
### data {#data}
@@ -280,10 +282,10 @@ Start query at a specific location by providing the specific number or value
280282
```
281283
3. Non-number values
282284
```js
283-
@firebaseConnect([
285+
firebaseConnect([
284286
'todos#startAt=val1&limitToFirst=10'
285287
// { path: '/todos', queryParams: [ 'startAt=5', 'limitToFirst=10' ] } // object notation
286-
])
288+
])(SomeComponent)
287289
```
288290

289291
## endAt
@@ -361,3 +363,23 @@ compose(
361363
}))
362364
)
363365
```
366+
367+
## storeAs {#storeAs}
368+
369+
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`:
370+
371+
#### Examples
372+
1. Querying the same path with different query parameters
373+
374+
```js
375+
compose(
376+
firebaseConnect(props => [
377+
{ path: 'projects' }
378+
{ path: 'projects', storeAs: 'myProjects', queryParams: ['orderByChild=uid', '123'] }
379+
]),
380+
connect(({ firebase }, props) => ({
381+
projects: populatedDataToJS(firebase, 'projects'),
382+
myProjects: populatedDataToJS(firebase, 'myProjects'), // use storeAs path to gather from redux
383+
}))
384+
)
385+
```

0 commit comments

Comments
 (0)