Search code examples
firebasereact-nativereact-reduxredux-thunk

Why are my redux actions not firing correctly?


I am trying to implement a check for authentication and to login/logout users using redux and firebase. I have the following code:
Action Types:

export const LOGIN_REQ = 'AUTH_REQ';
export const LOGOUT_REQ = 'LOGOUT_REQ';
export const AUTH_SUCCESS = 'AUTH_SUCCESS';
export const AUTH_FAILED = 'AUTH_FAILED';
export const GET_AUTH = 'GET_AUTH';

Reducers:

import * as ActionTypes from './ActionTypes';
export const auth = (state = {
    isAuth: false,
    user: null
}, action) => {
    switch (action.type) {
        case ActionTypes.LOGIN_REQ:
            return { ...state, isAuth: false, user: null };
        case ActionTypes.LOGOUT_REQ:
            return { ...state, isAuth: false, user: null };
        case ActionTypes.AUTH_FAILED:
            return { ...state, isAuth: false, user: null };
        case ActionTypes.AUTH_SUCCESS:
            return { ...state, isAuth: true, user: action.payload };
        case ActionTypes.GET_AUTH:
            return state;
        default:
            return state;
    }
}

Thunks:

export const getAuth = () => (dispatch) => {
    firebase.auth().onAuthStateChanged((user) => {
        if (user) {
            console.log('Get AUTH called');
            dispatch(authSuccess());
        }
        else {
            console.log('Get AUTH called');
            dispatch(authFailed());
        }
    });
}

export const loginReq = (email, password, remember) => (dispatch) => {
    firebase.auth().signInWithEmailAndPassword(email, password)
        .then((cred) => {
            if (remember === false) {
                firebase.auth().setPersistence(firebase.auth.Auth.Persistence.NONE);
                console.log('Logged In with Redux without persist');
            }
            else {
                console.log('Logging in with Persist');
            }
            console.log('Dispatching Success !');
            dispatch(authSuccess(cred.user.uid));
        })
        .catch((err) => {
            console.log(err);
            dispatch(authFailed(err));
        });
}

export const logoutReq = () => (dispatch) => {
    firebase.auth().signOut()
        .then(() => dispatch(getAuth()))
        .catch((err) => console.log(err));
}

export const authSuccess = (uid = null) => ({
    type: ActionTypes.AUTH_SUCCESS,
    payload: uid
});

export const authFailed = (resp) => ({
    type: ActionTypes.AUTH_FAILED,
    payload: resp
});

And I am calling it from a component as shown below:

const mapStateToProps = state => {
    return {
        isAuth: state.isAuth,
        user: state.user
    }
}

const mapDispatchToProps = dispatch => ({
    getAuth: () => { dispatch(getAuth()) },
    loginReq: (email, password, remember) => { dispatch(loginReq(email, password, remember)) },
    logoutReq: () => { dispatch(logoutReq()) }
})  
handleLogin() {
       this.props.loginReq(this.state.email, this.state.password, this.state.remember);
  }
handleLogOut() {
        this.props.logoutReq();
    }
<BUTTON onClick=()=>this.handleLogOut()/handleLogin()>

I am close to tears because I cannot figure out why my loginReq fires one or many gitAuth() methods even when i click on the button once. This happens only for the loginReq() action. I have not specified anywhere that loginReq() should fire it. Also i have called the getAuth() method in the component did mount method of my main screen which checks authentication status once at the start of the app.
EDIT: I have console logged in the component did mount method in the main component so I know that this getAuth() call is not coming from there.


Solution

  • Imo the answer is badly done, try to reestructure it better, what you call "Thunks" are actually "Actions". But if I were to tell you something that could help is that maybe the problem lies in the thunk middleware config or with the way firebase is beign treated by the dispatcher, so I would say that you better try coding an apporach with the react-redux-firebase library (this one: http://react-redux-firebase.com/docs/getting_started ) it makes easier to connect redux with a firebase back end. Other great reference, the one that I learned with, is The Net Ninja's tutorial playlist about react, redux and firebase.