7

Moim celem jest przekierowanie użytkownika do komponentu Home, jeśli użytkownik jest już zalogowany. Jestem w stanie zalogować się do użytkownika i przekierować go na numer Home tylko pod warunkiem, że jest to _logInUser() . Jednak po przekierowaniu do komponentu Home, po odświeżeniu symulatora aplikacja wraca do komponentu Login.React Native - Przekierowanie zalogował się użytkownik Firebase do Home Component

Podjęto próbę rozwiązania tego problemu przy użyciu componentWillMount() i ustawienia let user = firebaseApp.auth().currentUser. Jednak nawet zalogowałem się do konsoli user, ale wygląda na to, że test if przechodzi bezpośrednio do instrukcji else. Byłbym wdzięczny za każdy wgląd!

Tu jest mój kodu (używam react-native-router-flux routingu):

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

Niestety, nie mamy dla ciebie pełnej odpowiedzi. Uważam jednak, że funkcja [Przełącznik funkcji] (https://github.com/aksonov/react-native-router-flux/blob/master/docs/OTHER_INFO.md#switch-new-feature) może być tutaj przydatna. –

Odpowiedz

5

pierwsze, Twój komponent logowania sprawdzasz currentUser w sposób synchroniczny, ale może nie być to jeszcze dostępne w stanie w componentWillMount. Można powinien dostać w sposób asynchroniczny.

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

Najprawdopodobniej będzie to wystarczy zadzwonić Actions.home() jeśli użytkownik jest zalogowany Jednakże, jak rośnie Twoja aplikacja może chcesz przenieść tę logikę się z ekranu logowania. Jak zasugerował Kyle, możesz użyć funkcji Przełącz. Jest zwykle (do docs cudzysłów) używanych z Redux coś takiego:

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

Jeśli nie chcesz używać Redux, można ręcznie zawijać przełącznik zamiast korzystania reagować-Redux podłączane i zdać loggedin prop Przełącz . Na przykład możesz odsłuchiwać firewall na AuthStateChanged w tym opakowaniu, coś takiego:

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

Podoba mi się twoje rozwiązanie. Próbuję zaimplementować to bez Redux i otrzymuję ten błąd, który mówi, że 'connect is undefined'. Czy to jest metoda Redux? Jak mógłbym to zrobić bez Redux? Stworzyłem komponent 'FirebaseSwitch' i zaimportowałem go do mojego' index.ios.js', tak jak sugerowałeś. Dzięki jeszcze raz!!! – szier

+0

Tak, połączenie pochodzi z metody reakcji-redux. W Replace RootSwitch z FirebaseSwitch w scenach routera. –

+0

Fajne dzięki. Zrobiłem to, ale jestem ciekawy, jak "rootSelector" może nazywać 'props.loggedIn', ponieważ początkowa' Scena', która jest ładowana za każdym razem, gdy ponownie ładuję symulator jest zawsze 'authScreens'. – szier