7

我的目標是在用戶已登錄的情況下將用戶重定向到Home組件。我只能在調用_logInUser()時才能登錄用戶並將其重定向到Home 。但是,一旦重定向到Home組件,如果我刷新模擬器,應用程序將返回到Login組件。React Native - 將登錄的Firebase用戶重定向到家庭組件

我試圖用componentWillMount()let user = firebaseApp.auth().currentUser來解決這個問題。但是,我甚至將user登錄到控制檯,但似乎if檢查直接轉到else聲明。我將不勝感激任何見解!

這裏是我的代碼(我用react-native-router-flux路由):

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

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: '' 
    } 
    } 

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

對不起,我沒有一個完整的答案給你。但是,我相信[Switch Feature](https://github.com/aksonov/react-native-router-flux/blob/master/docs/OTHER_INFO.md#switch-new-feature)在這裏很有用。 –

回答

5

首先,在您正在以同步方式檢查currentUser的登錄組件,但它可能還沒有用能夠在componentWillMount。你可以得到應該在異步:

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

最有可能將是足以稱之爲Actions.home()如果用戶登錄然而,隨着應用的增長,你可能想從登錄屏幕上移至此邏輯。正如Kyle所建議的那樣,您可以使用Switch功能。它通常是(以引用文檔)與終極版中使用,如:

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

如果你不想使用終極版,您可以手動換行,而不是使用反應,終極版的連接交換機,並通過的loggedIn道具交換機。例如,您可以在此包裝器中聽取Firebase onAuthStateChanged,如下所示:

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}/>; 
    } 
} 
+0

我喜歡你的解決方案。我試圖在沒有Redux的情況下實現它,並且我得到了這個錯誤,說'connect is undefined'。這是一個Redux方法嗎?如何在沒有Redux的情況下執行此操作?我創建了'FirebaseSwitch'組件,並像你所建議的那樣將它導入到我的'index.ios.js'中。再次感謝!!! – szier

+0

是的,連接來自react-redux。在路由器場景中使用FirebaseSwitch替換RootSwitch。 –

+0

很酷謝謝你。我這樣做,但我很好奇如何'rootSelector'可以調用'props.loggedIn',因爲每當我重新加載模擬器時加載的初始'Scene'總是'authScreens'。 – szier

相關問題