mufc
mufc

Reputation: 715

React Native firebase Authentication handling

I am trying to create a simple Auth flow in my Expo application.

I've reacreated my project here so you can see what I am doing

Right now what happens in my app is I can register a user using Firebase authtentication, but can't navigate to the authenticated flows. Nothing happens after I click register, but I can see the user in firebase.

I have been reading the React Navigaion docs and tried implementing something similar to what they do for the Auth flow there, but have not had any success.

I think the issue has to do with how I am getting the token in App.js and my use of useEffect

App.js

import React, { useEffect } from 'react';
import * as eva from '@eva-design/eva';
import { Provider as AuthProvider } from './src/context/AuthContext';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { createStackNavigator } from '@react-navigation/stack';
import { ApplicationProvider } from '@ui-kitten/components';
import { NavigationContainer } from '@react-navigation/native';
import LandingScreen from './src/screens/LandingScreen';
import RegisterScreen from './src/screens/RegisterScreen';
import LoginScreen from './src/screens/LoginScreen';
import HomeScreen from './src/screens/HomeScreen';
import DetailScreen from './src/screens/DetailScreen';

const Drawer = createDrawerNavigator();
const Stack = createStackNavigator();

/*eslint-disable */
export default function App() {
  let token;
  useEffect(() => {
    // Fetch the token from storage then navigate to our appropriate place
    const localSignin = async () => {
      try {
        token = await AsyncStorage.getItem('userToken');
      } catch (e) {
        // Restoring token failed
      }
    };
    console.log(token);
    localSignin();
  }, []);

  return (
    <ApplicationProvider {...eva} theme={eva.light}>
      <AuthProvider>
        <NavigationContainer>
          {token ? (
            <>
              <Drawer.Navigator initialRouteName="Home">
                <Drawer.Screen name="Home" component={HomeScreen} />
                <Drawer.Screen name="Details" component={DetailScreen} />
              </Drawer.Navigator>
            </>
          ) : (
            <>
              <Stack.Navigator>
                <Stack.Screen name="Landing" component={LandingScreen} />
                <Stack.Screen name="Register" component={RegisterScreen} />
                <Stack.Screen name="Login" component={LoginScreen} />
              </Stack.Navigator>
            </>
          )}
        </NavigationContainer>
      </AuthProvider>
    </ApplicationProvider>
  );
}

Should I be using my AuthContext here somewhere? I am very new to react development so I am sorry if this is somewhat unclear.

Upvotes: 2

Views: 162

Answers (1)

Rander Gabriel
Rander Gabriel

Reputation: 647

Your "token" is manipulated asynchronously, so it should be a state variable so your component may re-render when it got changed. To achieve that, you should replace your token declaration with

const [token, setToken] = React.useState(undefined);

After that, when you want to change your token, instead of reassigning to the token variable, call setToken with the desired value. Like this:

setToken(await AsyncStorage.getItem('userToken'));

The final code should look like this

import React, { useEffect } from 'react';
import * as eva from '@eva-design/eva';
import { Provider as AuthProvider } from './src/context/AuthContext';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { createStackNavigator } from '@react-navigation/stack';
import { ApplicationProvider } from '@ui-kitten/components';
import { NavigationContainer } from '@react-navigation/native';
import LandingScreen from './src/screens/LandingScreen';
import RegisterScreen from './src/screens/RegisterScreen';
import LoginScreen from './src/screens/LoginScreen';
import HomeScreen from './src/screens/HomeScreen';
import DetailScreen from './src/screens/DetailScreen';

const Drawer = createDrawerNavigator();
const Stack = createStackNavigator();

/*eslint-disable */
export default function App() {
  const [token, setToken] = React.useState(undefined);
  useEffect(() => {
    // Fetch the token from storage then navigate to our appropriate place
    const localSignin = async () => {
      try {
        setToken(await AsyncStorage.getItem('userToken'));
      } catch (e) {
        // Restoring token failed
      }
    };
    console.log(token);
    localSignin();
  }, []);

  return (
    <ApplicationProvider {...eva} theme={eva.light}>
      <AuthProvider>
        <NavigationContainer>
          {token ? (
            <>
              <Drawer.Navigator initialRouteName="Home">
                <Drawer.Screen name="Home" component={HomeScreen} />
                <Drawer.Screen name="Details" component={DetailScreen} />
              </Drawer.Navigator>
            </>
          ) : (
            <>
              <Stack.Navigator>
                <Stack.Screen name="Landing" component={LandingScreen} />
                <Stack.Screen name="Register" component={RegisterScreen} />
                <Stack.Screen name="Login" component={LoginScreen} />
              </Stack.Navigator>
            </>
          )}
        </NavigationContainer>
      </AuthProvider>
    </ApplicationProvider>
  );
}

Upvotes: 1

Related Questions