React Native - 将登录的 Firebase 用户重定向到 Home 组件
Posted
技术标签:
【中文标题】React Native - 将登录的 Firebase 用户重定向到 Home 组件【英文标题】:React Native - Redirect logged in Firebase user to Home Component 【发布时间】:2016-12-05 20:18:43 【问题描述】:如果用户已经登录,我的目标是将用户重定向到Home
组件。只有当调用_logInUser()
时,我才能登录用户并将他们重定向到Home
。但是,一旦重定向到 Home
组件,如果我刷新模拟器,应用程序就会返回到 Login
组件。
我尝试使用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 ***
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`
);
);
【问题讨论】:
对不起,我没有完整的答案给你。但是,我相信 Switch Feature 在这里可能有用。 【参考方案1】:首先,在您的登录组件中,您正在以同步方式检查 currentUser,但它可能在 componentWillMount 中尚不可用。你可以异步进入:
firebase.auth().onAuthStateChanged(function(user)
if (user)
// User is signed in.
else
// No user is signed in.
);
如果用户已登录,很可能调用Actions.home()
就足够了。但是,随着您的应用程序的增长,您可能希望将此逻辑从登录屏幕上移。正如 Kyle 所建议的,您可以使用 Switch 功能。它通常(引用文档)与 redux 一起使用,如下所示:
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,如下所示:
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/>;
【讨论】:
我喜欢你的解决方案。我试图在没有 Redux 的情况下实现它,我收到了这个错误,上面写着connect is undefined
。这是一种 Redux 方法吗?如果没有 Redux,我将如何做到这一点?我创建了FirebaseSwitch
组件并将其导入到我的index.ios.js
中,就像您建议的那样。再次感谢!!!
是的,connect 来自 react-redux。在 Router 场景中将 RootSwitch 替换为 FirebaseSwitch。
很酷,谢谢。我这样做了,但我很好奇rootSelector
可以如何调用props.loggedIn
,因为每当我重新加载模拟器时加载的初始Scene
始终是authScreens
。
我的 FirebaseSwitch 中有错字,loggenIn
而不是 setState 中的 loggedIn
。我编辑了我的帖子。以上是关于React Native - 将登录的 Firebase 用户重定向到 Home 组件的主要内容,如果未能解决你的问题,请参考以下文章
React Native - 将 ActivityIndicator 重新定位到登录按钮
React Native - 将登录的 Firebase 用户重定向到 Home 组件
React-Native 将标题从 Navigator 传递到 NavigatorIOS