https://gyazo.com/64dd39bc0d236709ea16112c2775b51d
Hello there! I was trying to introduce google auth to my react-redux app for over a week and I was finally able to solve the problem.
First, I encountered this problem and I read almost all the solutions online but it did not help at all!
If you look at those solutions, most of them "decrease the version of history", but if it did not work, maybe you wanna take a look at my article!
I followed this tutorial https://github.com/GoZaddy/react-redux-firebase-article/blob/master/src to introduce Google Auth to my application. And its index.js is as follows.
index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
import { createStore, compose } from "redux";
import { Provider } from "react-redux";
import { ReactReduxFirebaseProvider } from "react-redux-firebase";
import { createFirestoreInstance } from "redux-firestore";
import { rootReducer } from "./ducks/reducers";
import App from "./App";
import { BrowserRouter } from "react-router-dom";
import * as serviceWorker from "./serviceWorker";
const firebaseConfig = {
apiKey: "AIzaSyBJTFQkg95Aj-s_NsA77mco8ZVG2siLv4U",
authDomain: "react-redux-firebase-article.firebaseapp.com",
databaseURL: "https://react-redux-firebase-article.firebaseio.com",
projectId: "react-redux-firebase-article",
storageBucket: "react-redux-firebase-article.appspot.com",
messagingSenderId: "781345165856",
appId: "1:781345165856:web:45fd42a60e5bb365172245",
measurementId: "G-XFR3YXLCGW",
};
const rrfConfig = {
userProfile: "users",
useFirestoreForProfile: true,
};
firebase.initializeApp(firebaseConfig);
firebase.firestore();
const initialState = {};
const store = createStore(rootReducer, initialState);
const rrfProps = {
firebase,
config: rrfConfig,
dispatch: store.dispatch,
createFirestoreInstance,
};
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<ReactReduxFirebaseProvider {...rrfProps}>
<BrowserRouter>
<App />
</BrowserRouter>
</ReactReduxFirebaseProvider>
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
I tried every solution online about this error so I thought
Error: Could not find router reducer in state tree, it must be mounted under "router"
I thought this error was occurring because of my Ducks pattern. So I tried to convert this index.js file to Ducks pattern then I was even more stuck and I didn't know what to do.
I spent a lot of time looking for how I can convert this Google Auth index.js file to Ducks pattern but I found zero articles. I followed some articles that explain how to convert from Re-ducks pattern to Ducks pattern and I followed but I started to get different errors continuously.
So I hired a tutor and asked a question and I was finally able to solve this problem.
Here is the important point. If you follow Ducks pattern, you don't wanna convert Google Auth index.js file to Ducks pattern because it makes things very complicated.
If you find this error while you are working on react-redux-firebase
Error: Could not find router reducer in state tree, it must be mounted under "router"
you should look at this official document.
https://www.npmjs.com/package/connected-react-router
For me, my problem was I did not have
<Provider store={store}>
in my App.js file.
Here is my App.js file.
import React, { Suspense } from 'react';
import { BrowserRouter as Router,Switch, Route} from 'react-router-dom';
import Top from './components/Top';
import Contact from './components/Contact';
import SignUp from './components/SignUp';
import SignIn from './components/SignIn';
import SignOut from './components/SignOut';
import { ConnectedRouter } from 'connected-react-router';
import {history} from './configureStore';
import { Provider } from 'react-redux'
import {configureStore} from './configureStore';
const store = configureStore();
const App = () => {
return (
<React.Fragment>
<Provider store={store}>
<ConnectedRouter history={history}>
<Switch>
<Route exact path="/" component={Top}/>
</Switch>
<Switch>
<Route exact path="/contact" component={Contact}/>
</Switch>
<Switch>
<Route exact path="/signup" component={SignUp}/>
</Switch>
<Switch>
<Route exact path="/signin" component={SignIn}/>
</Switch>
<Switch>
<Route exact path="/signout" component={SignOut}/>
</Switch>
<Switch>
<Route exact path="/top" component={Top}/>
</Switch>
</ConnectedRouter>
</Provider>
</React.Fragment>
)
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'
import { Provider } from 'react-redux';
import {configureStore} from './configureStore';
import firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
import { useHistory } from "react-router-dom";
import { createFirestoreInstance } from "redux-firestore";
import { BrowserRouter } from "react-router-dom";
import { useDispatch, useSelector } from 'react-redux';
import { ReactReduxFirebaseProvider } from "react-redux-firebase";
import { createStore, compose } from "redux";
import { rootReducer } from "./rootReducer";
const firebaseConfig = {
apiKey: "AIzaSyAOSBfTj_VQ4byWAAOWDhAsklmZtk2W_iE",
authDomain: "stresstackle-599d9.firebaseapp.com",
projectId: "stresstackle-599d9",
storageBucket: "stresstackle-599d9.appspot.com",
messagingSenderId: "930013144401",
appId: "1:930013144401:web:79b25db79f4118359fdf70",
measurementId: "G-J26Y6MYWV3"
};
const rrfConfig = {
userProfile: "users",
useFirestoreForProfile: true,
};
firebase.initializeApp(firebaseConfig);
firebase.firestore();
const initialState = {};
const store = createStore(rootReducer, initialState);
const rrfProps = {
firebase,
config: rrfConfig,
dispatch: store.dispatch,
createFirestoreInstance,
};
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<ReactReduxFirebaseProvider {...rrfProps}>
<App />
</ReactReduxFirebaseProvider>
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
/src/configureStore.js
import { createStore, applyMiddleware, compose } from 'redux';
import { routerMiddleware } from 'connected-react-router';
import {rootReducer} from './rootReducer';
// import thunk from 'redux-thunk';
// import logger from 'redux-logger';
const createBrowserHistory = require('history').createBrowserHistory;
export const history = createBrowserHistory();
//これをApp.jsに渡した
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
export function configureStore(preloadedState) {
const store = createStore(
rootReducer(history),
preloadedState,
composeEnhancers(
applyMiddleware(
routerMiddleware( history),
)
)
);
return store;
};
//↑Redux dev toolsとconnectingしている
/src/rootReducer.js
import {combineReducers} from 'redux';
import { connectRouter } from 'connected-react-router';
import {firebaseReducer} from "react-redux-firebase";
import {firestoreReducer} from "redux-firestore";
export const rootReducer =(history) => combineReducers({
router: connectRouter(history),
firebase: firebaseReducer,
firestore: firestoreReducer,
});
//history:履歴管理に必要なもの
//connected-react-router:reduxとつなげられる
//..>..>..>みたいなアプリ上での遷移に対応できる
// title: Consultation,
// inquiry: Consultation
/src/components/SignIn.js
import React, { useState } from 'react';
import { useFirebaseApp } from 'reactfire';
import 'firebase/auth'
import { makeStyles } from '@material-ui/core/styles';
import Paper from '@material-ui/core/Paper';
import Grid from '@material-ui/core/Grid';
import Header from './BasicComponents/Header';
import Footer from './BasicComponents/Footer';
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
import { StylesProvider } from "@material-ui/core/styles";
import styled from "styled-components";
import { useFirebase } from "react-redux-firebase";
import { useHistory } from "react-router-dom";
import { useDispatch, useSelector } from 'react-redux';
import { push } from 'connected-react-router'
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
paper: {
textAlign: 'center',
backgroundColor: '#C0C0C0',
opacity: 0.7,
borderRadius: 50,
height: 500,
paddingTop: 20,
},
grid: {
position: 'block',
margin: '0 auto',
marginTop: 50,
marginBottom: 50,
},
input:{
width: '70%',
height: 50,
fontSize: 15,
padding: '.3em',
borderRadius: 10,
border: '1px solid #aaa',
},
input1:{
width: '70%',
height: 50,
fontSize: 15,
padding: '.1em',
marginRight: 5,
borderRadius: 10,
border: '1px solid #aaa',
},
p1:{
textAlign: 'left',
paddingLeft: 80,
fontColor: 'black',
},
button1:{
backgroundColor: 'pink',
color: 'black',
width: '35%',
borderRadius:40,
marginTop: 10,
},
button2:{
backgroundColor: '#9400D3',
color: 'black',
width: '35%',
borderRadius:40,
},
}));
export default function SignUp() {
const classes = useStyles();
const auth = useSelector(state => state.auth); //global stateを呼び出すため,Dev toolをみて決めてる
const dispatch = useDispatch();
const firebase = useFirebase();
const signInWithGoogle = () => {
firebase
.login({
provider: "google",
type: "popup",
})
.then(() => {
dispatch({ type: "USE_PROFILE" });
dispatch(push('/top'));
});
};
return (
<div className={classes.root}>
<Header/>
<Grid >
<Grid item xs={5} className={classes.grid}>
<Paper className={classes.paper}>
<form>
<h1>Welcome back!</h1>
<p>Please sign in below to continue</p>
<p className={classes.p1}>Email address</p>
<input
type="text"
name="Email"
className={classes.input1}
/><br></br>
<p className={classes.p1}>Password</p>
<input
type="password"
name="password"
className={classes.input}
/><br></br>
<Button classes={{root: classes.button1,}} type="submit">
Sign in
</Button>
<p>or</p>
<Button classes={{root: classes.button2,}}
onClick={(event) => {
event.preventDefault();
signInWithGoogle();
}} >
Sign in with Gmail
</Button><br></br>
<p >Forgot Password?</p>
</form>
</Paper>
</Grid>
</Grid>
<Footer/>
</div>
);
}
I think this article can be helpful if you are working on react-redux-firebase and find this error because there are not many articles that explain how to solve this error for a react-redux-firebase app.
Error: Could not find router reducer in state tree, it must be mounted under "router"
Hope this was helpful for you!
Top comments (0)