7
\$\begingroup\$

I am using react-native-router-flux to organize the routes for my application. Using Firebase, I am able to call onAuthStateChanged() in the componentWillMount function to determine whether or not a user is logged in. If a user is logged in, the state: loggedIn is set to true and the appScenes routes are loaded. Likewise, if a user is not logged in loggedIn is set to false and the authScenes are loaded.

The major downside to this is that I had to create a component called FirebaseSwitch that has identical code. However, if I simply remove component={FirebaseSwitch} from the root <Scene />, the user does not get redirected to the Home component when _logInUser() is called.

Any suggestions as to how I can make this better? My code is below. Thanks in advance!

index.ios.js

import React, { Component } from 'react';
import { Scene, Router } from 'react-native-router-flux';
import {
  AppRegistry,
  StyleSheet
} from 'react-native';

import firebaseApp from './firebase_setup';

// Components
import Login from './components/user/login/login';
import Home from './components/user/home/home';

// Switching scene type
import FirebaseSwitch from './firebase_switch';

const styles = StyleSheet.create({
  navBarDefault: {
    backgroundColor: "#35A7FF",
  }
});

class TextbookSwap extends Component {
  state = {
    loggedIn: false
  }

  componentWillMount() {
    firebaseApp.auth().onAuthStateChanged((user) => 
      this.setState({ loggedIn: !!user })
    );
  }


  render() {
    const rootSelector = () => this.state.loggedIn ? 'appScenes' : 'authScenes';
    return (
      <Router>
        <Scene key="root" tabs={true} selector={rootSelector}>
          <Scene key="authScenes" hideNavBar={true}>
            <Scene key="login" component={Login} initial={true}/>
          </Scene>
          <Scene key="appScenes" hideNavBar={false} navigationBarStyle={styles.navBarDefault} titleStyle={{ color: "white" }}>
            <Scene key="home" component={Home} title="TextbookSwap" />
          </Scene>
        </Scene>
      </Router>
    );
  }
}


AppRegistry.registerComponent('TextbookSwap', () => TextbookSwap);

firebase_switch.js

import React, { Component } from 'react';
import { Switch } from 'react-native-router-flux';

import firebaseApp from './firebase_setup';

export default class FirebaseSwitch extends Component {
  state = {
    loggedIn: false
  }

  componentWillMount() {
    firebaseApp.auth().onAuthStateChanged((user) => 
      this.setState({ loggedIn: !user })
    );
  }

  render() {
    return(
      <Switch loggedIn={this.state.loggedIn} {...this.props} />
    );
  }
}

login.js

import React, { Component } from 'react';
import {
  AlertIOS,
  Dimensions,
  Image,
  ScrollView,
  StyleSheet,
  Text,
  TextInput,
  TouchableOpacity,
  View
} from 'react-native';

import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import { Actions } from 'react-native-router-flux';

import firebaseApp from 'TextbookSwap/firebase_setup';

// Set width and height to screen dimensions
const { width, height } = Dimensions.get("window"); 

// For Firebase Auth
const auth = firebaseApp.auth();

// Styles removed for codereview

export default class Login extends Component {
  constructor(props) {
    super(props);

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

  componentDidMount() {
    let user = auth.currentUser;
    if (user) {
      console.log(msg)
      Actions.home
    } else {
      return;
    }
  }

  render() {
    return (
      <View style={styles.mainContainer}>
        <KeyboardAwareScrollView 
          style={styles.scrollView}
          keyboardShouldPersistTaps={false}
          automaticallyAdjustContentInsets={true}
          alwaysBonceVertical={false}
        >
          <View style={styles.loginContainer}>

            <Image 
              source={require('TextbookSwap/assets/textbook.png')}
              style={styles.loginImage} 
            />

            <Text style={styles.headerText}>SCU TextbookSwap</Text>

            <View style={styles.inputContainer}>

              <TextInput
                style={styles.formInput}
                placeholder="Email"
                keyboardType="email-address"
                autoFocus={true}
                autoCorrect={false}
                autoCapitalize="none"
                onChangeText={(email) => this.setState({email})}
              />

              <TextInput
                style={styles.formInput}
                secureTextEntry={true}
                placeholder="Password"
                autoCorrect={false}
                autoCapitalize="none"
                onChangeText={(password) => this.setState({password})}
              />

              <TouchableOpacity 
                style={styles.loginButton}
                onPress={this._logInUser.bind(this)}
              >
                <Text style={styles.loginButtonText}>Log In</Text>
              </TouchableOpacity>

              <TouchableOpacity>
                <Text style={styles.toSignupButton}>Dont have an account? Create one!</Text>
              </TouchableOpacity>

            </View>
          </View>

          <View style={styles.footer}>
            <Text style={styles.footerText}>
              By signing up, I agree to TextbookSwap's <Text style={styles.footerActionText}>Terms of Service</Text> and <Text style={styles.footerActionText}>Privacy Policy</Text>.
            </Text>
          </View>
        </KeyboardAwareScrollView>
      </View>
    );
  }

  _logInUser() {
    let email = this.state.email;
    let password = this.state.password;

    auth.signInWithEmailAndPassword(email, password)
      .then(Actions.home)
      .catch((error) => {
        switch(error.code) {
          case "auth/wrong-password":
            AlertIOS.alert('Uh oh!', 'Invalid password! Please try again.');
          break;

          case "auth/invalid-email":
            AlertIOS.alert('Uh oh!', 'Invalid email! Please try again.'); 
          break;

          case "auth/user-not-found":
            AlertIOS.alert('Uh oh!', 'Please check your credentials and try again');
          break;
        }
      });
  }
}

home.js

import React, { Component } from 'react';
import { Actions } from 'react-native-router-flux';
import {
  AlertIOS,
  Dimensions,
  StyleSheet,
  Text,
  TouchableOpacity,
  View
} from 'react-native';

import firebaseApp from 'TextbookSwap/firebase_setup';

const { width, height } = Dimensions.get("window"); 
const auth = firebaseApp.auth();

// Styles removed for codereview

export default class Home extends Component {
  render() {
    let user = auth.currentUser;

    return (
      <View> 
        <View style={styles.homeContainer}>
          <TouchableOpacity style={styles.logOutButton} onPress={this._signUserOut}>
            <Text style={styles.logOutButtonText}>Log out: {user.email}</Text>
          </TouchableOpacity>
        </View>
      </View>
    );


  }
  _signUserOut() {
    auth.signOut().then(() => {
      console.log("User signed out"); 
      Actions.login
    }, (error) => {
      AlertIOS.alert(
        `${error.code}`,
        `${error.message}`
      );
    });
  }
}
\$\endgroup\$

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.