Search code examples
react-nativefirebase-authenticationreact-navigationreact-navigation-stack

How to jump another page after login/sign up


I build navigation with react-navigation v3 and auth with firebase. No problem with that. Navigation flow is works and I can sign up. The problem I am facing is, when I push the Sign up button it doesn't jump to Signup Screen.

So the structure that Build: in App.js I am doing navigation part. First sending Welcome Screen which include Login.

This is Welcome Screen:

import React, { Component } from 'react'
import {StyleSheet, View } from "react-native";
import {Container, Text, Form, Content, Header, Button, Input, Label, Item} from 'native-base';
import SignUp from '../screens/register/SignUp'
import * as firebase from 'firebase';

const firebaseConfig = {
    apiKey: "example example",
    authDomain: "example example",
    databaseURL: "example example",
    projectId: "example example",
    storageBucket: "example example",
};
firebase.initializeApp(firebaseConfig);


export default class WelcomeScreen extends Component {
    constructor(props){
        super(props)

        this.state = ({
            email: '',
            password: ''
        })
    }

    loginUser = (email, password, navigate) => {
        try {
            firebase.auth().signInWithEmailAndPassword(email,password).then(function(user){
                console.log(user);
                navigate('Learn')
            })
        }
        catch (error) {
            console.log(error.toString())
        }
    };

    render() {
        return (
            <Container style={styles.container}>
                <Form>
                    <Item floatingLabel>
                        <Label>E-mail</Label>
                        <Input
                            autocorrect={false}
                            autoCapitalize={'none'}
                            onChangeText={(email) => this.setState({email})}
                        />
                    </Item>
                    <Item floatingLabel>
                        <Label>Password</Label>
                        <Input
                            secureTextEntry={true}
                            autocorrect={false}
                            autoCapitalize={'none'}
                            onChangeText={(password)=>this.setState({password})}
                        />
                    </Item>
                </Form>
                <Button style={{backgroundColor:'#6c5ce7', marginTop: 10}}
                    onPress={()=>this.loginUser(this.state.email,this.state.password)}
                    rounded
                    success
                >
                    <Text>Kelimeda'ya Uç</Text>
                </Button>
                <Button style={{backgroundColor:'#6c5ce7', marginTop: 10}}
                    onPress={()=>this.props.navigation.navigate('SignUp')}
                    rounded
                    primary
                >
                    <Text>Beni Kaydet!</Text>
                </Button>
            </Container>
        );
    }
}

Sign Up Screen:

import React, { Component } from 'react'
import {StyleSheet, View } from "react-native";
import {Container, Text, Form, Content, Header, Button, Input, Label, Item} from 'native-base';
import * as firebase from 'firebase';



export default class WelcomeScreen extends Component {
    constructor(props){
        super(props)

        this.state = ({
            email: '',
            password: ''
        })
    }

    signUpUser = (email, password) => {
        try {
            if(this.state.password.length < 6){
                alert('Lutfen 6 dan daha uzun bir karakter giriniz.')
                return
            }
            firebase.auth().createUserWithEmailAndPassword(email,password)
        }
        catch (error) {
            console.log(error.toString())
        }
    };

    render() {
        return (
            <Container style={styles.container}>
                <Form>
                    <Item floatingLabel>
                        <Label>E-mail</Label>
                        <Input
                            autocorrect={false}
                            autoCapitalize={'none'}
                            onChangeText={(email) => this.setState({email})}
                        />
                    </Item>
                    <Item floatingLabel>
                        <Label>Password</Label>
                        <Input
                            secureTextEntry={true}
                            autocorrect={false}
                            autoCapitalize={'none'}
                            onChangeText={(password)=>this.setState({password})}
                        />
                    </Item>
                </Form>
                <Button style={{backgroundColor:'#6c5ce7', marginTop: 10}}
                        onPress={()=>this.signUpUser(this.state.email,this.state.password)}
                        rounded
                        primary
                >
                    <Text>Beni Kaydet!</Text>
                </Button>
            </Container>
        );
    }
}


const styles = StyleSheet.create({
    container: {
        flex: 1,
        padding: 5,
        justifyContent: 'center',
        backgroundColor: '#fff',
    },
}); 

and this is the App Screen. Do I need to check here user Logged in or Not? or Welcome Screen?

//imports...

import React, { Component } from 'react';
import {View, StatusBar} from 'react-native';
import {
  createSwitchNavigator,
  createAppContainer,
  createDrawerNavigator,
  createBottomTabNavigator,
  createStackNavigator,} from 'react-navigation';
import Icon from 'react-native-vector-icons/Ionicons';
import WelcomeScreen from './src/screens/Welcome';
import Learn from './src/screens/Tab/Learn';
import Settings from './src/screens/Tab/Settings';
import Play from './src/screens/Tab/Play';


//content: const & functions and styles...

const DashboardTabNavigator = createBottomTabNavigator({
  Play,
  Learn,
  Settings
},
{
  navigationOptions: ({navigation}) => {
    const {routeName} = navigation.state.routes
        [navigation.state.index];
    return {
      headerTitle: routeName,
      headerTintColor:'#fff',
      headerStyle:{
        backgroundColor: '#2c3e50',
      }
    };
  }
});

const DashStack = createStackNavigator({
  DashboardTabNavigator: DashboardTabNavigator
}, {
  defaultNavigationOptions:({navigation}) =>{
    return {
      headerLeft: <Icon
          style={{paddingLeft: 15, color:'#fff'}}
          onPress={()=>navigation.openDrawer()}
          name={'md-menu'}
          size={30}
          />
    }
  },
});

const appDrawNavigator = createDrawerNavigator({
  Dashboard:{ screen: DashStack }
});

const appSwitchNavigation = createSwitchNavigator({
  Welcome:{ screen: WelcomeScreen },
  Dashboard:{ screen: appDrawNavigator }
});

const AppContainer = createAppContainer(appSwitchNavigation);


class App extends Component {
  render() {
    return(
        <View style={{flex: 1}}>
          <StatusBar
            backgroundColor="blue"
            barStyle="light-content"
         />
          <AppContainer/>
          </View>

    ) ;
  }
}
export default App;

Solution

  • Solution for problem 1: You have not passed navigate to your loginUser function, so it is not working. Please send the navigate param to the loginUser like this.

    <Button
       style={{backgroundColor:'#6c5ce7', marginTop: 10}}
       onPress={()=>this.loginUser(this.state.email,this.state.password, this.props.navigation.navigate)}
       rounded
       success>
    

    Solution for problem 2: For the firebase duplication issue, its because you are initialising the firebase instance twice in the application. What you should do instead is, just initialize the firebase at the application root component like App.js or Splash screen, so that it can be available throughout the app lifecycle and whenever you need to use it just import it and use.

    Solution for problem 3: Its a common usecase as to know the logged in status of the user upfront to navigate the user appropriately into the application. For this, what you can do is, just save a flag in AsyncStorage for eg. isLoggedIn as YES upon successful login, and post this, whenever the app is opened just analyse with the flag's presence/value wether the user is logged in or not. A good place to do this is either your app's Splashscreen component or the root component of the application.

    Edited Answer (additional): (for problem 1)

    You have your navigation routes nested wrongly to directly jump to Learn from welcome screen, to navigate from one screen to another, the two screen should be in same navigation scope (if navigator is given as a route in another navigator then the route navigator is considered as a screen and the user will be navigated to its initial route when navigated to it)

    Your code should target navigating to Dashboard route, which will internally render the nested navigators i.e. the first/initial route but with current nesting this will land you to Play so what can be done is, make Learn as first/initial route of your tab navigator.

    The code in the loginUser should be navigate('Dashboard') and your tab navigator should have Learn as its initial route.