目标:
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);
请有人指导我,或者只是为教程或使用这种方法的示例提供链接。谢谢。
这是我的方法
在我的根容器中,我设置了DB的侦听器。当用户符号/日志中,我发射登录请求,该请求抓住该用户的快照,并将其存储到Redux Store作为用户。然后,您可以将想要的任何组件连接到商店...
链接到repo以供进一步参考。https://github.com/gavinthomas1192/motomechanicmeekanic/blob/master/app/containers/rootcontainer.jsrootcontainer ...
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);
});
};