Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mklemme/e027244d76cd898c132659dd054dceb1 to your computer and use it in GitHub Desktop.
Save mklemme/e027244d76cd898c132659dd054dceb1 to your computer and use it in GitHub Desktop.
Firebase Middleware on Redux - Follow up on "react-redux-universal-hot-example" (Firebase login example)
/**
* @path src/redux/middleware
*
* Extract from clientMiddleware example in order to showcase
* the difference and help in understanding the same.
*
* @diff - Differences with "react-redux-universal-hot-example"
*/
export default function firebaseMiddleware(fireRef) {
return ({dispatch, getState}) => {
return next => action => {
if (typeof action === 'function') {
return action(dispatch, getState);
}
// @diff Look for the firebase related actions instead of promise/client ones
const { firebase, types, ...rest } = action; // eslint-disable-line no-redeclare
// @diff if there is none, move on, same as promise/client
if (!firebase) {
return next(action);
}
const [REQUEST, SUCCESS, FAILURE] = types;
next({...rest, type: REQUEST});
const firebasePromise = firebase(fireRef);
firebasePromise.then(
(result) => next({...rest, result, type: SUCCESS}),
(error) => next({...rest, error, type: FAILURE})
).catch((error)=> {
console.error('MIDDLEWARE ERROR:', error);
next({...rest, error, type: FAILURE});
});
return firebasePromise;
};
};
}
/**
* @path src/redux
*
* Simple store binding change
*
* @diff - Differences with "react-redux-universal-hot-example"
*/
import { createStore as _createStore, applyMiddleware, compose } from 'redux';
import createMiddleware from './middleware/clientMiddleware';
// @diff firebaseMiddleware
import firebaseMiddleware from './middleware/firebaseMiddleware';
import { syncHistory } from 'react-router-redux';
// @diff accept firebase reference
export default function createStore(history, {client, firebase}, data) {
// Sync dispatched route actions to the history
const reduxRouterMiddleware = syncHistory(history);
// @diff line up firebase middleware
const middleware = [createMiddleware(client), firebaseMiddleware(firebase), reduxRouterMiddleware];
let finalCreateStore;
if (__DEVELOPMENT__ && __CLIENT__ && __DEVTOOLS__) {
const { persistState } = require('redux-devtools');
const DevTools = require('../containers/DevTools/DevTools');
finalCreateStore = compose(
applyMiddleware(...middleware),
window.devToolsExtension ? window.devToolsExtension() : DevTools.instrument(),
persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/))
)(_createStore);
} else {
finalCreateStore = applyMiddleware(...middleware)(_createStore);
}
const reducer = require('./modules/reducer');
const store = finalCreateStore(reducer, data);
reduxRouterMiddleware.listenForReplays(store);
if (__DEVELOPMENT__ && module.hot) {
module.hot.accept('./modules/reducer', () => {
store.replaceReducer(require('./modules/reducer'));
});
}
return store;
}
/**
* @path src
*
* @diff - Differences with "react-redux-universal-hot-example"
*/
import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import createStore from './redux/create';
import ApiClient from './helpers/ApiClient';
// @diff include Firebase, this is my helper, you can just use firebase package
import Firebase from './helpers/Firebase.js';
import io from 'socket.io-client';
import {Provider} from 'react-redux';
import { Router, browserHistory } from 'react-router';
import { ReduxAsyncConnect } from 'redux-async-connect';
import useScroll from 'scroll-behavior/lib/useStandardScroll';
import getRoutes from './routes';
// @diff fire it up
const firebase = new Firebase();
const client = new ApiClient();
const history = useScroll(() => browserHistory)();
const dest = document.getElementById('content');
// @diff param
const store = createStore(history, {client, firebase}, window.__data);
// ...
/**
* @path src
*
* Make the server.js adopt to the store changes.
* Replace.
*/
const store = createStore(history, {client});
//const store = createStore(history, client);
/**
* @path src/redux/modules
*
* Finally lets change old action using the client API
* into a Firebase login.
* Be sure to pass over a new 'password' param from containers/Login.
*
* Replace.
*/
export function login(name, password) {
return {
types: [LOGIN, LOGIN_SUCCESS, LOGIN_FAIL],
firebase: (fireRef) => fireRef.authWithPassword({password: password, email: name})
}
}
/**
-- OLD --
export function login(name) {
return {
types: [LOGIN, LOGIN_SUCCESS, LOGIN_FAIL],
promise: (client) => client.post('/login', {
data: {
name: name
}
})
};
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment