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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.