React Native - 将登录的 Firebase 用户重定向到 Home 组件 [英] React Native - Redirect logged in Firebase user to Home Component

查看:20
本文介绍了React Native - 将登录的 Firebase 用户重定向到 Home 组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是在用户已经登录的情况下将用户重定向到 Home 组件.只有在以下情况下我才能登录用户并将他们重定向到 Home_logInUser() 被调用.但是,一旦重定向到 Home 组件,如果我刷新模拟器,应用程序将返回到 Login 组件.

My goal is to redirect the user to the Home component 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 component, if I refresh the simulator the app goes back to the Login component.

我尝试使用 componentWillMount() 并设置 let user = firebaseApp.auth().currentUser 来解决这个问题.但是,我什至将 user 登录到控制台,但似乎 if 检查直接转到 else 语句.如有任何见解,我将不胜感激!

I attempted to solve this using componentWillMount() 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!

这是我的代码(我使用 react-native-router-flux 进行路由):

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 './components/user/login/login';
import Home from './components/user/home/home';

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


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

登录.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: ''
    }
  }

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

推荐答案

首先,在您的登录组件中,您正在以同步方式检查 currentUser,但它可能尚未在 componentWillMount 上可用.您应该可以异步进入:

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

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

如果用户已登录,很可能调用 Actions.home() 就足够了.但是,随着您的应用程序的增长,您可能希望将此逻辑从登录屏幕上移.正如凯尔建议的那样,您可以使用切换功能.它通常(引用文档)与 redux 一起使用,如下所示:

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} component={RootSwitch} selector={rootSelector}>
     <Scene key="authScreens" hideNavBar={true}>
       <Scene key="login" component={Login} initial={true}/>
       <Scene key="register" component={Register} />
       ...
     </Scene>
     <Scene key="workScreens">
       <Scene key="home" component={Home} initial={true}/>
       <Scene key="profile" component={ProfileMain}/>
       ...
     </Scene>
   </Scene>
);

如果你不想使用redux,你可以手动包装Switch,而不是使用react-redux的connect,并将loggedIn prop传递给Switch.例如,您可以在此包装器中监听 firebase onAuthStateChanged,如下所示:

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
  }

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

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

这篇关于React Native - 将登录的 Firebase 用户重定向到 Home 组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆