Skip to content

Commit 51efdc7

Browse files
authored
v3.0.5
* fix(auth): always return a promise from createUserProfile - prescottprue#789 * fix(tests): add check for promise return in all situations - prescottprue#789 * fix(docs): handle case of empty `providerData` in `profileFactory` example - prescottprue#739
1 parent ad28fc2 commit 51efdc7

File tree

9 files changed

+110
-214
lines changed

9 files changed

+110
-214
lines changed

docs/auth.md

+10-39
Original file line numberDiff line numberDiff line change
@@ -18,37 +18,6 @@ enhance(SomeComponent)
1818

1919
If you need access to methods that are not available at the top level, you can access Firebase's Full Auth API using `props.firebase.auth()`
2020

21-
#### NOTE
22-
All examples below assume you have passed `firebase` from `context` to props. Wrapping your component with with the `withFirebase` or `firebaseConnect` Higher Order Components will make `props.firebase` available within your component:
23-
24-
```js
25-
import React from 'react'
26-
import { withFirebase } from 'react-redux-firebase'
27-
28-
function SomeComponent (props) {
29-
return (
30-
// use props.firebase
31-
)
32-
}
33-
34-
export default withFirebase(SomeComponent) // or firebaseConnect()(SomeComponent)
35-
```
36-
37-
Works same with class components (make sure you import `Component` from react):
38-
39-
```js
40-
import React, { Component } from 'react'
41-
import { firebaseConnect } from 'react-redux-firebase'
42-
43-
class SomeComponent extends Component {
44-
render() {
45-
// use this.props.firebase
46-
}
47-
}
48-
49-
export default firebaseConnect()(SomeComponent) // or withFirebase(SomeComponent)
50-
```
51-
5221
#### Custom Claims
5322

5423
Firebase has a secure way of identifying and making claims about users with [custom claims](https://firebase.google.com/docs/auth/admin/custom-claims). This is a good way to provide roles for users.
@@ -110,6 +79,7 @@ For examples of how to use this API, checkout the [auth recipes section](/docs/r
11079
```
11180

11281
##### Returns
82+
11383
[**Promise**][promise-url] that resolves with the response from firebase's login method (an [**Object**][object-url]). `credential` property is also included if using oAuth provider.
11484
11585
**NOTE**: For email authentication in `v1.4.*` and earlier - The user's UID (a [**String**][string-url]) is returned instead of an object. This has been changed in `v1.5.0` for consistency across all auth types.
@@ -118,23 +88,23 @@ For examples of how to use this API, checkout the [auth recipes section](/docs/r
11888

11989
*Email*
12090
```js
121-
props.firebase.login({
91+
firebase.login({
12292
email: 'test@test.com',
12393
password: 'testest1'
12494
})
12595
```
12696

12797
*OAuth Provider Redirect*
12898
```js
129-
props.firebase.login({
99+
firebase.login({
130100
provider: 'google',
131101
type: 'redirect'
132102
})
133103
```
134104

135105
*OAuth Provider Popup*
136106
```js
137-
props.firebase.login({
107+
firebase.login({
138108
provider: 'google',
139109
type: 'popup',
140110
// scopes: ['email'] // not required
@@ -144,18 +114,18 @@ props.firebase.login({
144114
*Credential*
145115
```js
146116
// `googleUser` from the onsuccess Google Sign In callback
147-
props.firebase.login({
117+
firebase.login({
148118
credential: firebase.auth.GoogleAuthProvider.credential(googleUser.getAuthResponse().id_token)
149119
})
150120
// or using an accessToken
151-
props.firebase.login({
121+
firebase.login({
152122
credential: firebase.auth.GoogleAuthProvider.credential(null, 'some access token')
153123
})
154124
```
155125

156126
*Token*
157127
```js
158-
props.firebase.login({
128+
firebase.login({
159129
token: 'someJWTAuthToken',
160130
profile: { email: 'rick@sanchez.com' }
161131
})
@@ -167,8 +137,8 @@ async function loginWithFacebook() {
167137
const data = await Expo.Facebook.logInWithReadPermissionsAsync('FB_ID', { permissions: ['public_profile', 'email'] })
168138
169139
if (data.type === 'success') {
170-
const credential = props.firebase.auth.FacebookAuthProvider.credential(data.token)
171-
await props.firebase.login({ credential })
140+
const credential = firebase.auth.FacebookAuthProvider.credential(data.token)
141+
await firebase.login({ credential })
172142
}
173143
}
174144
```
@@ -219,6 +189,7 @@ createNewUser({
219189
```
220190
221191
##### Returns
192+
222193
[**Promise**][promise-url] with `userData`
223194
224195
## logout()

docs/recipes/actions.md

+16-118
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,17 @@ react-redux-firebase comes with built in async action creators for all parts of
55
For more on what [an async action creator is](http://redux.js.org/docs/advanced/AsyncActions.html#async-action-creators), please visit the [section on it in the redux-docs](http://redux.js.org/docs/advanced/AsyncActions.html#async-action-creators).
66

77
## Components
8-
Firebase actions can be accessed within a component by using either the [`withFirebase`](/docs/api/withFirebase) wrapper or the [`firebaseConnect` wrapper](/docs/api/firebaseConnect) like so:
98

10-
#### Functional Component
11-
```js
12-
import React from 'react'
13-
import PropTypes from 'prop-types'
14-
import { useFirebase } from 'react-redux-firebase'
9+
Methods which dispatch actions can be accessed within a component by using one of the following:
10+
* [`useFirebase` Hook](/docs/api/useFirebase)
11+
* [`withFirebase` HOC](/docs/api/withFirebase)
12+
* [`firebaseConnect` HOC](/docs/api/firebaseConnect)
1513

16-
function SimpleComponent(props) {
17-
const firebase = useFirebase()
18-
return (
19-
<button onClick={() => firebase.push('todos', { some: 'data' })}>
20-
Test Push
21-
</button>
22-
)
23-
}
24-
25-
SimpleComponent.propTypes = {
26-
firebase: PropTypes.shape({
27-
push: PropTypes.func.isRequired
28-
})
29-
}
30-
31-
export default SimpleComponent
32-
```
33-
34-
When using functional components, [recompose](https://github.com/acdlite/recompose/blob/master/docs/API.md) is a nice utility (think of it like lodash for Functional React Components):
14+
#### Functional Component
3515

3616
```js
3717
import React from 'react'
3818
import PropTypes from 'prop-types'
39-
import { compose } from 'recompose'
4019
import { useFirebase } from 'react-redux-firebase'
4120

4221
function SimpleComponent() {
@@ -48,7 +27,7 @@ function SimpleComponent() {
4827

4928
return (
5029
<button onClick={createTodo}>
51-
Test Push
30+
Create Example Todo
5231
</button>
5332
)
5433
}
@@ -58,96 +37,7 @@ export default SimpleComponent
5837

5938
#### Stateful Components
6039

61-
**Wrapping A Class Component**
62-
63-
```js
64-
import React, { Component } from 'react'
65-
import PropTypes from 'prop-types'
66-
import { firebaseConnect } from 'react-redux-firebase'
67-
68-
class SimpleComponent extends Component {
69-
static propTypes = {
70-
firebase: PropTypes.shape({
71-
push: PropTypes.func.isRequired
72-
})
73-
}
74-
75-
state = {
76-
wasSent: false
77-
}
78-
79-
testPush = () => {
80-
this.props.firebase
81-
.push('todos', { some: 'data' })
82-
.then(() => {
83-
this.setState({ wasSent: true })
84-
})
85-
}
86-
87-
render() {
88-
return (
89-
<div>
90-
<span>Was sent: {this.state.wasSent}</span>
91-
<button onClick={this.testPush}>
92-
Test Push
93-
</button>
94-
</div>
95-
)
96-
}
97-
}
98-
```
99-
100-
**Decorator**
101-
102-
Or if you are using decorators, you can accomplish the same thing with
103-
```js
104-
@firebaseConnect() // @withFirebase can also be used
105-
export default class SimpleComponent extends Component {
106-
// same component code from above
107-
}
108-
```
109-
110-
**Directly From Context**
111-
112-
`react-redux` passes store through `context` using `<Provider>`, so you can grab `store.firebase`:
113-
114-
```js
115-
import React, { Component } from 'react'
116-
import PropTypes from 'prop-types'
117-
118-
export default class SimpleComponent extends Component {
119-
static contextTypes = {
120-
store: PropTypes.object
121-
}
122-
123-
state = {
124-
wasSent: false
125-
}
126-
127-
testPush = () => {
128-
this.context.store.firebase
129-
.push('todos', { some: 'data' })
130-
.then(() => {
131-
this.setState({ wasSent: true })
132-
})
133-
}
134-
135-
render() {
136-
return (
137-
<div>
138-
<span>Was sent: {this.state.wasSent}</span>
139-
<button onClick={this.testPush}>
140-
Test Push
141-
</button>
142-
</div>
143-
)
144-
}
145-
}
146-
```
147-
148-
**Functional Stateful**
149-
150-
```js
40+
```jsx
15141
import React, { useState } from 'react'
15242
import { useFirebase } from 'react-redux-firebase'
15343

@@ -174,7 +64,15 @@ export default function SimpleComponent() {
17464
}
17565
```
17666

177-
Fun Fact: This is actually what happens internally with both `withFirebase` and `firebaseConnect`.
67+
**Decorator**
68+
69+
Or if you are using decorators, you can accomplish the same thing with
70+
```js
71+
@firebaseConnect() // @withFirebase can also be used
72+
export default class SimpleComponent extends Component {
73+
// same component code from above
74+
}
75+
```
17876

17977
## Advanced Actions
18078

docs/recipes/profile.md

+49-30
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,26 @@ const config = {
1515
reactReduxFirebase(fbConfig, config)
1616
```
1717

18+
### Using useSelector Hook
19+
20+
Then later `connect` (from [react-redux](https://github.com/reactjs/react-redux/blob/master/docs/api.md)) to redux state with:
21+
22+
```js
23+
import { useSelector } from 'react-redux'
24+
25+
function SomeComponent() {
26+
const profile = useSelector(state => state.firebase.profile)
27+
return <div>{JSON.stringify(profile, null, 2)}</div>
28+
}
29+
30+
function SomeComponent() {
31+
const profile = useSelector(({ firebase: { profile } }) => profile)
32+
return <div>{JSON.stringify(profile, null, 2)}</div>
33+
}
34+
```
35+
36+
### Using connect HOC
37+
1838
Then later `connect` (from [react-redux](https://github.com/reactjs/react-redux/blob/master/docs/api.md)) to redux state with:
1939

2040
```js
@@ -41,43 +61,40 @@ The current users profile can be updated by using the `updateProfile` method:
4161
import React from 'react'
4262
import PropTypes from 'prop-types'
4363
import { compose } from 'redux'
44-
import { connect } from 'react-redux'
64+
import { useSelector } from 'react-redux'
4565
import { withFirebase, isLoaded } from 'react-redux-firebase'
4666

47-
const UpdateProfilePage = ({ profile, firebase }) => (
48-
<div>
49-
<h2>Update User Profile</h2>
50-
<span>
51-
Click the button to update profile to include role parameter
52-
</span>
53-
<button onClick={() => firebase.updateProfile({ role: 'admin' })}>
54-
Add Role To User
55-
</button>
56-
<div>
57-
{
58-
isLoaded(profile)
59-
? JSON.stringify(profile, null, 2)
60-
: 'Loading...'
61-
}
62-
</div>
63-
</div>
64-
)
67+
export default function UpdateProfilePage() {
68+
const firebase = useFirebase()
69+
const profile = useSelector(state => state.firebase.profile)
6570

66-
UpdateProfilePage.propTypes = {
67-
profile: PropTypes.object,
68-
}
71+
function updateUserProfile() {
72+
return firebase.updateProfile({ role: 'admin' })
73+
}
6974

70-
export default compose(
71-
withFirebase, // add props.firebase (firebaseConnect() can also be used)
72-
connect(
73-
({ firebase: { profile } }) => ({
74-
profile
75-
})
75+
return (
76+
<div>
77+
<h2>Update User Profile</h2>
78+
<span>
79+
Click the button to update profile to include role parameter
80+
</span>
81+
<button onClick={updateUserProfile}>
82+
Add Role To User
83+
</button>
84+
<div>
85+
{
86+
isLoaded(profile)
87+
? JSON.stringify(profile, null, 2)
88+
: 'Loading...'
89+
}
90+
</div>
91+
</div>
7692
)
77-
)(UpdateProfilePage)
93+
}
7894
```
7995

8096
## Change How Profiles Are Stored
97+
8198
The way user profiles are written to the database can be modified by passing the `profileFactory` parameter .
8299

83100
```js
@@ -101,7 +118,9 @@ To list online users and/or track sessions, view the [presence recipe](/docs/rec
101118
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.
102119

103120
#### List
104-
profile.contacts contains a list of user UIDs that should be populated from the users list like so:
121+
122+
`profile.contacts` contains a list of user UIDs that should be populated from the users list like so:
123+
105124
```js
106125
{
107126
displayName: 'Rick Sanchez',

docs/recipes/roles.md

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ If you want to assign a role by default when users sign up, you can add a profil
9292
if (user.providerData && user.providerData.length) {
9393
profile.providerData = user.providerData
9494
}
95+
return profile
9596
}
9697
}
9798
```

0 commit comments

Comments
 (0)