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
Redux bindings for Firestore. Provides low-level API used in other libraries such as react-redux-firebase
Installation
npm install redux-firestore --saveNOTE
You probably want to be using react-redux-firebase.
If you are planning on using Firestore with Auth, Realtime DB, Storage or any other Firebase Products you will most likely want to use react-redux-firebase, which actually depends on this module.
This is a low level library that is meant to be used simple as a building block.
Use
import { createStore, combineReducers, compose } from 'redux'
import { reduxFirestore, firestoreReducer } from 'redux-firestore'
import firebase from 'firebase'
import 'firebase/firestore'
const firebaseConfig = {} // from Firebase Console
const rfConfig = {} // redux-firestore config
// Initialize firebase instance
const firebaseApp = firebase.initializeApp(config)
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)Then pass store to your component's context using react-redux's Provider:
ReactDOM.render(
<Provider store={store}>
<MyRootComponent />
</Provider>,
rootEl
)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.
import { connect } from 'react-redux'
import {
compose,
withHandlers,
lifecycle,
withContext,
getContext
} from 'recompose'
const withStore = compose(
withContext({ store: PropTypes.object }, () => {}),
getContext({ store: PropTypes.object }),
)
const enhance = compose(
withStore,
withHandlers({
loadData: props => () => 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) {
props.loadData()
}
}),
connect(({ firebase }) => ({ // state.firebase
todos: firebase.ordered.todos,
}))
)
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 { connect } from 'react-redux'
import { isEqual } from 'lodash'
import { watchEvents, unWatchEvents } from './actions/query'
import { getEventsFromInput, createCallable } from './utils'
class Todos extends Component {
static contextTypes = {
store: PropTypes.object.isRequired
}
componentWillMount () {
const { firebase } = this.context.store
firestore.get('todos')
}
render () {
return (
<div>
{
todos.map(todo => (
<div key={todo.id}>
{JSON.stringify(todo)}
</div>
))
}
</div>
)
}
}
export default connect((state) => ({
todos: state.firestore.ordered.todos
}))(Todos)Types of Queries
get
props.store.firestore.get({ collection: 'cities' }),
// store.firestore.get({ collection: 'cities', doc: 'SF' }), // doconSnapshot/setListener
store.firestore.onSnapshot({ collection: 'cities' }),
// store.firestore.setListener({ collection: 'cities' }), // alias
// store.firestore.setListener({ collection: 'cities', doc: 'SF' }), // docsetListeners
store.firestore.setListeners([
{ collection: 'cities' },
{ collection: 'users' },
]),Query Options
Collection
{ collection: 'cities' },
// or string equivalent
// store.firestore.get('cities'),Document
{ collection: 'cities', doc: 'SF' },
// or string equivalent
// props.store.firestore.get('cities/SF'),Sub Collections
{ collection: 'cities', doc: 'SF', subcollections: [{ collection: 'zipcodes' }] },
// or string equivalent
// props.store.firestore.get('cities/SF'),Where
Single To create a single where call, pass a single argument array to where
{
collection: 'cities',
where: ['state', '==', 'CA']
},Multiple
Multiple where queries are as simple as passing multiple argument arrays (each one representing a where call)
{
collection: 'cities',
where: [
['state', '==', 'CA'],
['population', '<', 100000]
]
},Should only be used with collections
storeAs
Storing data under a different path within redux is as easy as passing the storeAs parameter to your query:
{
collection: 'cities',
where: ['state', '==', 'CA'],
storeAs: 'caliCities' // store data in redux under this path instead of "cities"
},NOTE: Not yet supported for subcollections
Other Firebase Statics
Other Firebase statics (such as FieldValue) are available through the firestore instance:
import { connect } from 'react-redux'
import {
compose,
withHandlers,
lifecycle,
withContext,
getContext
} from 'recompose'
const withFirestore = compose(
withContext({ store: PropTypes.object }, () => {}),
getContext({ store: PropTypes.object }),
)
const enhance = compose(
withStore,
withHandlers({
onDoneClick: props => (key, done = true) => {
const { firestore } = props.store
return firestore.update('todos', key, {
done,
updatedAt: firestore.FieldValue.serverTimestamp() // use static from firestore instance
}),
}
})
)
export default enhance(SomeComponent)Applications Using This
- fireadmin.io - Firebase Instance Management Tool source available here)
Roadmap
v0.1.0 - Basic querying
redux-firestore can be used along side react-redux-firebase