Skip to content

xymw/redux-firebasev3

 
 

Repository files navigation

redux-firebasev3

NPM version NPM downloads Build Status Dependency Status Code Coverage License Code Style Gitter

Higher Order Component (HOC) for using Firebase with React and Redux

Demo

View deployed version of Material Example here

Features

  • Integrated into redux
  • Firebase v3+ support
  • Support small data ( using value ) or large datasets ( using child_added, child_removed, child_changed
  • queries support ( orderByChild, orderByKey, orderByValue, orderByPriority, limitToLast, limitToFirst, startAt, endAt, equalTo right now )
  • Automatic binding/unbinding
  • Declarative decorator syntax for React components
  • Support for nested props
  • Out of the box support for authentication (with auto load user profile)
  • Lots of helper functions

Install

$ npm install --save redux-firebasev3

Before Use

Peer Dependencies

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 shows implementation without decorators, while the Decorators Example shows the same application with decorators implemented.

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:

  1. run npm i --save-dev babel-plugin-transform-decorators-legacy
  2. Add the following line to your .babelrc:
{
    "plugins": ["transform-decorators-legacy"]
}

Use

Include reduxFirebase in your store compose function:

import { createStore, combineReducers, compose } from 'redux'
import { reduxFirebase, firebaseStateReducer } from 'redux-firebasev3'

// 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(
  reduxFirebase(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 { firebase, helpers } from 'redux-firebasev3'
const { isLoaded, isEmpty, dataToJS } = helpers

// Can be used if firebase is used elsewhere
// import { firebaseConnect } from 'redux-firebasev3'
// @firebaseConnect( [
//   '/todos'
// ])

@firebase( [
  '/todos'
  // { type: 'once', path: '/todos' } // for loading once instead of binding
])
@connect(
  ({firebase}) => ({
    todos: dataToJS(firebase, '/todos'),
  })
)
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>
    )
  }
}
export default Todos

Alternatively, if you choose not to use decorators:

const wrappedTodos = firebase([
  '/todos'
])(Todos)
export default connect(
  ({firebase}) => ({
    todos: dataToJS(firebase, '/todos'),
  })
)(wrappedTodos)

See API Docs

A simple example that was created using create-react-app's. Shows a list of todo items and allows you to add to them.

The simple example implemented using decorators built from the output of create-react-app's eject command. 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.

Generator

generator-react-firebase uses redux-firebasev3 when opting to include redux

In the future

  • Redux Form Example
  • More Unit Tests/Coverage
  • Ideas are welcome :)

Contributors

Thanks

Special thanks to Tiberiu Craciun for creating redux-react-firebase, which this project is heavily based on.

About

Firebase v3 with redux

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%