我用react navigation v3构建导航,用firebase构建auth。没问题。导航流程是可行的,我可以注册。我面临的问题是,当我按下"注册"按钮时,它不会跳到"注册屏幕"。
所以构建的结构:在App.js中我正在做导航部分。首次发送欢迎屏幕,其中包括登录。
这是欢迎屏幕:
import React, { Component } from 'react'
import {StyleSheet, View } from "react-native";
import {Container, Text, Form, Content, Header, Button, Input, Label, Item} from 'native-base';
import SignUp from '../screens/register/SignUp'
import * as firebase from 'firebase';
const firebaseConfig = {
apiKey: "example example",
authDomain: "example example",
databaseURL: "example example",
projectId: "example example",
storageBucket: "example example",
};
firebase.initializeApp(firebaseConfig);
export default class WelcomeScreen extends Component {
constructor(props){
super(props)
this.state = ({
email: '',
password: ''
})
}
loginUser = (email, password, navigate) => {
try {
firebase.auth().signInWithEmailAndPassword(email,password).then(function(user){
console.log(user);
navigate('Learn')
})
}
catch (error) {
console.log(error.toString())
}
};
render() {
return (
<Container style={styles.container}>
<Form>
<Item floatingLabel>
<Label>E-mail</Label>
<Input
autocorrect={false}
autoCapitalize={'none'}
onChangeText={(email) => this.setState({email})}
/>
</Item>
<Item floatingLabel>
<Label>Password</Label>
<Input
secureTextEntry={true}
autocorrect={false}
autoCapitalize={'none'}
onChangeText={(password)=>this.setState({password})}
/>
</Item>
</Form>
<Button style={{backgroundColor:'#6c5ce7', marginTop: 10}}
onPress={()=>this.loginUser(this.state.email,this.state.password)}
rounded
success
>
<Text>Kelimeda'ya Uç</Text>
</Button>
<Button style={{backgroundColor:'#6c5ce7', marginTop: 10}}
onPress={()=>this.props.navigation.navigate('SignUp')}
rounded
primary
>
<Text>Beni Kaydet!</Text>
</Button>
</Container>
);
}
}
注册屏幕:
import React, { Component } from 'react'
import {StyleSheet, View } from "react-native";
import {Container, Text, Form, Content, Header, Button, Input, Label, Item} from 'native-base';
import * as firebase from 'firebase';
export default class WelcomeScreen extends Component {
constructor(props){
super(props)
this.state = ({
email: '',
password: ''
})
}
signUpUser = (email, password) => {
try {
if(this.state.password.length < 6){
alert('Lutfen 6 dan daha uzun bir karakter giriniz.')
return
}
firebase.auth().createUserWithEmailAndPassword(email,password)
}
catch (error) {
console.log(error.toString())
}
};
render() {
return (
<Container style={styles.container}>
<Form>
<Item floatingLabel>
<Label>E-mail</Label>
<Input
autocorrect={false}
autoCapitalize={'none'}
onChangeText={(email) => this.setState({email})}
/>
</Item>
<Item floatingLabel>
<Label>Password</Label>
<Input
secureTextEntry={true}
autocorrect={false}
autoCapitalize={'none'}
onChangeText={(password)=>this.setState({password})}
/>
</Item>
</Form>
<Button style={{backgroundColor:'#6c5ce7', marginTop: 10}}
onPress={()=>this.signUpUser(this.state.email,this.state.password)}
rounded
primary
>
<Text>Beni Kaydet!</Text>
</Button>
</Container>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 5,
justifyContent: 'center',
backgroundColor: '#fff',
},
});
这就是应用程序屏幕。我需要在这里检查用户是否已登录?还是欢迎屏幕?
//imports...
import React, { Component } from 'react';
import {View, StatusBar} from 'react-native';
import {
createSwitchNavigator,
createAppContainer,
createDrawerNavigator,
createBottomTabNavigator,
createStackNavigator,} from 'react-navigation';
import Icon from 'react-native-vector-icons/Ionicons';
import WelcomeScreen from './src/screens/Welcome';
import Learn from './src/screens/Tab/Learn';
import Settings from './src/screens/Tab/Settings';
import Play from './src/screens/Tab/Play';
//content: const & functions and styles...
const DashboardTabNavigator = createBottomTabNavigator({
Play,
Learn,
Settings
},
{
navigationOptions: ({navigation}) => {
const {routeName} = navigation.state.routes
[navigation.state.index];
return {
headerTitle: routeName,
headerTintColor:'#fff',
headerStyle:{
backgroundColor: '#2c3e50',
}
};
}
});
const DashStack = createStackNavigator({
DashboardTabNavigator: DashboardTabNavigator
}, {
defaultNavigationOptions:({navigation}) =>{
return {
headerLeft: <Icon
style={{paddingLeft: 15, color:'#fff'}}
onPress={()=>navigation.openDrawer()}
name={'md-menu'}
size={30}
/>
}
},
});
const appDrawNavigator = createDrawerNavigator({
Dashboard:{ screen: DashStack }
});
const appSwitchNavigation = createSwitchNavigator({
Welcome:{ screen: WelcomeScreen },
Dashboard:{ screen: appDrawNavigator }
});
const AppContainer = createAppContainer(appSwitchNavigation);
class App extends Component {
render() {
return(
<View style={{flex: 1}}>
<StatusBar
backgroundColor="blue"
barStyle="light-content"
/>
<AppContainer/>
</View>
) ;
}
}
export default App;
您的登录功能如下所示:
loginUser = (email, password, navigate) => {
try {
firebase.auth().signInWithEmailAndPassword(email,password).then(function(user){
console.log(user);
navigate('Learn')
})
}
catch (error) {
console.log(error.toString())
}
};
此函数需要三个参数。您应该将this.props.navigation.navigate
传递给登录功能以使用导航("学习")
<Button
style={{backgroundColor:'#6c5ce7', marginTop: 10}}
onPress={()=>this.loginUser(this.state.email,this.state.password,this.props.navigation.navigate)}
rounded
success
>
问题1的解决方案:您尚未将导航传递给loginUser
函数,因此它不起作用。请像这样将导航参数发送到loginUser
。
<Button
style={{backgroundColor:'#6c5ce7', marginTop: 10}}
onPress={()=>this.loginUser(this.state.email,this.state.password, this.props.navigation.navigate)}
rounded
success>
问题2的解决方案:对于firebase复制问题,这是因为您在应用程序中初始化了firebase实例两次。相反,你应该做的是,只需在应用程序根组件(如App.js
或Splash屏幕)初始化firebase,这样它就可以在整个应用程序生命周期中使用,无论何时你需要使用它,只要导入并使用它。
问题3的解决方案:这是一个常见的用例,可以提前了解用户的登录状态,以便将用户适当地导航到应用程序中。为此,您可以做的是,只需在AsyncStorage
中保存一个标志,例如成功登录后,将isLoggedIn
保存为YES
,并将其发布,无论何时打开应用程序,都只需分析标志的存在性/值,无论用户是否登录。一个很好的地方是你的应用程序的Splashscreen组件或应用程序的根组件。
编辑的答案(附加):(针对问题1)
您的导航路线嵌套错误,无法直接跳转到"学习自"欢迎屏幕,要从一个屏幕导航到另一个屏幕,两个屏幕应该在相同的导航范围内(如果导航器在另一个导航器中被指定为路线,则路线导航器被视为屏幕,用户在导航到它时将被导航到其初始路线)
您的代码应该以导航到Dashboard
路由为目标,这将在内部呈现嵌套的导航器,即第一个/初始路由,但对于当前嵌套,这将使您到达Play
,因此可以做的是,将Learn as first/initial route
作为选项卡导航器。
loginUser
中的代码应该是navigate('Dashboard')
,您的选项卡导航器应该将Learn
作为其初始路由。