0

I'm using Firebase for user authentication and I want to use the onAuthStateChanged() to make a user persist even after refreshing the browser. I'm also using redux-sagas to handle async operations.

Index.jsx file:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import './index.css';
import './App.scss';
import store from './store';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'));
serviceWorker.unregister();

App.jsx:

import React, { Component } from 'react';
import { Route, BrowserRouter as Router, Switch } from 'react-router-dom';
import { connect } from 'react-redux';
import Navbar from './components/navbar';
import routes from './routes';
import { actionTypes } from './components/signin/actionTypes';

const { VERIFY_REQUEST } = actionTypes;

const mapDispatchToProps = {
    VERIFY_REQUEST,
};

class App extends Component {

    render() {
        return (
            <Router>
                <Navbar />
                <Switch>
                    {routes.map(route => (
                        <Route
                            key={route.path}
                            path={route.path}
                            exact={route.exact}
                            component={route.component}
                        />
                    ))}
                </Switch>
            </Router>
        );
    }
}

export default connect(null, mapDispatchToProps)(App);

My sagas generator function binded to the action type:

function onAuthState() {
    return new Promise((resolve, reject) => {
        loginToFirebase.auth().onAuthStateChanged(user => {
            if (user) {
                console.log(user);
                resolve(user);
            } else {
                reject(new Error('Ops!'));
            }
        });
    });
}

function* verifyUserAuth() {
    try {
        const LOGIN_API_URL = process.env.REACT_APP_USER_AUTH_API;
        const { user } = yield onAuthState();
        console.log(user);
        const userInfo = { userAuth: user, userType: 'user' };
        const config = { headers: { 'Content-Type': 'application/json' } };
        const body = JSON.stringify(userInfo);
        const response = yield axios.post(LOGIN_API_URL, body, config);
        if (response.status === 200) {
            const { data: { info } } = response.data;
            yield put({ payload: info, type: VERIFY_SUCCESS });
        } else yield put(loginError(response.status));
    } catch (error) {
        yield put(loginError(error));
    }
}

export default function* watchUserLoginAction() {
    yield takeEvery(VERIFY_REQUEST, verifyUserAuth);
}

Everytime I check my redux tools, I don't see the action being fired on component mount.

Edward Bella
  • 129
  • 8
  • Have you tried using [componentDidMount()](https://reactjs.org/docs/react-component.html#componentdidmount)? its invoked immediately after a component is mounted (inserted into the tree). Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request. – Tomer Dec 17 '19 at 12:30

1 Answers1

1

You can use the componentDidMount lifecycle method whenever you want to do something after the component is mounted. Modify your mapDispatchToProps

const mapDispatchToProps = dispatch => {
         return {
            verifyRequest: () => { dispatch( {type : VERIFY_REQUEST} ) }
          };
    };

and then call verifyRequest from componentDidMount

componentDidMount = () =>{
     this.props.verifyRequest()
}

Also, it is better to create action creators instead of directly dispatching the action, like so

export const verifyRequestAction = () => {
    return {
        type: VERIFY_REQUEST
    }
}

and then

const mapDispatchToProps = dispatch => {
         return {
            verifyRequest: () => { dispatch(verifyRequestAction()}
          };
    };
Amruta
  • 163
  • 1
  • 13