connect App to firebase auth; display splash screen while loading auth state

This commit is contained in:
Ruidy Nemausat 2020-05-13 17:57:24 +02:00
parent 66541bd0e7
commit 2b1bd46268
7 changed files with 77 additions and 49 deletions

View file

@ -4,11 +4,12 @@ import {BrowserRouter} from 'react-router-dom';
import Router from './router/Router'; import Router from './router/Router';
import NavBar from './components/NavBar'; import NavBar from './components/NavBar';
// Redux // Redux
import {Provider} from 'react-redux'; import {Provider, useSelector} from 'react-redux';
import store from './store'; import store from './store';
// Firebase // Firebase
import {ReactReduxFirebaseProvider} from 'react-redux-firebase'; import {ReactReduxFirebaseProvider, isLoaded} from 'react-redux-firebase';
import rrfProps from './store/firebase'; import rrfProps from './store/firebase/config';
import {selectAuthState} from './store/firebase';
/** /**
* Main App container * Main App container
@ -20,12 +21,28 @@ const App: FC = () => {
<Provider store={store}> <Provider store={store}>
<ReactReduxFirebaseProvider {...rrfProps}> <ReactReduxFirebaseProvider {...rrfProps}>
<BrowserRouter> <BrowserRouter>
<NavBar /> <AuthApp />
<Router />
</BrowserRouter> </BrowserRouter>
</ReactReduxFirebaseProvider> </ReactReduxFirebaseProvider>
</Provider> </Provider>
); );
}; };
/**
* Display a loading screen while fetching authentication state
*/
const AuthApp: FC = () => {
const auth = useSelector(selectAuthState);
if (!isLoaded(auth)) {
// TODO: insert Splash Screen here
return <div>Loading...</div>;
}
return (
<>
<NavBar />
<Router />
</>
);
};
export default App; export default App;

View file

@ -3,20 +3,20 @@ import React, {FC} from 'react';
import {Link} from 'react-router-dom'; import {Link} from 'react-router-dom';
import * as ROUTES from '../constants/routes'; import * as ROUTES from '../constants/routes';
//Redux //Redux
import {connect} from 'react-redux'; // import {connect} from 'react-redux';
import {selectAuthState} from '../store/auth'; // import {selectAuthState} from '../store/auth';
// Style // Style
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {faCode, faSignOutAlt, faUser} from '@fortawesome/free-solid-svg-icons'; import {faCode, faSignOutAlt, faUser} from '@fortawesome/free-solid-svg-icons';
interface IProps { interface IProps {
isAuthenticated: boolean; isAuthenticated?: boolean;
loading: boolean; loading?: boolean;
} }
/** /**
* Main Navbar serves navigation routes. * Main Navbar serves navigation routes.
*/ */
const NavBar: FC<IProps> = ({isAuthenticated, loading}) => { const NavBar: FC<IProps> = ({isAuthenticated = true, loading = false}) => {
const publicLinks = ( const publicLinks = (
<ul data-testid="publicLinks"> <ul data-testid="publicLinks">
<li> <li>
@ -80,4 +80,5 @@ const NavBar: FC<IProps> = ({isAuthenticated, loading}) => {
}; };
/** connect HOC subscribes to the store */ /** connect HOC subscribes to the store */
export default connect(selectAuthState)(NavBar); export default NavBar;
//connect(selectAuthState)(NavBar);

View file

@ -0,0 +1,19 @@
//Firebase
import firebase from 'firebase/app';
import 'firebase/auth';
const CONFIG = {
apiKey: process.env.REACT_APP_API_KEY,
authDomain: process.env.REACT_APP_AUTH_DOMAIN,
databaseURL: process.env.REACT_APP_DB_URL,
projectId: process.env.REACT_APP_PROJECT_ID,
storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_MSG_SENDER_ID,
appId: process.env.REACT_APP_APP_ID,
measurementId: process.env.REACT_APP_MEASUREMENT_ID,
};
// initialize firebase
firebase.initializeApp(CONFIG);
export default firebase;

View file

@ -1,6 +1,5 @@
// Redux // Redux
import {createSlice} from '@reduxjs/toolkit'; import {createSlice} from '@reduxjs/toolkit';
import {RootState} from '..';
// Typing // Typing
import User from '../../models/User'; import User from '../../models/User';
@ -28,10 +27,10 @@ const authSlice = createSlice({
export const {} = authSlice.actions; export const {} = authSlice.actions;
// export selectors // export selectors
export const selectAuthState = (state: RootState) => { // export const selectAuthState = (state: RootState) => {
const {isAuthenticated, loading} = state.auth; // const {isAuthenticated, loading} = state.auth;
return {isAuthenticated, loading}; // return {isAuthenticated, loading};
}; // };
// export reducer // export reducer
export default authSlice.reducer; export default authSlice.reducer;

View file

@ -0,0 +1,17 @@
// Redux
import store from '..';
// Firebase
import firebase from '../../services/firebase';
// react-redux-firebase config
const RRF_CONFIG = {
// userProfile: 'users'
};
// object required by RRFProvider
const rrfProps = {
firebase,
config: RRF_CONFIG,
dispatch: store.dispatch,
};
export default rrfProps;

View file

@ -1,32 +1,4 @@
//Firebase import {RootState} from '..';
import firebase from 'firebase/app';
import 'firebase/auth';
// Redux
import store from '..';
const CONFIG = { /** export firebase authentication */
apiKey: process.env.REACT_APP_API_KEY, export const selectAuthState = (state: RootState) => state.firebase.auth;
authDomain: process.env.REACT_APP_AUTH_DOMAIN,
databaseURL: process.env.REACT_APP_DB_URL,
projectId: process.env.REACT_APP_PROJECT_ID,
storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_MSG_SENDER_ID,
appId: process.env.REACT_APP_APP_ID,
measurementId: process.env.REACT_APP_MEASUREMENT_ID,
};
// initialize firebase
firebase.initializeApp(CONFIG);
// react-redux-firebase config
const RRF_CONFIG = {
// userProfile: 'users'
};
// object required by RRFProvider
const rrfProps = {
firebase,
config: RRF_CONFIG,
dispatch: store.dispatch,
};
export default rrfProps;

View file

@ -2,7 +2,7 @@
import {configureStore} from '@reduxjs/toolkit'; import {configureStore} from '@reduxjs/toolkit';
import authReducer from './auth/'; import authReducer from './auth/';
// Firebase // Firebase
import {firebaseReducer} from 'react-redux-firebase'; import {firebaseReducer, FirebaseReducer} from 'react-redux-firebase';
const store = configureStore({ const store = configureStore({
reducer: { reducer: {
@ -12,6 +12,9 @@ const store = configureStore({
}); });
// State type // State type
export type RootState = ReturnType<typeof store.getState>; export interface RootState {
firebase: FirebaseReducer.Reducer;
}
// export type RootState = ReturnType<typeof store.getState>;
export default store; export default store;