如何在使用 redux 登录 facebook/expo 和 firebase 后显示用户数据
Posted
技术标签:
【中文标题】如何在使用 redux 登录 facebook/expo 和 firebase 后显示用户数据【英文标题】:How to show the User Data after logging in with facebook/expo and firebase using redux 【发布时间】:2017-12-12 02:41:25 【问题描述】:目标: 1. 我想将我的用户的 public_profile 数据保存到 firebase 数据库 2. 我想在我的编辑配置文件屏幕组件之一中显示我的用户的 public_profile,并且能够对其进行编辑。
当前进展: 1. 我现在可以通过 facebook(expo) 对我的用户进行身份验证,并通过 Redux 在 firebase 身份验证控制台上显示它。
这是我的代码: 这是我的 auth_actions.js
import AsyncStorage from 'react-native';
import
FACEBOOK_LOGIN_SUCCESS,
FACEBOOK_LOGIN_FAIL
from './types';
import Facebook from 'expo';
import firebase from 'firebase';
// How to use Asyncstorage
// Asyncstorage.setItem('fb_token', token);
// AsyncStorage.getItem('fb_token');
export const facebookLogin = () => async dispatch =>
let token = await AsyncStorage.getItem('fb_token');
if (token)
//Dispatch an action saying FB login is done
dispatch( type: FACEBOOK_LOGIN_SUCCESS, payload: token );
else
// Start up F B Login process
doFacebookLogin(dispatch);
;
const doFacebookLogin = async dispatch =>
let type, token = await Facebook.logInWithReadPermissionsAsync('215807715628181',
permissions: ['public_profile', 'email']
);
if (type === 'cancel')
return dispatch( type: FACEBOOK_LOGIN_FAIL );
if (type === 'success')
await AsyncStorage.setItem('fb_token', token);
const credential = firebase.auth.FacebookAuthProvider.credential(token);
firebase.auth().signInWithCredential(credential).catch((error) =>
console.log(error)
);
dispatch( type: FACEBOOK_LOGIN_SUCCESS, payload: token );
;
这是我的 LandingScreen.js
import React, Component from 'react';
import View, Text, Image, StyleSheet, AsyncStorage from 'react-native';
import Button, SocialIcon from 'react-native-elements';
import Actions from 'react-native-router-flux';
import connect from 'react-redux';
import * as actions from '../actions';
class LandingScreen extends Component
fbLoginPress()
this.props.facebookLogin();
this.onAuthComplete(this.props);
// Code for rebuilding the facebook authentication flow,
// remove this when you want to try it on the first load.
AsyncStorage.removeItem('fb_token');
componentWillReceiveProps(nextProps)
this.onAuthComplete(nextProps);
onAuthComplete(props)
if (props.token)
Actions.home()
render()
return (
<View>
<View>
<Image
resizeMode='contain'
style=styles.landingImageStyle
source=require('../assets/risto-landing.png')
/>
<Text style=styles.titleAppStyle>Risto </Text>
</View>
<View style=styles.buttonContainer>
<Button
large
title='Sign in With Facebook'
backgroundColor='#4068AD'
icon=name: 'facebook-square', type: 'font-awesome'
style=[styles.buttonStyle, styles.fbColor]
onPress=Actions.home
// onPress=this.fbLoginPress.bind(this)
/>
<Button
large
title='Sign In or Sign Up With Email'
icon=name: 'envelope', type: 'font-awesome'
backgroundColor='#F8A443'
style=[styles.buttonStyle, styles.emailColor]
onPress=Actions.emailLogin
/>
</View>
</View>
);
const styles = StyleSheet.create(
landingImageStyle:
alignSelf: 'center',
height: 350,
,
titleAppStyle:
alignSelf: 'center',
textAlign: 'center',
fontWeight: 'bold',
fontSize: 18,
marginTop: 40
,
buttonStyle:
marginTop: 20,
borderRadius: 15,
borderWidth: 4,
,
emailColor:
borderColor: '#F8A443'
,
fbColor:
borderColor: '#4068AD'
,
buttonContainer:
marginTop: 90
);
function mapStateToProps( auth )
return token: auth.token ;
export default connect (mapStateToProps, actions)(LandingScreen);
请有人指导我,或者只是提供一个使用这种方法的教程或示例的链接。谢谢。
【问题讨论】:
【参考方案1】:这是我的方法
在我的根容器中,我从数据库设置事件侦听器。当用户登录/登录时,我会触发一个登录请求,该请求会获取该用户的快照并将其作为用户存储到 redux 存储中。然后你可以将任何你想要的组件连接到商店...
链接到 repo 以供进一步参考。 https://github.com/GavinThomas1192/motoMechanicMeeKanic/blob/master/App/Containers/RootContainer.js 根容器...
componentDidMount()
// if redux persist is not active fire startup action
if (!ReduxPersist.active)
this.props.startup()
// ********* Add a listener from the database to monitor whos logged in. *********
firebase.auth().onAuthStateChanged((user) =>
// ********* If a user is logged in firebase will return the user object. THEY ARE NOT LOGGED IN THOUGH *********
if (user)
console.log('onAuthStateChanged', user)
// ********* Then we call an official Firebase login function through actions *********
this.props.loginRequest(user);
else
console.log('No user signed in')
);
// ********* After logging in the found user from above we need to set them to redux store *********
let signedInUser = firebase.auth().currentUser;
if (signedInUser)
this.props.loginRequest(signedInUser);
console.log('currentUserSignedIn', signedInUser)
else
console.log('no active user', signedInUser)
Redux 操作
// ******** This is actually referencing the firebaseInitializeApp from the ./Containers/App ********
import firebase from 'firebase'
export const userSet = user => (
type: 'USER_SET',
payload: user,
);
export const userCreate = user => (
type: 'USER_CREATE',
payload: user,
);
export const userUpdate = user => (
type: 'USER_UPDATE',
payload: user,
);
export const userSetRequest = user => dispatch =>
return new Promise((resolve, reject) =>
resolve(dispatch(userSet(user)));
);
;
export const loginRequest = user => dispatch =>
// ******** This gets called in RootContainer on mount, it will populate redux store with the entire User object from firebase ********
// ******** FYI - The entire user object also contains their vehicles ********
// ******** Here we need to check if user already exists in Firebase Database so that we dont overwrite their old data ********
// ******** WARNING! With Firebase if you set data to a spot that has existing data it will overwrite it! ********
console.log('RECIEVED USER TO LOOKUP', user);
firebase.database().ref('users/' + user.uid).once('value').then(function (snapshot)
// ******** This method is straight from their docs ********
// ******** It returns whatever is found at the path xxxxx/users/user.uid ********
let username = snapshot.val();
console.log(' FOUND THIS USER FROM THE DB', username);
// ******** If the username object is empty there wasn't any data at xxxxxx/user/user.uid ********
// ******** It's safe to write data to this spot ********
username === null ? firebase.database().ref('users/' + user.uid).set(
account: username
).then(function ()
console.log('STORED THIS USER TO FIREBASE DB', username);
dispatch(userSet(username))
)
// ******** Otherwise, the user already exists and we should update redux store with logged in user ********
: dispatch(userSet(username))
)
.catch((err) => console.log(err));
dispatch(userSet(user))
console.log('INSIDE FIREBASEE DB SET', user)
;
export const signupRequest = (email, password, username) => dispatch =>
// ******** The signup actions only trigger for first time users, no need to check database ********
console.log('RECIEVED USER TO SIGNUP', email, password);
firebase.auth().createUserWithEmailAndPassword(email, password)
.then((authData) =>
// ******** Firebase will create a route with whatever KEY is fed to the .set method ********
// ******** We dont actually want this to avoid deep nesting ********
// ******** So we package up our user.account object and .set(account) without any key value pairs ********
let account =
account.email = email.toLowerCase()
account.uid = authData.uid
account.username = username
firebase.database().ref('users/' + authData.uid).set(
account
).then(() =>
// ******** Now we need to grap a snapshot from the DB to validate account creation and update the redux store locally ********
firebase.database().ref('users/' + authData.uid).once('value').then(function (snapshot)
let updatedUser = snapshot.val();
console.log(' FOUND THIS USER FROM THE DB after signup', username);
).then(() =>
dispatch(userSet(updatedUser));
)
)
).catch((err) => console.log(err));
;
export const passwordResetRequest = email => dispatch =>
var auth = firebase.auth();
let emailAccount = email.toLowerCase();
console.log(emailAccount)
auth.sendPasswordResetEmail(emailAccount).then(function ()
console.log('Password reset email sent')
).catch(function (error)
console.log(error);
);
;
【讨论】:
以上是关于如何在使用 redux 登录 facebook/expo 和 firebase 后显示用户数据的主要内容,如果未能解决你的问题,请参考以下文章
如何在使用 redux 登录 facebook/expo 和 firebase 后显示用户数据
如何在页面打开后从 cookie 中正确设置属性(如果用户已登录)或使用路由器和 redux 在 React 中使用 F5
如何使用 MongoDB + NodeJS Express 向 ReactJS React Router 和 Redux 添加登录身份验证和会话?