Redux bindings for Firebase. Includes Higher Order Component (HOC) for use with React.
The Material Example is deployed to demo.react-redux-firebase.com.
- Integrated into redux
 - Support for updating and nested props
 - Population capability (similar to mongoose's 
populateor SQL'sJOIN) - Out of the box support for authentication (with auto load user profile)
 - Firebase Storage Support
 - Support small data ( using 
value) or large datasets ( usingchild_added,child_removed,child_changed) - queries support ( 
orderByChild,orderByKey,orderByValue,orderByPriority,limitToLast,limitToFirst,startAt,endAt,equalToright now ) - Automatic binding/unbinding
 - Declarative decorator syntax for React components
 redux-thunkandredux-observableintegrations- Action Types and other Constants exported for external use (such as in 
redux-observable) - Firebase v3+ support
 - Server Side Rendering Support
 react-nativesupport
npm install --save react-redux-firebaseInstall peer dependencies: npm i --save redux react-redux
Though they are optional, it is highly recommended that you use decorators with this library. The Simple Example shows implementation without decorators, while the Decorators Example shows the same application with decorators implemented.
A side by side comparison using react-redux's connect function/HOC is the best way to illustrate the difference:
class SomeComponent extends Component {
}
export default connect()(SomeComponent)vs.
@connect()
export default class SomeComponent extends Component {
}In order to enable this functionality, you will most likely need to install a plugin (depending on your build setup). For Webpack and Babel, you will need to make sure you have installed and enabled babel-plugin-transform-decorators-legacy by doing the following:
- run 
npm i --save-dev babel-plugin-transform-decorators-legacy - Add the following line to your 
.babelrc: 
{
    "plugins": ["transform-decorators-legacy"]
}
Include reduxFirebase in your store compose function:
import { createStore, combineReducers, compose } from 'redux'
import { reactReduxFirebase, firebaseStateReducer } from 'react-redux-firebase'
// Add Firebase to reducers
const rootReducer = combineReducers({
  firebase: firebaseStateReducer
})
// Firebase config
const config = {
  apiKey: '<your-api-key>',
  authDomain: '<your-auth-domain>',
  databaseURL: '<your-database-url>',
  storageBucket: '<your-storage-bucket>'
}
// Add redux Firebase to compose
const createStoreWithFirebase = compose(
  reactReduxFirebase(config, { userProfile: 'users' }),
)(createStore)
// Create store with reducers and initial state
const store = createStoreWithFirebase(rootReducer, initialState)In components:
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import {
  firebaseConnect,
  isLoaded,
  isEmpty,
  dataToJS
} from 'react-redux-firebase'
@firebaseConnect([
  '/todos'
  // { path: '/todos' } // object notation
])
@connect(
  ({ firebase }) => ({
    // Connect todos prop to firebase todos
    todos: dataToJS(firebase, '/todos'),
  })
)
export default class Todos extends Component {
  static propTypes = {
    todos: PropTypes.object,
    firebase: PropTypes.object
  }
  render() {
    const { firebase, todos } = this.props;
    // Add a new todo to firebase
    const handleAdd = () => {
      const {newTodo} = this.refs
      firebase.push('/todos', { text:newTodo.value, done:false })
      newTodo.value = ''
    }
    // Build Todos list if todos exist and are loaded
    const todosList = !isLoaded(todos)
      ? 'Loading'
      : isEmpty(todos)
        ? 'Todo list is empty'
        : Object.keys(todos).map(
            (key, id) => (
              <TodoItem key={key} id={id} todo={todos[key]}/>
            )
          )
    return (
      <div>
        <h1>Todos</h1>
        <ul>
          {todosList}
        </ul>
        <input type="text" ref="newTodo" />
        <button onClick={handleAdd}>
          Add
        </button>
      </div>
    )
  }
}Alternatively, if you choose not to use decorators:
import { compose } from 'redux'
export default compose(
  firebaseConnect(['/todos']),
  connect(
    ({firebase}) => ({ todos: dataToJS(firebase, '/todos') })
  )
)(Todos)Firebase's library requires XML request capability, so if you are using react-redux-firebase in a Server Side rendering environment, make sure you require xmlhttprequest.
If you disagree with having to do this yourself, hop on gitter and let us know!
// needed to fix "Error: The XMLHttpRequest compatibility library was not found."
global.XMLHttpRequest = require('xmlhttprequest').XMLHttpRequestSee full documentation at react-redux-firebase.com
Examples folder is broken into two categories complete and 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).
Snippet showing querying based on data in redux state. One of the most common examples of this is querying based on the current users auth UID.
Snippet showing how to use decorators to simplify connect functions (redux's connect and react-redux-firebase's firebaseConnect)
A simple example that was created using create-react-app's. Shows a list of todo items and allows you to add to them.
An example that user Material UI built on top of the output of create-react-app's eject command. Shows a list of todo items and allows you to add to them. This is what is deployed to redux-firebasev3.firebaseapp.com.
Join us on the redux-firebase gitter.
If you are using redux-thunk, make sure to set up your thunk middleware using it's redux-thunk's withExtraArgument method so that firebase is available within your actions. Here is an example createStore function that adds getFirebase as third argument along with a thunk that uses it:
createStore:
import { applyMiddleware, compose, createStore } from 'redux';
import thunk from 'redux-thunk';
import { reactReduxFirebase, getFirebase } from 'react-redux-firebase';
import makeRootReducer from './reducers';
const fbConfig = {} // your firebase config
const config = {
  userProfile: 'users',
  enableLogging: false
}
const store = createStore(
  makeRootReducer(),
  initialState,
  compose(
    applyMiddleware([
      thunk.withExtraArgument(getFirebase) // Pass getFirebase function as extra argument
    ]),
    reactReduxFirebase(fbConfig, config)
  )
);Action:
import { pathToJS } from 'react-redux-firebase'
export const addTodo = (newTodo) =>
  (dispatch, getState, getFirebase) => {
    const auth = pathToJS(getState.firebase, 'auth')
    newTodo.createdBy = auth.uid //
    getFirebase()
      .push('todos', newTodo)
      // using pushWithMeta instead would attach createdBy and createdAt automatically
      .then(() => {
        dispatch({
          type: 'TODO_CREATED',
          payload: newTodo
        })
      })
  };If you are using redux-observable, make sure to set up your redux-observable middleware so that firebase is available within your epics. Here is an example combineEpics function that adds getFirebase as third argument along with an epic that uses it:
import { getFirebase } from 'react-redux-firebase'
import { combineEpics } from 'redux-observable'
const rootEpic = (...args) =>
  combineEpics(somethingEpic, epic2)(..args, getFirebase)
// then later in your epics
const somethingEpic = (action$, store, getFirebase) =>
  action$.ofType(SOMETHING)
    .map(() =>
      getFirebase().push('somePath/onFirebase', { some: 'data' })
    )For full example, go to the Routing Recipes Section of the docs
In order to only allow authenticated users to view a page, a UserIsAuthenticated Higher Order Component can be created:
import { browserHistory } from 'react-router'
import { UserAuthWrapper } from 'redux-auth-wrapper'
import { pathToJS } from 'react-redux-firebase'
export const UserIsAuthenticated = UserAuthWrapper({
  wrapperDisplayName: 'UserIsAuthenticated',
  authSelector: ({ firebase }) => pathToJS(firebase, 'auth'),
  authenticatingSelector: ({ firebase }) =>
    pathToJS(firebase, 'isInitializing') === true ||
    pathToJS(firebase, 'auth') === undefined
  predicate: auth => auth !== null,
  redirectAction: (newLoc) => (dispatch) => {
    browserHistory.replace(newLoc)
    dispatch({
      type: 'UNAUTHED_REDIRECT',
      payload: { message: 'You must be authenticated.' },
    })
  },
})Then it can be used as a Higher Order Component wrapper on a component:
@UserIsAuthenticated // redirects to '/login' if user not is logged in
export default class ProtectedThing extends Component {
  render() {
    return (
      <div>
        You are authed!
      </div>
    )
  }
}generator-react-firebase is a yeoman generator uses react-redux-firebase when opting to include redux.
The examples folder contains full applications that can be copied/adapted and used as a new project.
- How is this different than 
redux-react-firebase? 
This library was actually originally forked from redux-react-firebase, but adds extended functionality such as:
- populate functionality (similar to mongoDB or SQL JOIN)
 profileDecorator- change format of profile stored on FirebasegetFirebase- access to firebase instance that fires actions when methods are called- integrations for 
redux-thunkandredux-observable- usinggetFirebase - access to firebase's 
storagemethod` uniqueSetmethod 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) - Server Side Rendering Support
 - Complete Firebase Auth Integration including 
signInWithRedirectcompatibility for OAuth Providers 
I have been talking to the author of 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 if you haven't already since a ton of this type of discussion goes on there.
- 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
- Where can I find some examples?
 
- Recipes Section of the docs
 - examples folder contains complete example apps as well as useful snippets
 
- How does 
connectrelate tofirebaseConnect? 
- How do I help?
 
- Join the conversion on gitter
 - Post Issues
 - Create Pull Requests
 
Meet some of the outstanding companies and individuals that made it possible:
Special thanks to Tiberiu Craciun for creating redux-react-firebase, which this project was originally based on.

