@taraai/read-write
Version:
Synchronous NoSQL/Firestore for React
111 lines (102 loc) • 3.73 kB
JavaScript
import { defaultConfig } from './constants';
import createFirestoreInstance from './createFirestoreInstance';
let firestoreInstance;
/**
* @name reduxFirestore
* @external
* Redux store enhancer that accepts configuration options and adds
* store.firestore. Enhancers are most commonly placed in redux's `compose` call
* along side applyMiddleware.
* @param {object} firebaseInstance - Initiated firebase instance
* @param {object} otherConfig - Containing react-redux-firebase specific configuration
* @returns {Function} That accepts a component and returns a Component which
* wraps the provided component (higher order component).
* @example <caption>Setup</caption>
* import { createStore, compose } from 'redux'
* import { reduxFirestore } from 'redux-firestore'
* import firebase from 'firebase' // must be 4.5.0 or higher
import 'firebase/firestore' // make sure you add this for firestore
* // Redux Firestore Config
* const config = {
* // here is where you place other config options
* }
* // initialize script from Firestore page
* const fbConfg = {} // firebase config object
* firebase.initializeApp(fbConfig)
* firebase.firestore()
*
* // Add redux-firestore enhancer to store creation compose
* // Note: In full projects this will often be within createStore.js or store.js
const store = createStore(
makeRootReducer(),
initialState,
compose(
// pass firebase instance and config
reduxFirestore(firebase, reduxConfig),
// applyMiddleware(...middleware),
// ...enhancers
)
)
*
* // Use Function later to create store
* const store = createStoreWithFirestore(rootReducer, initialState)
*/
export default function reduxFirestore(firebaseInstance, otherConfig) {
return (next) => (reducer, initialState, middleware) => {
const store = next(reducer, initialState, middleware);
const configs = { ...defaultConfig, ...otherConfig };
firestoreInstance = createFirestoreInstance(
firebaseInstance.firebase_ || firebaseInstance, // eslint-disable-line no-underscore-dangle, no-undef, max-len
configs,
store.dispatch, // eslint-disable-line comma-dangle
);
store.firestore = firestoreInstance;
return store;
};
}
/**
* Expose Firestore instance created internally. Useful for
* integrations into external libraries such as redux-thunk and redux-observable.
* @returns {object} Firebase Instance
* @example <caption>redux-thunk integration</caption>
* import { applyMiddleware, compose, createStore } from 'redux';
* import thunk from 'redux-thunk';
* import makeRootReducer from './reducers';
* import { reduxFirestore, getFirestore } from 'redux-firestore';
*
* const fbConfig = {} // your firebase config
*
* const store = createStore(
* makeRootReducer(),
* initialState,
* compose(
* applyMiddleware([
* // Pass getFirestore function as extra argument
* thunk.withExtraArgument(getFirestore)
* ]),
* reduxFirestore(fbConfig)
* )
* );
* // then later
* export const addTodo = (newTodo) =>
* (dispatch, getState, getFirestore) => {
* const firebase = getFirestore()
* firebase
* .add('todos', newTodo)
* .then(() => {
* dispatch({ type: 'SOME_ACTION' })
* })
* };
*
*/
export function getFirestore() {
// TODO: Handle receiveing config and creating firebase instance if it doesn't exist
/* istanbul ignore next: Firebase instance always exists during tests */
if (!firestoreInstance) {
throw new Error(
'Firebase instance does not yet exist. Check your compose function.',
);
}
// TODO: Create new firebase here with config passed in
return firestoreInstance;
}