使用Redux登录到Facebook/Expo和Firebase之后,如何显示用户数据



目标:
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);
    });
};

最新更新