使用redux登录facebook / expo和firebase后如何显示用户数据

问题描述 投票:1回答:1

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

请有人指导我,或者只是提供教程的链接或使用这种方法的示例。谢谢。

react-native redux facebook-sdk-4.0 expo
1个回答
1
投票

这是我的方法

在我的根容器中,我从数据库中设置事件侦听器。当用户签名/登录时,我会触发一个登录请求,该请求抓取该用户的快照并将其作为用户存储到redux存储中。然后你可以将你想要的任何组件连接到商店......

链接到回购以供进一步参考。 https://github.com/GavinThomas1192/motoMechanicMeeKanic/blob/master/App/Containers/RootContainer.js RootContainer ...

  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);
    });

};
© www.soinside.com 2019 - 2024. All rights reserved.