Skip to content

Commit 657c39a

Browse files
prescottprueScott Prue
authored and
Scott Prue
committed
v0.6.0
* feat(query): composite `storeAs` - @demoran23 * feat(build): publishing to npm now happens using node 10 * fix(reducers): correctly update state for docs with keys that contain a dot when using storeAs - @compojoom * feat(query): consolidate oneListenerPerPath and allowMultipleListeners logic - @alexmattson * feat(query): initial support for populate - #48, [RRF 362](prescottprue/react-redux-firebase#362) * fix(deps): remove `@types/lodash` from dev dependencies * fix(deps): update to babel7
2 parents 109f158 + ae3f4d2 commit 657c39a

26 files changed

+4277
-4264
lines changed

.babelrc

+15-10
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
{
22
"presets": [
3-
"react",
4-
["env", {
5-
"targets": {
6-
"chrome": 52,
7-
"browsers": ["last 2 versions", "safari >= 7"]
3+
"@babel/preset-react",
4+
[
5+
"@babel/preset-env",
6+
{
7+
"targets": {
8+
"chrome": 52,
9+
"browsers": [
10+
"last 2 versions",
11+
"safari >= 7"
12+
]
13+
}
814
}
9-
}]
15+
]
1016
],
1117
"plugins": [
1218
"lodash",
13-
"transform-object-rest-spread",
14-
"transform-object-assign",
19+
"@babel/plugin-transform-runtime",
20+
"@babel/plugin-transform-async-to-generator",
21+
"@babel/plugin-transform-regenerator"
1522
],
1623
"env": {
1724
"es": {
@@ -28,8 +35,6 @@
2835
},
2936
"test": {
3037
"plugins": [
31-
"transform-runtime",
32-
"transform-async-to-generator",
3338
["module-resolver", {
3439
"root": ["./src"]
3540
}]

.editorconfig

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# EditorConfig is awesome: http://EditorConfig.org
2+
3+
# top-most EditorConfig file
4+
root = true
5+
6+
# Unix-style newlines with a newline ending every file
7+
[*]
8+
end_of_line = lf
9+
indent_style = space
10+
11+
[*.{js,jsx}]
12+
insert_final_newline = true
13+
indent_size = 2

.eslintrc

+1
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ rules:
2020
no-confusing-arrow: 0
2121
no-case-declarations: 0
2222
arrow-parens: [2, "as-needed"]
23+
prefer-default-export: 0

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ es
55
*.log
66
coverage
77
.idea
8+
.DS_Store

.travis.yml

+23-13
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ sudo: false
33
language: node_js
44

55
node_js:
6-
- 6.14.0 # Cloud Functions Runtime
7-
- 9
8-
- 10
6+
- 6 # Maintenance
7+
- 8 # Active
8+
- 10 # Current release
99

1010
notifications:
1111
email:
@@ -14,21 +14,14 @@ notifications:
1414
on_success: change
1515

1616
cache:
17+
bundler: true
1718
directories:
18-
- node_modules
19+
- $HOME/.npm
1920

2021
branches:
2122
only:
2223
- master
23-
24-
deploy:
25-
skip_cleanup: true
26-
provider: npm
27-
email: $NPM_EMAIL
28-
api_key: $NPM_KEY
29-
on:
30-
node: '10'
31-
branch: 'master'
24+
- next
3225

3326
script:
3427
- npm run lint
@@ -37,3 +30,20 @@ script:
3730
after_success:
3831
- codeclimate-test-reporter < coverage/lcov.info
3932
- npm run codecov
33+
34+
deploy:
35+
- provider: npm
36+
skip_cleanup: true
37+
email: $NPM_EMAIL
38+
api_key: $NPM_TOKEN
39+
on:
40+
node: '10'
41+
branch: 'master'
42+
- provider: npm
43+
skip_cleanup: true
44+
email: $NPM_EMAIL
45+
api_key: $NPM_TOKEN
46+
tag: next
47+
on:
48+
node: '10'
49+
branch: 'next'

README.md

+96-10
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ const enhance = compose(
114114
props.store.firestore.add('todos', { ...newTodo, owner: 'Anonymous' }),
115115
}),
116116
lifecycle({
117-
componentWillMount(props) {
117+
componentDidMount(props) {
118118
props.loadData()
119119
}
120120
}),
@@ -142,7 +142,7 @@ class Todos extends Component {
142142
store: PropTypes.object.isRequired
143143
}
144144

145-
componentWillMount () {
145+
componentDidMount () {
146146
const { firestore } = this.context.store
147147
firestore.get('todos')
148148
}
@@ -251,7 +251,7 @@ After setting a listener/multiple listeners, you can unset them with the followi
251251
```js
252252
store.firestore.unsetListener({ collection: 'cities' }),
253253
// of for any number of listeners at once :
254-
store.firestore.unsetListeners([query1Options, query2Options]),
254+
store.firestore.unsetListeners([query1Options, query2Options]),
255255
// here query1Options as in { collection: 'cities' } for example
256256
```
257257

@@ -305,6 +305,21 @@ Multiple `where` queries are as simple as passing multiple argument arrays (each
305305
},
306306
```
307307

308+
Firestore doesn't alow you to create `or` style queries. Instead, you should pass in multiple queries and compose your data.
309+
310+
``` javascript
311+
['sally', 'john', 'peter'].map(friendId => ({
312+
collection: 'users',
313+
where: [
314+
['id', '==', friendId],
315+
['isOnline', '==', true]
316+
]
317+
storeAs: 'onlineFriends'
318+
}));
319+
```
320+
321+
Since the results must be composed, a query like this is unable to be properly ordered. The results should be pulled from `data`.
322+
308323
*Can only be used with collections*
309324

310325
##### orderBy
@@ -432,16 +447,16 @@ Storing data under a different path within redux is as easy as passing the `stor
432447
Other Firebase statics (such as [FieldValue](https://firebase.google.com/docs/reference/js/firebase.firestore.FieldValue)) are available through the firestore instance:
433448

434449
```js
450+
import PropTypes from 'prop-types'
435451
import { connect } from 'react-redux'
436452
import {
437453
compose,
438454
withHandlers,
439-
lifecycle,
440455
withContext,
441456
getContext
442457
} from 'recompose'
443458

444-
const withFirestore = compose(
459+
const withStore = compose(
445460
withContext({ store: PropTypes.object }, () => {}),
446461
getContext({ store: PropTypes.object }),
447462
)
@@ -462,6 +477,82 @@ const enhance = compose(
462477
export default enhance(SomeComponent)
463478
```
464479

480+
### Population
481+
Population, made popular in [react-redux-firebase](http://react-redux-firebase.com/docs/recipes/populate.html), also works with firestore.
482+
483+
484+
#### Automatic Listeners
485+
```js
486+
import { connect } from 'react-redux'
487+
import { firestoreConnect, populate } from 'react-redux-firebase'
488+
import {
489+
compose,
490+
withHandlers,
491+
lifecycle,
492+
withContext,
493+
getContext
494+
} from 'recompose'
495+
496+
const populates = [{ child: 'createdBy', root: 'users' }]
497+
const collection = 'projects'
498+
499+
const withPopulatedProjects = compose(
500+
firestoreConnect((props) => [
501+
{
502+
collection,
503+
populates
504+
}
505+
]),
506+
connect((state, props) => ({
507+
projects: populate(state.firestore, collection, populates)
508+
}))
509+
)
510+
```
511+
512+
#### Manually using setListeners
513+
```js
514+
import { withFirestore, populate } from 'react-redux-firebase'
515+
import { connect } from 'react-redux'
516+
import { compose, lifecycle } from 'recompose'
517+
518+
const collection = 'projects'
519+
const populates = [{ child: 'createdBy', root: 'users' }]
520+
521+
const enhance = compose(
522+
withFirestore,
523+
lifecycle({
524+
componentDidMount() {
525+
this.props.firestore.setListener({ collection, populates })
526+
}
527+
}),
528+
connect(({ firestore }) => ({ // state.firestore
529+
todos: firestore.ordered.todos,
530+
}))
531+
)
532+
```
533+
534+
#### Manually using get
535+
```js
536+
import { withFirestore, populate } from 'react-redux-firebase'
537+
import { connect } from 'react-redux'
538+
import { compose, lifecycle } from 'recompose'
539+
540+
const collection = 'projects'
541+
const populates = [{ child: 'createdBy', root: 'users' }]
542+
543+
const enhance = compose(
544+
withFirestore,
545+
lifecycle({
546+
componentDidMount() {
547+
this.props.store.firestore.get({ collection, populates })
548+
}
549+
}),
550+
connect(({ firestore }) => ({ // state.firestore
551+
todos: firestore.ordered.todos,
552+
}))
553+
)
554+
```
555+
465556
## Config Options
466557
Optional configuration options for redux-firestore, provided to reduxFirestore enhancer as optional second argument. Combine any of them together in an object.
467558

@@ -480,11 +571,6 @@ Default: `false`
480571

481572
Whether or not to allow multiple listeners to be attached for the same query. If a function is passed the arguments it receives are `listenerToAttach`, `currentListeners`, and the function should return a boolean.
482573

483-
#### oneListenerPerPath
484-
Default: `false`
485-
486-
If set to true redux-firestore will attach a listener on the same path just once & will count how many the listener was set. When you try to unset the listener, it won't unset until you have less than 1 listeners on this path
487-
488574
#### preserveOnDelete
489575
Default: `null`
490576

examples/basic/jsconfig.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"compilerOptions": {
3+
"baseUrl": "./src"
4+
},
5+
"exclude": [
6+
"node_modules",
7+
"public",
8+
]
9+
}

jsconfig.json

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"compilerOptions": {
3+
"baseUrl": "./src",
4+
"paths": {
5+
"utils/*": [
6+
"utils/*",
7+
]
8+
}
9+
},
10+
"exclude": [
11+
"node_modules",
12+
"dist",
13+
"es",
14+
"lib",
15+
"coverage"
16+
]
17+
}

0 commit comments

Comments
 (0)