Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Docs updated with firebaseConnect change.
  • Loading branch information
prescottprue committed Oct 27, 2017
commit 24a1c32926cc78de7081935a219dc6e1efc98df9
6 changes: 3 additions & 3 deletions docs/api/connect.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,16 @@ const Posts = ({ done, text, author }) => (
export default enhance(Posts)
```

_Data that depends on auth state_
_Data that depends on state_

```javascript
import { compose } from 'redux'
import { connect } from 'react-redux'
import { firebaseConnect } from 'react-redux-firebase'

export default compose(
firebaseConnect((props, firebase) => ([
`todos/${firebase._.authUid}` // sync /todos from firebase into redux
firebaseConnect((props, state) => ([
`todos/${state.firebase.auth.uid}` // sync /todos from firebase into redux
]),
connect(({ firebase: { data, auth } }) => ({
todosList: data.todos && data.todos[auth.uid],
Expand Down
71 changes: 34 additions & 37 deletions docs/recipes/profile.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ connect(
profile: state.firebase.profile // profile passed as props.profile
})
)(SomeComponent) // pass component to be wrapped

// or with some shorthand:
connect(({ firebase: { profile } }) => ({
profile // profile passed as props.profile
Expand All @@ -36,49 +37,45 @@ connect(({ firebase: { profile } }) => ({
The current users profile can be updated by using the `updateProfile` method:

```js
import React, { Component } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { compose } from 'redux'
import { connect } from 'react-redux'
import { firebaseConnect, isLoaded } from 'react-redux-firebase'

@firebaseConnect()
@connect(
({ firebase: { profile } }) => ({
profile,
})
import { withFirebase, isLoaded } from 'react-redux-firebase'

const UpdateProfilePage = ({ profile, firebase }) => (
<div>
<h2>Update User Profile</h2>
<span>
Click the button to update profile to include role parameter
</span>
<button onClick={() => firebase.updateProfile({ role: 'admin' })}>
Add Role To User
</button>
<div>
{
isLoaded(profile)
? JSON.stringify(profile, null, 2)
: 'Loading...'
}
</div>
</div>
)
export default class UpdateProfilePage extends Component {
static propTypes = {
profile: PropTypes.object,
}

addRole = () => {
return this.props.updateProfile({ role: ''})
}

render() {
const { profile } = this.props
return (
<div>
<h2>Update User Profile</h2>
<span>
Click the button to update profile to include role parameter
</span>
<button onClick={this.addRole}>
Add Role To User
</button>
<div>
{
isLoaded(profile)
? JSON.stringify(profile, null, 2)
: 'Loading...'
}
</div>
</div>
)
}
UpdateProfilePage.propTypes = {
profile: PropTypes.object,
}

export default compose(
withFirebase, // firebaseConnect() can also be used
connect(
({ firebase: { profile } }) => ({
profile,
})
)
)(UpdateProfilePage)
```

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

Expand Down
48 changes: 33 additions & 15 deletions docs/recipes/roles.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Though there are many patterns, we are going to use the following terminology:

Add the Roles collection in Firebase. It should be a sibling of the `users` collection. For example:

_Tip: you can import below JSON directly into Firebase. Alternatively, you can populate it in the start of your application or when you deploy to Firebase._
_Tip: you can import below JSON directly into Firebase. Alternatively, you can upload it in the start of your application or when you deploy to Firebase._

```js
{
Expand Down Expand Up @@ -139,6 +139,8 @@ Here is an example of a UserHasPermission HOC that allows us to pass in a string

_Tip: you can place the below HOC in `router.js` together with `UserIsNotAuthenticated` and `UserIsAuthenticated`._

**redux-auth-wrapper v1**

```js
import { get } from 'lodash';
import { UserAuthWrapper } from 'redux-auth-wrapper';
Expand All @@ -152,36 +154,52 @@ import CircularProgress from 'material-ui/CircularProgress';
* @return {Component} wrappedComponent
*/
export const UserHasPermission = permission => UserAuthWrapper({
wrapperDisplayName: 'UserHasPermission',
LoadingComponent: LoadingScreen,
allowRedirectBack: false,
failureRedirectPath: '/login',
authSelector: ({ firebase: { profile, auth } }) => ({ auth, profile })
authenticatingSelector: ({ firebase: { profile, auth, isInitializing } }) =>
auth === undefined || profile === undefined || isInitializing === true,
predicate: auth => get(auth, `profile.role.${permission}`, false),
redirectAction: newLoc => (dispatch) => {
browserHistory.replace(newLoc);
dispatch({ type: UNAUTHED_REDIRECT });
},
failureRedirectPath: '/login',
});
```

**react-router v4 + redux-auth-wrapper v2**

```javascript
import locationHelperBuilder from 'redux-auth-wrapper/history4/locationHelper';
import { browserHistory } from 'react-router';
import LoadingScreen from '../components/LoadingScreen'; // change it to your custom component

const locationHelper = locationHelperBuilder({});

export const UserHasPermission = permission => UserAuthWrapper({
wrapperDisplayName: 'UserHasPermission',
predicate: auth => get(auth, `profile.role.${permission}`, false),
AuthenticatingComponent: LoadingScreen,
allowRedirectBack: false,
LoadingComponent: <CircularProgress mode="indeterminate" size={80} />,
redirectPath: (state, ownProps) =>
locationHelper.getRedirectQueryParam(ownProps) || '/login',
authenticatingSelector: ({ firebase: { auth, isInitializing } }) =>
!auth.isLoaded || !profile.isLoaded || isInitializing === true,
authenticatedSelector: ({ firebase: { auth } }) =>
auth.isLoaded && !auth.isEmpty,
redirectAction: newLoc => (dispatch) => {
browserHistory.replace(newLoc); // or routerActions.replace
dispatch({ type: UNAUTHED_REDIRECT });
}
});
```


## Checking for roles on pages/components

The Higher Order Component above can then be applied like so:

```js
export default UserHasPermission('todo')(SomeComponent)
```

or using es7 decorator syntax:

```js
@UserHasPermission('todos')
export default class SomePage extends Component {
render() {
// only rendered if user has role which matches this permission
}
}
```
39 changes: 23 additions & 16 deletions docs/recipes/routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const UserIsAuthenticated = UserAuthWrapper({
type: 'UNAUTHED_REDIRECT',
payload: { message: 'You must be authenticated.' },
})
},
}
})
```

Expand All @@ -85,29 +85,36 @@ import LoadingScreen from '../components/LoadingScreen'; // change it to your cu
const locationHelper = locationHelperBuilder({});

export const UserIsAuthenticated = connectedRouterRedirect({
wrapperDisplayName: 'UserIsAuthenticated',
AuthenticatingComponent: LoadingScreen,
allowRedirectBack: true,
redirectPath: (state, ownProps) =>
locationHelper.getRedirectQueryParam(ownProps) || '/login',
allowRedirectBack: true,
authenticatingSelector: ({ firebase: { auth, profile, isInitializing } }) =>
!auth.isLoaded || isInitializing === true,
authenticatedSelector: ({ firebase: { auth } }) =>
auth && auth.isLoaded && !auth.isEmpty,
authenticatingSelector: ({ firebase: { auth } }) =>
auth === undefined || !auth.isLoaded,
AuthenticatingComponent: Loading,
wrapperDisplayName: 'UserIsAuthenticated',
redirectAction: routerActions.replace, // can be same as v1
})
auth.isLoaded && !auth.isEmpty,
redirectAction: newLoc => (dispatch) => {
browserHistory.replace(newLoc); // or routerActions.replace
dispatch({ type: 'UNAUTHED_REDIRECT' });
},
});

export const UserIsNotAuthenticated = connectedRouterRedirect({
wrapperDisplayName: 'UserIsNotAuthenticated',
AuthenticatingComponent: LoadingScreen,
allowRedirectBack: false,
redirectPath: (state, ownProps) =>
locationHelper.getRedirectQueryParam(ownProps) || '/',
allowRedirectBack: false,
authenticatingSelector: ({ firebase: { auth, isInitializing } }) =>
!auth.isLoaded || isInitializing === true,
authenticatedSelector: ({ firebase: { auth } }) =>
auth && auth.isLoaded && auth.isEmpty,
authenticatingSelector: ({ firebase: { auth } }) =>
auth === undefined || !auth.isLoaded,
wrapperDisplayName: 'UserIsNotAuthenticated',
redirectAction: routerActions.replace, // can be same as v1
})
auth.isLoaded && auth.isEmpty,
redirectAction: newLoc => (dispatch) => {
browserHistory.replace(newLoc); // or routerActions.replace
dispatch({ type: 'UNAUTHED_REDIRECT' });
},
});
```


Expand Down
60 changes: 60 additions & 0 deletions docs/v2-migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* allows [`react-native-firebase`](https://github.com/invertase/react-native-firebase) to be passed (for using native modules instead of JS within `react-native`)
* firebase is no longer a dependency (shrinks umd bundle size)
* Auth state works differently - `{ isLoaded: false, isEmpty: false }` is the initialState instead of `undefined` - means updates to routing HOCs and other code using auth state (see [Routing Section below](#routing))
* `firebaseConnect` now passes `state` as second argument if function is passed. `store.firebase` is now third argument instead of second (see [state based query secont](#stateBasedQueries) below)
* `profileParamsToPopulate` does not automatically populate profile, populated version can be loaded with `populate` (there will most likely be an option to enable auto populating before `v2.0.0` is out of pre-release)
* Firestore is supported (setup shown below)
* `LOGOUT` is no longer dispatched on empty auth state changes (`enableEmptyAuthChanges: true` can be passed to dispatch `AUTH_EMPTY_CHANGE` action in its place)
Expand Down Expand Up @@ -290,6 +291,65 @@ const enhance = compose(
export default enhance(SomeComponent)
```

### State Based Queries {#stateBasedQueries}

`state` (from store.getState) is now the second argument instead of `firebaseInstance` (`store.firebase`), which is now the third argument.

**`v1.*.*`**

```js
import { compose } from 'redux'
import { connect } from 'react-redux'
import {
firebaseConnect,
populatedDataToJS,
pathToJS
} from 'react-redux-firebase';

const populates = [{ child: 'owner', root: 'users' }]

const enhance = compose(
connect(
(state) => ({
auth: pathToJS(state.firebase, 'auth')
})
)
firebaseConnect(
(props, firebaseInstance) => [
{ path: `todos/${props.auth.uid}` }
]
),
connect(
(state, props) => ({
todos: dataToJS(state.firebase, `todos/${props.auth.uid}`)
})
)
)
```

**`v2.*.*`**


```js
import { compose } from 'redux'
import { connect } from 'react-redux'
import { firebaseConnect } from 'react-redux-firebase';


const enhance = compose(
firebaseConnect(
(props, state, firebaseInstance) => [
{ path: `todos/${state.firebase.auth.uid}` }
]
),
connect(
({ firebase: { data, auth } }) => ({
todos: data.todos && data.todos[auth.uid]
})
)
)
```

### Empty Auth {#emptyAuth}

`enableEmptyAuthChanges`, which was created for [https://github.com/prescottprue/react-redux-firebase/issues/137]() no longer exists. It has been replaced by `preserveOnEmptyAuthChange` so that an action is still dispatched, and configuration can control what is preserved:
Expand Down
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-redux-firebase",
"version": "2.0.0-beta.13",
"version": "2.0.0-beta.14",
"description": "Redux integration for Firebase. Comes with a Higher Order Components for use with React.",
"main": "lib/index.js",
"module": "es/index.js",
Expand Down Expand Up @@ -56,6 +56,12 @@
"redux-react-firebase"
],
"dependencies": {
"gitbook-plugin-anchorjs": "^1.1.1",
"gitbook-plugin-edit-link": "^2.0.2",
"gitbook-plugin-ga": "^1.0.1",
"gitbook-plugin-github": "^2.0.0",
"gitbook-plugin-prism": "^2.3.0",
"gitbook-plugin-versions-select": "^0.1.1",
"hoist-non-react-statics": "^2.3.1",
"lodash": "^4.17.4",
"prop-types": "^15.5.10",
Expand Down