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}`
);
});
}
}