JSPM

  • Created
  • Published
  • Downloads 2561
  • Score
    100M100P100Q114142F
  • License MIT

Redux bindings for Firestore.

Package Exports

  • redux-firestore

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (redux-firestore) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

redux-firestore

NPM version NPM downloads License Code Style Dependency Status Build Status

Gitter

Redux bindings for Firestore

NOTE: This library is still under construction, use at your own risk

Installation

npm install redux-firestore --save

Use

import { createStore, combineReducers, compose } from 'redux'
import { reduxFirestore, firestoreReducer } from 'redux-firestore'
import firebase from 'firebase'
import 'firebase/firestore'

const firebaseConfig = {
  apiKey: '<your-api-key>',
  authDomain: '<your-auth-domain>',
  databaseURL: '<your-database-url>',
  storageBucket: '<your-storage-bucket>'
}
const rfConfig = { userProfile: 'users' } // react-redux-firebase config

// initialize firebase instance
const firebaseApp = firebase.initializeApp(config) // <- new to v2.*.*
firebase.firestore(); // Initialize Cloud Firestore through Firebase

// Add reduxReduxFirebase to compose
const createStoreWithFirebase = compose(
  reduxFirestore(firebaseApp, rfConfig), // firebase instance as first argument
)(createStore)

// Add Firebase to reducers
const rootReducer = combineReducers({
  firestore: firestoreReducer
})

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

Call Firestore

Firestore Instance

Functional Components

It is common to make react components "stateless" meaning that the component is just a function. This can be useful, but then can limit usage of lifecycle hooks and other features of Component Classes. recompose helps solve this by providing Higher Order Component functions such as withContext, lifecycle, and withHandlers.

const withStore = compose(
  withContext({ store: PropTypes.object }, () => {}),
  getContext({ store: PropTypes.object }),
)
const enhance = compose(
  withStore,
  withHandlers({
    loadData: props => err => props.store.firestore.get('todos'),
    onDoneClick: props => (key, done = false) =>
      props.store.firestore.update('todos', key, { done }),
    onNewSubmit: props => newTodo =>
      props.store.firestore.add('todos', { ...newTodo, owner: 'Anonymous' }),
  }),
  lifecycle({
    componentWillMount(props) {
      console.log('props', this.props)
    }
  }),
  connect(({ firebase }) => ({ // state.firebase
    // ImmutableJS map (for plain js checkout v2)
    todos: firebase.ordered.todos,
  }))
)(Some)

export default enhance(SomeComponent)

For more information on using recompose visit the docs

Component Class
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { isEqual } from 'lodash'
import { watchEvents, unWatchEvents } from './actions/query'
import { getEventsFromInput, createCallable } from './utils'

export const firebaseConnect = (dataOrFn = []) => WrappedComponent => {
  class FirebaseConnect extends Component {
    static contextTypes = {
      store: PropTypes.object.isRequired
    }

    componentWillMount () {
      const { firebase, dispatch } = this.context.store
      firebase.watchEvent(firebase, dispatch, 'todos')
    }

    componentWillUnmount () {
      const { firebase, dispatch } = this.context.store
      firebase.unWatchEvent(firebase, dispatch, 'todos')
    }

    render () {
      return (
        <WrappedComponent
          {...this.props}
          {...this.state}
          firebase={this.firebase}
        />
      )
    }
  }

  return FirebaseConnect
}

Middleware

redux-firestore's enhancer offers a new middleware setup that was not offered in react-redux-firebase (but will eventually make it redux-firebase) Note: This syntax is just a sample and is not currently released

import { actionTypes } from 'redux-firestore'

dispatch({
  type: actionTypes.FIREBASE_CALL,
  namespace: 'firestore' ,// database, auth, storage, etc
  collection: 'users', // only used when namespace is firestore
  method:  'get' // get method
})

Some of the goals behind this approach include:

  1. Not needing to pass around a Firebase instance (with react-redux-firebase this meant using firebaseConnect HOC or getFirebase)
  2. Follows patterns outlined in the redux docs for data fetching
  3. Easier to expand/change internal API as Firebase/Firestore API grows & changes

Roadmap

v0.1.0 - Basic querying