redux-firebasev3

October 14, 2016 ยท View on GitHub

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

Deprecation Warning

react-redux-firebase is the new version of this library

This library will no longer be updated under this name after v1.0.0, please use react-redux-firebase.

Demo

View deployed version of Material Example here

Features

  • Integrated into redux
  • Population capability (similar to JOIN)
  • 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
  • Firebase v3+ support
  • Support for updating and nested props
  • Out of the box support for authentication (with auto load user profile)
  • Lots of helper functions

Install

NOTE: redux-firebasev3 has been moved to react-redux-firebase

API

See API Docs

Generator

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

Use

Include reduxFirebase in your store compose function:

import { createStore, combineReducers, compose } from 'redux'
import { reduxFirebase, 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(
  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 'react-redux-firebase'
const { isLoaded, isEmpty, dataToJS } = helpers

// Can be used if firebase is used elsewhere
// import { firebaseConnect } from 'react-redux-firebase'
// @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)