react-redux-firebase

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

Gitter

Redux bindings for Firebase. Includes Higher Order Component (HOC) for use with React.

Demo

The Material Example is deployed to demo.react-redux-firebase.com.

Features

  • Support for updating and nested props
  • Population capability (similar to mongoose's populate or SQL's JOIN)
  • Out of the box support for authentication (with auto load user profile)
  • Firebase Database, Firestore, Auth, Storage, and Messaging Support
  • Support small data ( using value ) or large datasets ( using child_added, child_removed, child_changed )
  • queries including orderByChild, orderByKey, orderByValue, orderByPriority, limitToLast, limitToFirst, startAt, endAt, equalTo
  • Automatic binding/unbinding through firestoreConnect (manual through watchEvent)
  • Declarative decorator syntax for React components
  • Tons of integrations including redux-thunk and redux-observable
  • Action Types and other Constants exported for external use (such as in redux-observable)
  • Firebase v3+ support
  • Server Side Rendering Support
  • react-native support using native modules or web sdk

Install

npm install --save react-redux-firebase@next

Use

Include reactReduxFirebase in your store compose function and firebaseReducer in your reducers:

import { createStore, combineReducers, compose } from 'redux'
import { reactReduxFirebase, firebaseReducer } from 'react-redux-firebase'
import firebase from 'firebase'
// import 'firebase/firestore' // <- needed if using firestore

const firebaseConfig = {}

// react-redux-firebase config
const rrfConfig = {
  userProfile: 'users',
  // useFirestoreForProfile: true // Firestore for Profile instead of Realtime DB
}

// initialize firebase instance
firebase.initializeApp(config) // <- new to v2.*.*

// initialize firestore
// firebase.firestore() // <- needed if using firestore

// Add reduxReduxFirebase enhancer when making store creator
const createStoreWithFirebase = compose(
  reactReduxFirebase(firebase, rrfConfig), // firebase instance as first argument
  // reduxFirestore(firebase) // <- needed if using firestore
)(createStore)

// Add Firebase to reducers
const rootReducer = combineReducers({
  firebase: firebaseReducer,
  // firestore: firestoreReducer // <- needed if using firestore
})

// Create store with reducers and initial state
const initialState = {}
const store = createStoreWithFirebase(rootReducer, initialState)

In components:

Add Data

import React from 'react'
import PropTypes from 'prop-types'
import { withFirebase } from 'react-redux-firebase'

const Todos = ({ firebase }) => {
  const sampleTodo = { text: 'Sample', done: false }
  const pushSample = () => firebase.push('todos', sampleTodo)
  return (
    <div>
      <h1>Todos</h1>
      <ul>
        {todosList}
      </ul>
      <input type="text" ref="newTodo" />
      <button onClick={pushSample}>
        Add
      </button>
    </div>
  )
}

export default withFirebase(Todos)
// or firebaseConnect()(Todos) if attaching listeners

Load Data (listeners managed on mount/unmount)

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

const Todos = ({ todos, firebase }) => {
  // 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={this.handleAdd}>
        Add
      </button>
    </div>
  )
}

export default compose(
  firebaseConnect([
    'todos' // { path: '/todos' } // object notation
  ]),
  connect(
    (state) => ({
      todos: state.firebase.data.todos,
      // profile: state.firebase.profile // load profile
    })
  )
)(Todos)

Load Data On Click

import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { compose } from 'redux'
import { withFirebase, isLoaded, isEmpty } from 'react-redux-firebase'

const Todos = ({ firebase }) => {
  // 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>
      <button onClick={() => firebase.watchEvent('value', 'todos')}>
        Load Todos
      </button>
    </div>
  )
}

export default compose(
  withFirebase, // or firebaseConnect()
  connect(
    (state) => ({
      todos: state.firebase.data.todos,
      // profile: state.firebase.profile // load profile
    })
  )
)(Todos)

Queries Based On State Todos component from above examples

import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { compose } from 'redux'
import { firebaseConnect } from 'react-redux-firebase'

export default compose(
  firebaseConnect((props, store) => {
    const state = store.getState();
    // Get Todos stored by user UID
    return state.auth ? [`todos/${state.auth.uid}`] : []
  }),
  connect(
    (state) => ({
      todos: state.firebase.data.todos,
      // profile: state.firebase.profile // load profile
    })
  )
)(Todos)

Docs

See full documentation at react-redux-firebase.com

Examples

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).

State Based Query Snippet

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.

Decorators Snippet

Snippet showing how to use decorators to simplify connect functions (redux's connect and react-redux-firebase's firebaseConnect)

Simple App Example

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

Material App Example

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.

Discussion

Join us on the redux-firebase gitter.

Integrations

View docs for recipes on integrations with:

Starting A Project

Generator

generator-react-firebase is a yeoman generator uses react-redux-firebase when opting to include redux.

Complete Examples

The examples folder contains full applications that can be copied/adapted and used as a new project.

FAQ

Please visit the FAQ section of the docs

Contributors

This project exists thanks to all the people who contribute.

Backers

Thank you to all our backers! 🙏

results matching ""

    No results matching ""