0
votes

I am using redux with react native and react navigation. Everything works fine when I login but when i logout, it doesn't redirect me back to login screen. The application flow for backend is: Get token from google > send to nodejs server to verify with same client id > create new or get existing user > sign the userid with JWT > send back the new token. Here's my code

Authnavigator.js

...

import {AuthScreens, DashboardScreens} from './AppNavigator';

// redux
import {useSelector} from 'react-redux';

const AuthNavigator = () => {
  const userGoogleLogin = useSelector(state => state.userGoogleLogin);
  const {loading, userInfo} = userGoogleLogin;

  return (
    <NavigationContainer>
      {userInfo && <DashboardScreens />}
      {!userInfo && <AuthScreens />}
    </NavigationContainer>
  );
};

export default AuthNavigator;

userAction.js

import axios from 'axios';
import {
  GOOGLE_USER_LOGIN_REQUEST,
  GOOGLE_USER_LOGIN_SUCCESS,
  GOOGLE_USER_LOGIN_FAIL,
  GOOGLE_USER_LOGOUT,
} from '../constants/userConstants';

import {GoogleSignin} from '@react-native-google-signin/google-signin';

export const googleLogin = idToken => async dispatch => {
  try {
    // request action
    dispatch({type: GOOGLE_USER_LOGIN_REQUEST});

    // set content type
    const config = {
      headers: {
        'Content-Type': 'application/json',
      },
    };

    // send post request
    const {data} = await axios.post(
      `https://still-eyrie-92675.herokuapp.com/api/auth/google`,
      {
        token: idToken,
      },
    );

    // send back user data
    dispatch({
      type: GOOGLE_USER_LOGIN_SUCCESS,
      payload: data,
    });
  } catch (error) {
    dispatch({
      type: GOOGLE_USER_LOGIN_FAIL,
      payload: error,
    });
  }
};

export const googleLogout = () => async dispatch => {
  await GoogleSignin.revokeAccess();
  await GoogleSignin.signOut();
  dispatch({type: GOOGLE_USER_LOGOUT});
};


userReducer.js

import {
  GOOGLE_USER_LOGIN_REQUEST,
  GOOGLE_USER_LOGIN_SUCCESS,
  GOOGLE_USER_LOGIN_FAIL,
  GOOGLE_USER_LOGOUT,
} from '../constants/userConstants';

export const userGoogleLoginReducer = (state = {}, action) => {
  switch (action.type) {
    case GOOGLE_USER_LOGIN_REQUEST:
      return {loading: true};
    case GOOGLE_USER_LOGIN_SUCCESS:
      return {loading: false, userInfo: action.payload};
    case GOOGLE_USER_LOGIN_FAIL:
      return {loading: false, error: action.payload};
    case GOOGLE_USER_LOGOUT:
      return {};
    default:
      return state;
  }
};

Dashboard.js

...
// redux
import {useDispatch, useSelector} from 'react-redux';
import {googleLogout} from '../actions/userAction';

export default function Dashboard({navigation}) {
  const dispatch = useDispatch();

  const userGoogleLogin = useSelector(state => state.userGoogleLogin);
  const {loading, error, userInfo} = userGoogleLogin;

  return (
    <Background>
      <Logo />
      <Header>Let’s start</Header>
      <Paragraph>
        Your amazing app starts here. Open you favorite code editor and start
        editing this project.
      </Paragraph>
      <Button mode="outlined" onPress={() => dispatch(googleLogout())}>
        Logout
      </Button>
    </Background>
  );
}
3

3 Answers

0
votes

Error seems to be in your reducer file when you are logged out reset your value of userInfo

case GOOGLE_USER_LOGOUT:
  return {userInfo: null, loading: false};

because why it is happening that your userInfo value didn't reseted and your {userInfo && } condition is true

and I have one more suggestion that is to use ternary operator like this it looks more readable

{userInfo ? <DashboardScreens />: <AuthScreens />}
0
votes

The issue was with my navigator and it had nothing to do with redux. Solved it.

0
votes

Have a try with the below code

const AuthNavigator = () => {
  const {loading, userInfo} = useSelector(state => state.userGoogleLogin);

  return (
    <NavigationContainer>
      {userInfo && <DashboardScreens />}
      {!userInfo && <AuthScreens />}
    </NavigationContainer>
  );
};

Hope your issue will resolved.