登录 Firebase React Native Expo 后无法获取用户数据
Posted
技术标签:
【中文标题】登录 Firebase React Native Expo 后无法获取用户数据【英文标题】:Can't get user data after logging in Firebase React Native Expo 【发布时间】:2021-09-22 02:23:12 【问题描述】:我正在尝试使用 React Native / Expo 和 Firebase 创建一个社交媒体应用程序,并且我已经成功地能够创建帐户和登录,但我仍在尝试弄清楚如何获取用户数据,例如用户名用户登录。基本上,当我登录或创建帐户时,我希望个人资料页面显示与登录用户关联的用户名和个人资料图片,但我不知道该怎么做。它可能与 AuthStateChanged() 函数或类似的东西有关,但我不确定。
这是我的 App.js 文件:
import 'react-native-gesture-handler';
import React, useState from 'react';
import LogBox, Text, View from 'react-native';
import AppLoading from 'expo-app-loading';
import * as Font from 'expo-font';
import Feather from '@expo/vector-icons/Feather'
import useFonts, Nunito_400Regular as NunitoRegular, Nunito_700Bold as NunitoBold from '@expo-google-fonts/nunito';
import NavigationContainer, DefaultTheme from '@react-navigation/native';
import Navigator from './src/navigation/index';
import * as firebase from "firebase";
import "firebase/auth";
// Your web app's Firebase configuration
var firebaseConfig =
apiKey: "AIzaSyB1TxcRpLQq0Zqs0f0FvPitIto0tZo_0xM",
authDomain: "shutter-42e70.firebaseapp.com",
projectId: "shutter-42e70",
storageBucket: "shutter-42e70.appspot.com",
messagingSenderId: "149059508529",
appId: "1:149059508529:web:0dbc5bbbb75bf022ef7810"
;
if (firebase.apps.length === 0)
firebase.initializeApp(firebaseConfig);
// The theme we'll be using for our navigator
const MyTheme =
...DefaultTheme,
colors:
...DefaultTheme.colors,
background: '#FAFAFA'
,
;
// Loads the Feather icons (https://docs.expo.io/guides/icons/)
function cacheFonts(fonts)
return fonts.map(font => Font.loadAsync(font));
export default function App()
const [assetsReady, setAssetsReady] = useState(false);
async function _loadFonts()
const iconFontAssets = cacheFonts([Feather.font])
await Promise.all([...iconFontAssets]);
// Loads the Nunito font (https://docs.expo.io/guides/using-custom-fonts/)
let [fontsLoaded] = useFonts(
NunitoRegular, NunitoBold
);
// If the fonts or assets are not loaded, we show a default App Loading screen.
// Otherwise, we return our Photo Sharing App!
if (!fontsLoaded || !assetsReady)
return <AppLoading
startAsync=_loadFonts
onFinish=() => setAssetsReady(true)
onError=console.warn
/>
return (
<NavigationContainer theme=MyTheme>
<Navigator />
</NavigationContainer>
);
这是我的 Login.js 文件:
import React from 'react';
import StyleSheet, View, Text, Image, TextInput, TouchableOpacity from 'react-native';
import theme from '../../assets/themes';
import Formik from 'formik';
import Octicons, Fontisto from '@expo/vector-icons';
import Separator from './Separator';
import KeyBoardAvoidingWrapper from './KeyboardAvoidingWrapper';
import firebase from 'firebase';
var errorMsg = '...'
const Login = (navigation) =>
return (
<KeyBoardAvoidingWrapper>
<View>
<View style = styles.StyledContainer>
<View style = styles.InnerContainer>
<Image style = styles.PageLogo resizeMode = "cover" source = require('./../../assets/images/logo.png') />
<Text style = styles.PageTitle>Shutter</Text>
<Text style = styles.TagLine>Social Media for Photographers</Text>
</View>
</View>
<Formik
initialValues = email: '', password: ''
onSubmit = (values) =>
firebase.auth().signInWithEmailAndPassword(values.email, values.password)
.then((result) =>
navigation.navigate('Feed');
)
.catch((error) =>
alert(error)
)
>
(handleChange, handleBlur, handleSubmit, values) => (
<View style = styles.styledFormArea>
<MyTextInput
label = " "
icon = "mail"
placeholder = "email@email.com"
placeholderTextColor = theme.colors.black
onChangeText = handleChange('email')
onBlur = handleBlur('email')
value = values.email
keyboardType = "email-address"
/>
<MyTextInput
label = " "
icon = "lock"
placeholder = "password"
placeholderTextColor = theme.colors.black
onChangeText = handleChange('password')
onBlur = handleBlur('password')
value = values.password
secureTextEntry = true
/>
<Text style = styles.msgBox>errorMsg</Text>
<TouchableOpacity onPress = handleSubmit style = styles.loginButton>
<Text style = styles.loginButtonText>Login</Text>
</TouchableOpacity>
<Separator />
<TouchableOpacity onPress = handleSubmit style = styles.googleSigninButton>
<Fontisto name = "google" color = theme.colors.white size = 25 ></Fontisto>
<Text style = styles.googleSigninButtonText>Sign in with Google</Text>
</TouchableOpacity>
<View style = styles.signupLinkView>
<Text style = styles.signupText>Don't have an account? </Text>
<TouchableOpacity style = styles.signupLinkButton>
<Text onPress = () => navigation.navigate('Sign Up') style = styles.signupLinkText>Sign up</Text>
</TouchableOpacity>
</View>
</View>
)
</Formik>
</View>
</KeyBoardAvoidingWrapper>
);
;
const MyTextInput = (label, icon, ...props) =>
return (
<View>
<View style = styles.leftIcon>
<Octicons name = icon size = 30 color = theme.colors.primary />
</View>
<Text style = styles.styledTextInput>label</Text>
<TextInput style = styles.textInput ...props />
</View>
)
const styles = StyleSheet.create(
StyledContainer:
flex: 1,
padding: theme.spacing.m,
paddingTop: theme.spacing.l,
backgroundColor: theme.colors.white,
marginTop: 80,
,
InnerContainer:
justifyContent: 'center',
alignItems: 'center',
,
PageLogo:
width: 100,
height: 100,
,
PageTitle:
...theme.textVariants.h1,
marginTop: theme.spacing.m,
,
TagLine:
...theme.textVariants.body3,
,
styledFormArea:
justifyContent: 'center',
marginHorizontal: theme.spacing.l,
borderRadius: theme.borderRadius.m,
marginTop: 40,
,
leftIcon:
position: 'absolute',
zIndex: 1,
marginTop: 28,
marginLeft: 12,
,
styledTextInput:
...theme.textVariants.body3,
,
textInput:
backgroundColor: theme.colors.gray,
paddingVertical: 10,
paddingLeft: 50,
paddingRight: theme.spacing.l,
borderRadius: theme.borderRadius.m,
,
loginButton:
backgroundColor: theme.colors.primary,
alignItems: 'center',
marginTop: 20,
paddingVertical: 8,
borderRadius: theme.borderRadius.m,
,
loginButtonText:
...theme.textVariants.body2,
color: theme.colors.white,
,
msgBox:
...theme.textVariants.body3,
alignSelf: 'center',
,
googleSigninButton:
backgroundColor: theme.colors.primary,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
marginTop: 16,
paddingVertical: 8,
borderRadius: theme.borderRadius.m,
,
googleSigninButtonText:
...theme.textVariants.body2,
color: theme.colors.white,
paddingLeft: 25,
,
signupLinkView:
justifyContent: 'center',
flexDirection: 'row',
alignItems: 'center',
padding: theme.spacing.sm,
,
signupText:
...theme.textVariants.body3,
,
signupLinkButton:
,
signupLinkText:
...theme.textVariants.body3,
opacity: 0.6,
,
)
export default Login;
这是我的 Signup.js 文件:
import React from 'react';
import StyleSheet, View, Text, Image, TextInput, TouchableOpacity from 'react-native';
import theme from '../../assets/themes';
import Formik from 'formik';
import Octicons from '@expo/vector-icons';
import Separator from './Separator';
import KeyboardAvoidingWrapper from './KeyboardAvoidingWrapper';
import firebase from 'firebase';
var errorMsg = '...'
const SignUp = (navigation) =>
return (
<KeyboardAvoidingWrapper>
<View>
<View style = styles.StyledContainer>
<View style = styles.InnerContainer>
<Image style = styles.PageLogo resizeMode = "cover" source = require('./../../assets/images/logo.png') />
<Text style = styles.PageTitle>Shutter</Text>
<Text style = styles.TagLine>Social Media for Photographers</Text>
</View>
</View>
<Formik
initialValues = fullName: '', email: '', username: '', password: '', confirmPassword: ''
onSubmit = (values) =>
firebase.auth().createUserWithEmailAndPassword(values.email, values.password)
.then((result) =>
firebase.firestore().collection("users")
.doc(firebase.auth().currentUser.uid)
.set(
fullName: values.fullName,
displayName: values.email,
username: values.username,
password: values.password,
)
if (values.password === values.confirmPassword)
navigation.navigate('Signup Options')
else
errorMsg = 'Passwords do not match'
)
.catch((error) =>
alert(error)
)
>
(handleChange, handleBlur, handleSubmit, values) => (
<View style = styles.styledFormArea>
<MyTextInput
label = "Name"
icon = "person"
placeholder = "John Doe"
placeholderTextColor = theme.colors.black
onChangeText = handleChange('fullName')
onBlur = handleBlur('fullName')
value = values.fullName
/>
<MyTextInput
label = "Email"
icon = "mail"
placeholder = "email@email.com"
placeholderTextColor = theme.colors.black
onChangeText = handleChange('email')
onBlur = handleBlur('email')
value = values.email
keyboardType = "email-address"
/>
<MyTextInput
label = "Username"
icon = "person"
placeholder = "username"
placeholderTextColor = theme.colors.black
onChangeText = handleChange('username')
onBlur = handleBlur('username')
value = values.username
/>
<MyTextInput
label = "Password"
icon = "lock"
placeholder = "password"
placeholderTextColor = theme.colors.black
onChangeText = handleChange('password')
onBlur = handleBlur('password')
value = values.password
secureTextEntry = true
/>
<MyTextInput
label = "Confirm Password"
icon = "lock"
placeholder = "retype password"
placeholderTextColor = theme.colors.black
onChangeText = handleChange('confirmPassword')
onBlur = handleBlur('confirmPassword')
value = values.confirmPassword
secureTextEntry = true
/>
<Text style = styles.msgBox>errorMsg</Text>
<TouchableOpacity onPress = handleSubmit style = styles.loginButton>
<Text style = styles.loginButtonText>Sign Up</Text>
</TouchableOpacity>
<Separator />
<View style = styles.signupLinkView>
<Text style = styles.signupText>Already have an account? </Text>
<TouchableOpacity style = styles.signupLinkButton>
<Text onPress = () => navigation.navigate('Login') style = styles.signupLinkText>Login</Text>
</TouchableOpacity>
</View>
</View>
)
</Formik>
</View>
</KeyboardAvoidingWrapper>
);
;
const onSignUp = (values) =>
console.log(values);
const MyTextInput = (label, icon, ...props) =>
return (
<View style = styles.inputFieldView>
<View style = styles.leftIcon>
<Octicons name = icon size = 30 color = theme.colors.primary />
</View>
<Text style = styles.styledTextInput>label</Text>
<TextInput style = styles.textInput ...props />
</View>
)
const styles = StyleSheet.create(
StyledContainer:
flex: 1,
padding: theme.spacing.m,
paddingTop: theme.spacing.l,
backgroundColor: theme.colors.white,
marginTop: 80,
,
InnerContainer:
justifyContent: 'center',
alignItems: 'center',
,
PageLogo:
width: 100,
height: 100,
,
PageTitle:
...theme.textVariants.h1,
marginTop: theme.spacing.m,
,
TagLine:
...theme.textVariants.body3,
,
inputFieldView:
marginTop: 12,
,
styledFormArea:
justifyContent: 'center',
marginHorizontal: theme.spacing.l,
borderRadius: theme.borderRadius.m,
marginTop: 40,
,
leftIcon:
position: 'absolute',
zIndex: 1,
marginTop: 28,
marginLeft: 12,
,
styledTextInput:
...theme.textVariants.body3,
,
textInput:
backgroundColor: theme.colors.gray,
paddingVertical: 10,
paddingLeft: 50,
paddingRight: theme.spacing.l,
borderRadius: theme.borderRadius.m,
,
loginButton:
backgroundColor: theme.colors.primary,
alignItems: 'center',
marginTop: 20,
paddingVertical: 8,
borderRadius: theme.borderRadius.m,
,
loginButtonText:
...theme.textVariants.body2,
color: theme.colors.white,
,
msgBox:
...theme.textVariants.body3,
alignSelf: 'center',
,
signupLinkView:
justifyContent: 'center',
flexDirection: 'row',
alignItems: 'center',
padding: theme.spacing.sm,
,
signupText:
...theme.textVariants.body3,
,
signupLinkButton:
,
signupLinkText:
...theme.textVariants.body3,
opacity: 0.6,
,
)
export default SignUp;
很抱歉,如果我的代码写得不是很好,也不是很有条理。我找不到很多关于 firebase 身份验证的好教程,所以这是我在看了 5 个不同的 firebase 身份验证教程后想出的,哈哈。任何帮助将不胜感激!
另外,如果你想查看我的整个项目文件,这里是我的 github 存储库的链接:github repo
【问题讨论】:
【参考方案1】:您应该使用 redux 或 React 挂钩将用户信息保存到全局状态。
https://reactjs.org/docs/hooks-reference.html#usecontext
https://redux.js.org/introduction/getting-started
在signInWithEmailAndPassword()的回调中返回用户资料数据
firebase.auth().signInWithEmailAndPassword(email, password)
.then((userCredential) =>
// Signed in
var user = userCredential.user;
/* user:
- email
- uid
- displayName
- emailVerified
- phoneNumber
- photoURL
- metadata
...
*/
)
.catch((error) =>
// catch error
);
然后在您的组件/屏幕中,您可以调用状态来显示用户的数据。
【讨论】:
您先生是救生员。我会试试这个! 好的,到目前为止,实现工作正常,但我将如何使用钩子使用户变量全局化?对不起,我有点菜鸟 您应该阅读上面的 2 个链接并尝试在 GitHub 上搜索一些示例存储库。这是一个例子https://github.com/9kmmr/react-native-firebase-noob-example以上是关于登录 Firebase React Native Expo 后无法获取用户数据的主要内容,如果未能解决你的问题,请参考以下文章
登录 Firebase React Native Expo 后无法获取用户数据
React Native - 将登录的 Firebase 用户重定向到 Home 组件
React native firebase - facebook登录未触发onAuthStateChanged侦听器
如何在使用 firebase/auth 和 react-native 验证他/她的电子邮件后立即登录用户而不创建整个登录页面?