最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Native - Redirect logged in Firebase user to Home Component - Stack Overflow

programmeradmin2浏览0评论

My goal is to redirect the user to the Home ponent if the user is already logged in. I am able to login a user and redirect them to Home only if _logInUser() is called. However, once redirected to the Home ponent, if I refresh the simulator the app goes back to the Login ponent.

I attempted to solve this using ponentWillMount() and setting let user = firebaseApp.auth().currentUser. However, I even logged the user to the console but it seems like the if check goes straight to the else statement. I would appreciate any insight!

Here is my code (I am using react-native-router-flux for routing):

index.ios.js

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

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

class AppName extends Component {
  render() {
    return (
      <Router>
        <Scene key="root">
          <Scene key="login" ponent={Login} title="Login" hideNavBar={true} initial={true}/>
          <Scene key="home" ponent={Home} title="Home"/>
        </Scene>
      </Router>
    );
  }
}


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

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 'AppName/firebase_setup';

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

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

// Removed styles for StackOverflow

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

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

  ponentWillMount() {
    let user = auth.currentUser;
    if (user != null) {
      console.log(user);
      Actions.home
    } else {
      return;
    }
  }

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

            <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) => {
        AlertIOS.alert(
          `${error.code}`,
          `${error.message}`
        );
      });
  }
}

My goal is to redirect the user to the Home ponent if the user is already logged in. I am able to login a user and redirect them to Home only if _logInUser() is called. However, once redirected to the Home ponent, if I refresh the simulator the app goes back to the Login ponent.

I attempted to solve this using ponentWillMount() and setting let user = firebaseApp.auth().currentUser. However, I even logged the user to the console but it seems like the if check goes straight to the else statement. I would appreciate any insight!

Here is my code (I am using react-native-router-flux for routing):

index.ios.js

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

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

class AppName extends Component {
  render() {
    return (
      <Router>
        <Scene key="root">
          <Scene key="login" ponent={Login} title="Login" hideNavBar={true} initial={true}/>
          <Scene key="home" ponent={Home} title="Home"/>
        </Scene>
      </Router>
    );
  }
}


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

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 'AppName/firebase_setup';

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

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

// Removed styles for StackOverflow

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

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

  ponentWillMount() {
    let user = auth.currentUser;
    if (user != null) {
      console.log(user);
      Actions.home
    } else {
      return;
    }
  }

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

            <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) => {
        AlertIOS.alert(
          `${error.code}`,
          `${error.message}`
        );
      });
  }
}
Share Improve this question edited Jul 31, 2016 at 19:05 szier asked Jul 31, 2016 at 18:34 szierszier 1,5073 gold badges19 silver badges32 bronze badges 1
  • Sorry, I don't have a plete answer for you. But, I believe the Switch Feature could be useful here. – Kyle Finley Commented Jul 31, 2016 at 19:04
Add a ment  | 

1 Answer 1

Reset to default 7

First, in your login ponent you are checking currentUser in synchronous way, but it might be not yet available at ponentWillMount. You can should get in asynchronously:

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    // User is signed in.
  } else {
    // No user is signed in.
  }
});

Most likely it will be enough to call Actions.home() if user is logged in. However, as your app grows you might want to move this logic up from Login screen. As Kyle suggested, you can use Switch feature. It is usually (to quote docs) used with redux, like this:

const RootSwitch = connect(state => ({loggedIn: state.transient.loggedIn}))(Switch);
const rootSelector = props => props.loggedIn ? 'workScreens' : 'authScreens';

const scenes = Actions.create(
   <Scene key="root" tabs={true} ponent={RootSwitch} selector={rootSelector}>
     <Scene key="authScreens" hideNavBar={true}>
       <Scene key="login" ponent={Login} initial={true}/>
       <Scene key="register" ponent={Register} />
       ...
     </Scene>
     <Scene key="workScreens">
       <Scene key="home" ponent={Home} initial={true}/>
       <Scene key="profile" ponent={ProfileMain}/>
       ...
     </Scene>
   </Scene>
);

If you don't want to use redux, you can manually wrap Switch instead of using react-redux's connect and pass loggedIn prop to Switch. For example, you can listen to firebase onAuthStateChanged in this wrapper, something like this:

class FirebaseSwitch extends Component {

  state = {
    loggenIn: false
  }

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

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

评论列表(0)

  1. 暂无评论