Skip to content

Commit 46ca1a8

Browse files
prescottpruegregfentonmsutkowskithemindoverallharveychow
authored
v3.6.0 (#966)
* feat(types): add database and firestore statics (#957) - @msutkowski, @themindoverall, @phryneas * feat(types): add type predicate to `isLoaded` (#956) - @lukeKonopka * chore(docs): formatting fixes in firestore docs section (#959) - @gregfenton * feat(docs): add firestore populate docs (#954) - @harveychow Co-authored-by: gregfenton <[email protected]> Co-authored-by: Matt Sutkowski <[email protected]> Co-authored-by: Chris Serino <[email protected]> Co-authored-by: Harvey Chow <[email protected]> Co-authored-by: Luke Konopka <[email protected]>
1 parent e242b41 commit 46ca1a8

File tree

12 files changed

+595
-495
lines changed

12 files changed

+595
-495
lines changed

.github/workflows/verify.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
runs-on: ubuntu-latest
99
strategy:
1010
matrix:
11-
node-version: [10.x, 12.x]
11+
node-version: [10.x, 12.x, 14.x]
1212
steps:
1313
- name: Checkout code
1414
uses: actions/checkout@v2

README.md

+4-6
Original file line numberDiff line numberDiff line change
@@ -178,15 +178,16 @@ import React from 'react'
178178
import PropTypes from 'prop-types'
179179
import { get } from 'lodash'
180180
import { useSelector } from 'react-redux'
181-
import { useFirebaseConnect } from 'react-redux-firebase'
181+
import { useFirebaseConnect, useFirebase } from 'react-redux-firebase'
182182
import { useParams } from 'react-router-dom'
183183

184184
export default function Todo() {
185185
const { todoId } = useParams() // matches todos/:todoId in route
186+
const firebase = useFirebase()
186187

187188
useFirebaseConnect([
188189
{ path: `todos/${todoId}` } // create todo listener
189-
// `todos/${props.params.todoId}` // equivalent string notation
190+
// `todos/${todoId}` // equivalent string notation
190191
])
191192

192193
const todo = useSelector(
@@ -238,7 +239,7 @@ function TodosList() {
238239
)
239240
}
240241

241-
function Todos() {
242+
export default function Todos() {
242243
const firebase = useFirebase()
243244

244245
return (
@@ -251,9 +252,6 @@ function Todos() {
251252
</div>
252253
)
253254
}
254-
255-
// Export enhanced component
256-
export default Todos
257255
```
258256

259257
## Firestore

docs/api/firestoreConnect.md

+10-18
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,25 @@
22

33
### Table of Contents
44

5-
- [firestoreConnect][1]
6-
- [Parameters][2]
7-
- [Examples][3]
8-
- [Parameters][4]
5+
- [firestoreConnect][1]
6+
- [Parameters][2]
7+
- [Examples][3]
8+
- [Parameters][4]
99

1010
## firestoreConnect
1111

1212
**Extends React.Component**
1313

14-
1514
Higher Order Component that automatically listens/unListens
1615
to provided Cloud Firestore paths using React's Lifecycle hooks. Make sure you
17-
have required/imported Cloud Firestore, including its reducer, before
16+
have required/imported Cloud Firestore, including it's reducer, before
1817
attempting to use. **Note** Populate is not yet supported.
1918

2019
### Parameters
2120

22-
- `queriesConfig` **([Array][6] \| [Function][7])** Array of objects or strings for paths to sync
23-
from Firebase. Can also be a function that returns the array. The function
24-
is passed the current props and the firebase object. (optional, default `[]`)
21+
- `queriesConfig` **([Array][6] \| [Function][7])** Array of objects or strings for paths to sync
22+
from Firebase. Can also be a function that returns the array. The function
23+
is passed the current props and the firebase object. (optional, default `[]`)
2524

2625
### Examples
2726

@@ -51,28 +50,21 @@ export default compose(
5150
Returns **[Function][7]** Function which accepts a component to wrap and returns the
5251
wrapped component
5352
54-
##
53+
##
5554
5655
Render component wrapped in context
5756
5857
### Parameters
5958
60-
- `props` **[object][8]** Component props
59+
- `props` **[object][8]** Component props
6160
6261
Returns **React.Component** Component wrapped in context
6362
6463
[1]: #firestoreconnect
65-
6664
[2]: #parameters
67-
6865
[3]: #examples
69-
7066
[4]: #parameters-1
71-
7267
[5]: https://react-redux-firebase.com/docs/api/firestoreConnect.html
73-
7468
[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
75-
7669
[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function
77-
7870
[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

docs/firestore.md

+104-107
Original file line numberDiff line numberDiff line change
@@ -98,38 +98,36 @@ Firestore queries can be created in the following ways:
9898
`useFirestoreConnect` is a React hook that manages attaching and detaching listeners for you as the component mounts and unmounts.
9999

100100
#### Examples
101-
102101
1. Basic query that will attach/detach as the component passed mounts/unmounts. In this case we are setting a listener for the `'todos'` collection:
103-
104-
```js
105-
import React from 'react'
106-
import { useSelector } from 'react-redux'
107-
import { useFirestoreConnect } from 'react-redux-firebase'
108-
109-
export default function SomeComponent() {
110-
useFirestoreConnect([
111-
{ collection: 'todos' } // or 'todos'
112-
])
113-
const todos = useSelector((state) => state.firestore.ordered.todos)
114-
}
115-
```
102+
```js
103+
import React from 'react'
104+
import { useSelector } from 'react-redux'
105+
import { useFirestoreConnect } from 'react-redux-firebase'
106+
107+
export default function SomeComponent() {
108+
useFirestoreConnect([
109+
{ collection: 'todos' } // or 'todos'
110+
])
111+
const todos = useSelector((state) => state.firestore.ordered.todos)
112+
}
113+
```
116114

117115
2. Props can be used as part of queries. In this case we will get a specific todo:
118116

119-
```js
120-
import React from 'react'
121-
import { useSelector } from 'react-redux'
122-
import { useFirestoreConnect } from 'react-redux-firebase'
123-
124-
export default function SomeComponent({ todoId }) {
125-
useFirestoreConnect(() => [
126-
{ collection: 'todos', doc: todoId } // or `todos/${props.todoId}`
127-
])
128-
const todo = useSelector(
129-
({ firestore: { data } }) => data.todos && data.todos[todoId]
130-
)
131-
}
132-
```
117+
```js
118+
import React from 'react'
119+
import { useSelector } from 'react-redux'
120+
import { useFirestoreConnect } from 'react-redux-firebase'
121+
122+
export default function SomeComponent({ todoId }) {
123+
useFirestoreConnect(() => [
124+
{ collection: 'todos', doc: todoId } // or `todos/${props.todoId}`
125+
])
126+
const todo = useSelector(
127+
({ firestore: { data } }) => data.todos && data.todos[todoId]
128+
)
129+
}
130+
```
133131

134132
### Automatically with HOC {#firestoreConnect}
135133

@@ -138,36 +136,35 @@ export default function SomeComponent({ todoId }) {
138136
#### Examples
139137

140138
1. Basic query that will attach/detach as the component passed mounts/unmounts. In this case we are setting a listener for the `'todos'` collection:
141-
142-
```js
143-
import { compose } from 'redux'
144-
import { connect } from 'react-redux'
145-
import { firestoreConnect } from 'react-redux-firebase'
146-
147-
export default compose(
148-
firestoreConnect(() => ['todos']), // or { collection: 'todos' }
149-
connect((state, props) => ({
150-
todos: state.firestore.ordered.todos
151-
}))
152-
)(SomeComponent)
153-
```
139+
140+
```js
141+
import { compose } from 'redux'
142+
import { connect } from 'react-redux'
143+
import { firestoreConnect } from 'react-redux-firebase'
144+
145+
export default compose(
146+
firestoreConnect(() => ['todos']), // or { collection: 'todos' }
147+
connect((state, props) => ({
148+
todos: state.firestore.ordered.todos
149+
}))
150+
)(SomeComponent)
151+
```
154152

155153
2. Create a query based on props by passing a function. In this case we will get a specific todo:
156-
157-
```js
158-
import { compose } from 'redux'
159-
import { connect } from 'react-redux'
160-
import { firestoreConnect } from 'react-redux-firebase'
161-
162-
export default compose(
163-
firestoreConnect((props) => [
164-
{ collection: 'todos', doc: props.todoId } // or `todos/${props.todoId}`
165-
]),
166-
connect(({ firestore: { data } }, props) => ({
167-
todos: data.todos && data.todos[todoId]
168-
}))
169-
)(SomeComponent)
170-
```
154+
```js
155+
import { compose } from 'redux'
156+
import { connect } from 'react-redux'
157+
import { firestoreConnect } from 'react-redux-firebase'
158+
159+
export default compose(
160+
firestoreConnect((props) => [
161+
{ collection: 'todos', doc: props.todoId } // or `todos/${props.todoId}`
162+
]),
163+
connect(({ firestore: { data } }, props) => ({
164+
todos: data.todos && data.todos[todoId]
165+
}))
166+
)(SomeComponent)
167+
```
171168

172169
## Manual {#manual}
173170

@@ -281,58 +278,58 @@ By default the results of queries are stored in redux under the path of the quer
281278
#### Examples
282279

283280
1. Querying the same path with different query parameters
284-
285-
```js
286-
import { compose } from 'redux'
287-
import { connect } from 'react-redux'
288-
import { firestoreConnect } from 'react-redux-firebase'
289-
const myProjectsReduxName = 'myProjects'
290-
291-
compose(
292-
firestoreConnect((props) => [
293-
{ collection: 'projects' },
294-
{
295-
collection: 'projects',
296-
where: [['uid', '==', '123']],
297-
storeAs: myProjectsReduxName
298-
}
299-
]),
300-
connect((state, props) => ({
301-
projects: state.firestore.data.projects,
302-
myProjects: state.firestore.data[myProjectsReduxName] // use storeAs path to gather from redux
303-
}))
304-
)
305-
```
306-
307-
2. Set `useFirestoreConnect` for subcollections documents
308-
For example, in Firestore cloud you have such message structure:
309-
`chatMessages (collection) / chatID (document) / messages (collection) / messageID (document)`
310-
311-
You can't write the path in `useFirestoreConnect` like:
312-
313-
```js
314-
useFirestoreConnect(`chatMessages/${chatID}/messages`)
315-
```
316-
317-
You will have error:
318-
319-
`Queries with subcollections must use "storeAs" to prevent invalid store updates. This closley matches the upcoming major release (v1), which stores subcollections at the top level by default.`
320-
321-
Solution:
322-
Use `subcollections` for 'messages' and `storeAs`.
323-
324-
````import { useFirestoreConnect } from 'react-redux-firebase'
325-
useFirestoreConnect([
326-
{
327-
collection: 'chatMessages',
328-
doc: chatID,
329-
subcollections: [{ collection: 'messages' }],
330-
storeAs: 'myMessages'
331-
}
332-
])```
333-
281+
```js
282+
import { compose } from 'redux'
283+
import { connect } from 'react-redux'
284+
import { firestoreConnect } from 'react-redux-firebase'
285+
const myProjectsReduxName = 'myProjects'
286+
287+
compose(
288+
firestoreConnect((props) => [
289+
{ collection: 'projects' },
290+
{
291+
collection: 'projects',
292+
where: ['uid', '==', '123'],
293+
storeAs: myProjectsReduxName
294+
}
295+
]),
296+
connect((state, props) => ({
297+
projects: state.firestore.data.projects,
298+
myProjects: state.firestore.data[myProjectsReduxName] // use storeAs path to gather from redux
299+
}))
300+
)
301+
```
302+
303+
2. Set `useFirestoreConnect` for subcollections documents. For example, in Cloud Firestore you might have a message structure such as:
304+
305+
`chatMessages (collection) / chatID (document) / messages (collection) / messageID (document)`
306+
307+
You cannot write the path in `useFirestoreConnect` like:
308+
309+
```js
310+
useFirestoreConnect(`chatMessages/${chatID}/messages`)
311+
```
312+
313+
This will lead to the error:
314+
315+
`Queries with subcollections must use "storeAs" to prevent invalid store updates. This closley matches the upcoming major release (v1), which stores subcollections at the top level by default.`
316+
317+
**Solution**:
318+
319+
Use `subcollections` for `messages` and `storeAs`.
320+
321+
```js
322+
import { useFirestoreConnect } from 'react-redux-firebase'
323+
useFirestoreConnect([
324+
{
325+
collection: 'chatMessages',
326+
doc: chatID,
327+
subcollections: [{ collection: 'messages' }],
328+
storeAs: 'myMessages'
329+
}
330+
])
331+
```
334332

335333
## Populate {#populate}
336334

337335
Populate is supported for Firestore as of [v0.6.0 of redux-firestore](https://github.com/prescottprue/redux-firestore/releases/tag/v0.6.0). It was added [as part of issue #48](https://github.com/prescottprue/redux-firestore/issues/48).
338-
````

docs/populate.md

+23
Original file line numberDiff line numberDiff line change
@@ -334,3 +334,26 @@ const config = {
334334
}
335335
}
336336
```
337+
338+
### Use with Firestore
339+
340+
To use populate with Firestore, just replace firebaseConnect with firestoreConnect with the corresponding charaters.
341+
342+
```javascript
343+
import { firestoreConnect, populate } from 'react-redux-firebase';
344+
345+
const populates = [
346+
{ child: 'owner', root: 'users', childAlias: 'ownerObj' }
347+
]
348+
349+
const enhance = compose(
350+
firestoreConnect([
351+
{ collection: 'todos', populates }
352+
]),
353+
connect(
354+
({ firebase }) => ({
355+
todos: populate(firebase, 'todos', populates),
356+
})
357+
)
358+
)
359+
```

examples/snippets/watchEvent/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ render () {
3939
}
4040
```
4141

42-
**NOTE**: This is simplified functionality of what is available through [`firebaseConnect`](https://react-redux-firebase.com/docs/api/firebaseConnect.html) and {`useFirebaseConnect`](https://react-redux-firebase.com/docs/api/useFirebaseConnect.html).
42+
**NOTE**: This is simplified functionality of what is available through [`firebaseConnect`](https://react-redux-firebase.com/docs/api/firebaseConnect.html) and [`useFirebaseConnect`](https://react-redux-firebase.com/docs/api/useFirebaseConnect.html).

0 commit comments

Comments
 (0)