Skip to content

Commit

Permalink
Version v1.2.0 (#37)
Browse files Browse the repository at this point in the history
## Breaking Changes
- Data gathered during population is now normalized in redux [following defined redux practice of normalizing](http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html) (instead of placed directly into nested object). **THIS BREAKS v1.1.5 AND EARLIER IMPLEMENTATIONS OF POPULATE**. Now population will require the usage of `populatedDataToJS`.
- `populatedDataToJS` function added to helpers (returns data populated from normalized state)
- `profileDecorator` config option renamed to `profileFactory` for clarity (`profileDecorator` still supported, but will throw deprecation warning)
- default file metadata written to database includes `downloadURL` instead of `downloadURLs` array
- Meta values (`timestamp`, `requesting`, `requested`) are now stored by string key (keeps invalid keyPath error from showing up)
- `enableRedirectHandling` config param added to enable/disable auth redirect handling (enabled by default, which can cause breakage in none HTTP/HTTPS environments)

## Enhancements
- `once` queries no longer cause `off` error due to unmounting non existent listener (fixes #36)
- login with auth redirect no longer returns null  and other redirect handling improvements (#33)
- deep set `invalid keyPath` error fixed in data section of reducer (deep list is null first then has value)
- `fileMetadataFactory` config option added to allow control of metadata written to database when using `uploadFile` and `uploadFiles`
- Profile Params Populate now working for both object and string notation
- Config params type validation
- Roadmap updated with `v2.0.0` plans
- `profileDecorator` backwards compatibility is included (with a deprecation warning)
- `CODE_OF_CONDUCT.md` and `PATRONS.md` added
- Docs + Tests updated
  • Loading branch information
prescottprue committed Jan 23, 2017
1 parent 0263b0b commit 3e2de97
Show file tree
Hide file tree
Showing 50 changed files with 1,754 additions and 589 deletions.
74 changes: 74 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at prescottprue@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]

[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
5 changes: 5 additions & 0 deletions PATRONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Patrons

Meet some of the outstanding companies and individuals that made it possible:

* [Reside Network Inc.](https://github.com/reside-eng)
30 changes: 20 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ Install peer dependencies: `npm i --save redux react-redux`

### Decorators

Though they are optional, it is highly recommended that you used decorators with this library. [The Simple Example](examples/simple) shows implementation without decorators, while [the Decorators Example](examples/decorators) shows the same application with decorators implemented.
Though they are optional, it is highly recommended that you use decorators with this library. [The Simple Example](examples/simple) shows implementation without decorators, while [the Decorators Example](examples/decorators) shows the same application with decorators implemented.

A side by side comparison using [react-redux](https://github.com/reactjs/react-redux)'s `connect` function/HOC is the best way to illustrate the difference:

#### Without Decorators
```javascript
class SomeComponent extends Component {

Expand All @@ -55,6 +56,7 @@ export default connect()(SomeComponent)
```
vs.

#### With Decorators
```javascript
@connect()
export default class SomeComponent extends Component {
Expand Down Expand Up @@ -112,7 +114,7 @@ const { isLoaded, isEmpty, dataToJS } = helpers

@firebaseConnect( [
'/todos'
// { type: 'once', path: '/todos' } // for loading once instead of binding
// { path: '/todos' } // object notation
])
@connect(
({ firebase }) => ({
Expand Down Expand Up @@ -178,8 +180,8 @@ export default connect(

```

## [Documentation](http://react-redux-firebase.com)
See [react-redux-firebase.com](http://react-redux-firebase.com)
## [Docs](http://react-redux-firebase.com)
See full documentation at [react-redux-firebase.com](http://react-redux-firebase.com)

* [Getting Started](http://react-redux-firebase.com/docs/getting_started)
* [Auth](http://react-redux-firebase.com/docs/auth)
Expand All @@ -189,7 +191,7 @@ See [react-redux-firebase.com](http://react-redux-firebase.com)

## [Examples](examples)

Examples folder is broken into two categories [complete](https://github.com/prescottprue/react-redux-firebase/tree/master/examples/complete) and [snippets](https://github.com/prescottprue/react-redux-firebase/tree/master/examples/snippets). Complete contains full applications that can be run as is, where as snippets is small amounts of code to show functionality (dev tools and deps not included).
Examples folder is broken into two categories [complete](https://github.com/prescottprue/react-redux-firebase/tree/master/examples/complete) and [snippets](https://github.com/prescottprue/react-redux-firebase/tree/master/examples/snippets). `/complete` contains full applications that can be run as is, while `/snippets` contains small amounts of code to show functionality (dev tools and deps not included).

#### [State Based Query Snippet](examples/snippets/stateBasedQuery)

Expand Down Expand Up @@ -276,9 +278,11 @@ const somethingEpic = (action$, store, getFirebase) =>
)
```

## Generator
## Starting A Project

[generator-react-firebase](https://github.com/prescottprue/generator-react-firebase) uses react-redux-firebase when opting to include redux
### Generator

[generator-react-firebase](https://github.com/prescottprue/generator-react-firebase) is a yeoman generator uses react-redux-firebase when opting to include redux

## FAQ

Expand All @@ -293,19 +297,25 @@ const somethingEpic = (action$, store, getFirebase) =>
* `uniqueSet` method helper for only setting if location doesn't already exist
* Object or String notation for paths (`[{ path: '/todos' }]` equivalent to `['/todos']`)
* Action Types and other Constants are exposed for external usage (such as with `redux-observable`)
* [Complete Firebase Auth Integration](http://react-redux-firebase.com/docs/auth.html#examples) including `signInWithRedirect` compatibility for OAuth Providers

#### Well why not combine?
I have been talking to the author of [redux-react-firebase](https://github.com/tiberiuc/redux-react-firebase) about combining, but we are not sure that the users of both want that at this point. Join us on the [redux-firebase gitter](https://gitter.im/redux-firebase/Lobby) if you haven't already since a ton of this type of discussion goes on there.

**Bottom line:** The author of redux-react-firebase was absent when functionality was needed by me and others, so this library was created.

2. Why use redux if I have Firebase to store state?

This isn't a super quick answer, so I wrote up [a medium article to explain](https://medium.com/@prescottprue/firebase-with-redux-82d04f8675b9)


# Patrons

Meet some of the outstanding companies and individuals that made it possible:

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


## Contributors
- [Prescott Prue](https://github.com/prescottprue)
- [Tiberiu Craciun](https://github.com/tiberiuc)
- [Bojhan](https://github.com/Bojhan)
- [Rahav Lussto](https://github.com/RahavLussato)
- [Justin Handley](https://github.com/justinhandley)
Expand Down
3 changes: 3 additions & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
* [Populate](/docs/populate.md)
* [Storage](/docs/storage.md)
* [Recipes](/docs/recipes/README.md)
* [Profile](/docs/recipes/profile.md)
* [Upload](/docs/recipes/upload.md)
* [Actions](/docs/recipes/actions.md)
* [Thunks](/docs/recipes/thunks.md)
* [Epics](/docs/recipes/epics.md)
* [Redux Form](/docs/recipes/redux-form.md)
* [Populate](/docs/recipes/populate.md)
* [API Reference](/docs/api/README.md)
* [constants](/docs/api/constants.md)
Expand Down
76 changes: 58 additions & 18 deletions docs/api/compose.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,42 @@

# reactReduxFirebase

Middleware that handles configuration (placed in redux's `compose` call)
Middleware that handles configuration (placed in redux's
`compose` call)

**Parameters**
**Properties**

- `fbConfig` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object containing Firebase config including databaseURL
- `fbConfig` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object containing Firebase config including
databaseURL
- `fbConfig.apiKey` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Firebase apiKey
- `fbConfig.authDomain` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Firebase auth domain
- `fbConfig.databaseURL` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Firebase database url
- `fbConfig.storageBucket` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Firebase storage bucket
- `config` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Containing react-redux-firebase specific config such as userProfile
- `config.userProfile` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Location on firebase to store user profiles
- `config.enableLogging` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Location on firebase to store user profiles. default: `false`
- `config.profileDecorator` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** Location on firebase to store user profiles. default: `false`
- `config.updateProfileOnLogin` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Whether or not to update profile when logging in. default: `false`
- `config.profileParamsToPopulate` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Parameters within profile object to populate
- `config.enableLogging` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Whether or not to enable Firebase database logging
- `config.updateProfileOnLogin` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Whether or not to update profile when logging in. (default: `false`)
- `config.enableRedirectHandling` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Whether or not to enable auth redirect handling listener. (default: `true`)
- `config.profileFactory` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** Factory for modifying how user profile is saved.
- `config.uploadFileDataFactory` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** Factory for modifying how file meta data is written during file uploads
- `config.profileParamsToPopulate` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String))** Parameters within profile object to populate

**Examples**

_Data_
_Setup_

```javascript
import { createStore, compose } from 'redux'
import { reactReduxFirebase } from 'react-redux-firebase'

// Firebase config
const fbConfig = {
apiKey: '<your-api-key>',
authDomain: '<your-auth-domain>',
databaseURL: '<your-database-url>',
storageBucket: '<your-storage-bucket>'
}

// React Redux Firebase Config
const config = {
userProfile: 'users'
userProfile: 'users', // saves user profiles to '/users' on Firebase
// here is where you place other config options
}

// Add react-redux-firebase to compose
// Note: In full projects this will often be within createStore.js or store.js
const createStoreWithFirebase = compose(
reactReduxFirebase(fbConfig, config),
)(createStore)
Expand All @@ -48,4 +46,46 @@ const createStoreWithFirebase = compose(
const store = createStoreWithFirebase(rootReducer, initialState)
```

Returns **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** Middleware function
Returns **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** That accepts a component a returns a wrapped version of component

# getFirebase

Expose Firebase instance created internally. Useful for
integrations into external libraries such as redux-thunk and redux-observable.

**Examples**

_redux-thunk integration_

```javascript
import { applyMiddleware, compose, createStore } from 'redux';
import thunk from 'redux-thunk';
import { reactReduxFirebase } from 'react-redux-firebase';
import makeRootReducer from './reducers';
import { getFirebase } from 'react-redux-firebase';

const fbConfig = {} // your firebase config

const store = createStore(
makeRootReducer(),
initialState,
compose(
applyMiddleware([
// Pass getFirebase function as extra argument
thunk.withExtraArgument(getFirebase)
]),
reactReduxFirebase(fbConfig)
)
);
// then later
export const addTodo = (newTodo) =>
(dispatch, getState, getFirebase) => {
const firebase = getFirebase()
firebase
.helpers
.push('todos', newTodo)
.then(() => {
dispatch({ type: 'SOME_ACTION' })
})
};
```
18 changes: 3 additions & 15 deletions docs/api/connect.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,6 @@ import { firebaseConnect } from 'react-redux-firebase'
export default firebaseConnect()(App)
```

_Paths_

```javascript
import { connect } from 'react-redux'
import { firebaseConnect, helpers } from 'react-redux-firebase'
const { pathToJS } = helpers

// pass todos list from redux as this.props.todosList
export default connect(({ firebase }) => ({
profile: pathToJS(firebase, 'profile'),
auth: pathToJS(firebase, 'auth')
}))(App)
```

_Data_

```javascript
Expand All @@ -49,7 +35,9 @@ const fbWrapped = firebaseConnect([

// pass todos list from redux as this.props.todosList
export default connect(({ firebase }) => ({
todosList: dataToJS(firebase, 'todos')
todosList: dataToJS(firebase, 'todos'),
profile: pathToJS(firebase, 'profile'), // pass profile data as this.props.proifle
auth: pathToJS(firebase, 'auth') // pass auth data as this.props.auth
}))(fbWrapped)
```

Expand Down
35 changes: 31 additions & 4 deletions docs/api/constants.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,41 @@ constants.actionsPrefix === '@@reactReduxFirebase' // true

Object containing all action types

**Properties**

- `START` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/START`
- `SET` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/SET`
- `SET_PROFILE` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/SET_PROFILE`
- `LOGIN` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/LOGIN`
- `LOGOUT` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/LOGOUT`
- `LOGIN_ERROR` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/LOGIN_ERROR`
- `NO_VALUE` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/NO_VALUE`
- `UNAUTHORIZED_ERROR` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/UNAUTHORIZED_ERROR`
- `INIT_BY_PATH` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/INIT_BY_PATH`
- `AUTHENTICATION_INIT_STARTED` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/AUTHENTICATION_INIT_STARTED`
- `AUTHENTICATION_INIT_FINISHED` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/AUTHENTICATION_INIT_FINISHED`
- `FILE_UPLOAD_START` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/FILE_UPLOAD_START`
- `FILE_UPLOAD_ERROR` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/FILE_UPLOAD_ERROR`
- `FILE_UPLOAD_PROGRESS` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/FILE_UPLOAD_PROGRESS`
- `FILE_UPLOAD_COMPLETE` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/FILE_UPLOAD_COMPLETE`
- `FILE_DELETE_START` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/FILE_DELETE_START`
- `FILE_DELETE_ERROR` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/FILE_DELETE_ERROR`
- `FILE_DELETE_COMPLETE` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `@@reactReduxFirebase/FILE_DELETE_COMPLETE`

**Examples**

```javascript
import { actionTypes } from 'react-redux-firebase'
actionTypes.SET === '@@reactReduxFirebase/SET' // true
```

```javascript
import { constants } from 'react-redux-firebase'
constants.actionTypes.SET === '@@reactReduxFirebase/SET' // true
```
# defaultConfig

Default configuration options

**Properties**

- `userProfile` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** `null` Location on Firebase where user profiles are stored. Often set to `'users'`.
- `enableLogging` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** `false` Whether or not firebase logging is enabled
- `updateProfileOnLogin` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** `true` Whether or not to update user profile when logging in
- `enableRedirectHandling` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** `true` Whether or not to enable redirect handling

0 comments on commit 3e2de97

Please sign in to comment.