首页 文章

React native redux fbsdk登录

提问于
浏览
2

我想在我的应用程序上创建一个facebook登录名,使用react-native,redux和react-native-fbsdk . 实际上,当我处于第一个状态(未登录)时,我遇到了一个问题,我看到了这个状态:

enter image description here

当我点击登录按钮时,我有这样的状态:

enter image description here

验证设置为true,但应用程序保持身份验证,即使我等了5分钟,也没有发生任何事情......我认为它在我的代码中遗漏了一些但我不知道是什么 .

我在这里通过我的代码 .

The reducer :

import {
  AUTH_SUCCESS,
  AUTH_FAILURE,
  AUTH_STARTED,
  AUTH_ERROR,
  AUTH_FAILURE_REMOVE,
  LOGOUT
} from '../actions/types';

const initialState = {
  authenticating: false,
  authToken: null,
  authError: null,
  facebookToken: null,
  facebookProfile: null
}

function authReducer(state = initialState, action) {
  switch(action.type) {
    case AUTH_STARTED:
      return Object.assign({}, state, {
        authenticating: true,
        loginText: 'Connexion..'
      });
    case AUTH_SUCCESS:
      return Object.assign({}, state, {
        authenticating: false,
        authToken: action.authToken,
        facebookToken: action.facebookToken,
        facebookProfile: action.facebookProfile,
      });
    case AUTH_FAILURE:
      return Object.assign({}, state, {
        authenticating: false,
        authError: action.authError.message,
      });
    case AUTH_FAILURE_REMOVE:
      return Object.assign({}, state, {
        authError: null,
      });
    case LOGOUT:
      return Object.assign({}, state, {
        authenticating: false,
        authToken: null,
        facebookToken: null,
        facebookProfile: null,
        loginText: null,
      });
    default:
      return state;
  }
}

export default authReducer;

The action : (所有操作都在名为types.js的单独文件中)

import { facebookLoginAPI, getFacebookInfoAPI } from '../src/facebook';
import { getServerAuthToken } from '../src/auth';
import {
  AUTH_STARTED,
  AUTH_SUCCESS,
  AUTH_FAILURE,
  AUTH_ERROR,
  AUTH_FAILURE_REMOVE,
  LOGOUT
} from './types';

export function authStarted() {
  return {
    type: AUTH_STARTED,
  };
}

export function authSuccess(facebookToken, facebookProfile, serverAuthToken){
  return {
    type: AUTH_SUCCESS,
    facebookToken,
    facebookProfile,
    authToken: serverAuthToken,
  };
}

export function authFailure(authError){
  return {
    type: AUTH_FAILURE,
    authError,
  };
}

export function authFailureRemove() {
  return {
    type: AUTH_FAILURE_REMOVE,
  };
}

export function logout() {
  return {
    type: LOGOUT,
  };
}

export function facebookLogin() {
  return (dispatch) => {
    dispatch(authStarted());
    const successValues = [];
    facebookLoginAPI().then((facebookAuthResult) => {
      successValues.push(facebookAuthResult.accessToken);
      return getFacebookInfoAPI(facebookAuthResult.accessToken);
    }).then((facebookProfile) => {
      successValues.push(serverAuthToken);
      dispatch(authSuccess(...successValues));
    }).catch((error) => {
      dispatch(authFailure(error));
      setTimeOut(() => {
        dispatch(authFailureRemove());
      }, 4000);
    });
  };
}

The facebook API :

import {
  LoginManager,
  AccessToken,
  GraphRequest,
  GraphRequestManager,
} from 'react-native-fbsdk';

const facebookParams = 'id,name,email,picture.width(100).height(100)';

export function facebookLoginAPI() {
  return new Promise((resolve, reject) => {
    LoginManager.logInWithReadPermissions(['public_profile', 'user_friends', 'email'])
    .then((FBloginResult) => {
      if (FBloginResult.isCancelled) {
        throw new Error('Login cancelled');
      }

      if (FBloginResult.deniedPermissions) {
        throw new Error('We need the requested permissions');
      }

      return AccessToken.getCurrentAccessToken();
      console.log(FBloginResult);
    })
    .then((result) => {
      resolve(result);
    })
    .catch((error) => {
      reject(error);
    });
  });
}

export function getFacebookInfoAPI() {
  return new Promise((resolve, reject) => {
    const profileInfoCallback = (error, profileInfo) => {
      if (error) reject(error);

      resolve(profileInfo);
    };

    const profileInfoRequest =
      new GraphRequest(
        '/me',
        {
          parameters: {
            fields: {
              string: facebookParams,
            },
          },
        },
        profileInfoCallback
      );

    new GraphRequestManager().addRequest(profileInfoRequest).start();
  });
}

export function getFacebookFriends() {
  return new Promise((resolve, reject) => {
    const profileInfoCallback = (error, profileInfo) => {
      if (error) reject(error);
      console.log(profileInfo);
      resolve(profileInfo);
    };

    const profileFriendsRequest =
      new GraphRequest(
        '/me/friends',
        {
          parameters: {
            fields: {
              string: facebookParams,
            },
          },
        },
        profileInfoCallback
      );

    new GraphRequestManager().addRequest(profileFriendsRequest).start();
  });
}

The Button for login :

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { View } from 'react-native';
import { bindActionCreators } from 'redux';
import { facebookLogin } from '../../actions/auth';
import { Button } from '../common';
import FBSDK, { LoginManager } from 'react-native-fbsdk';



class Login extends Component {
  componentWillMount() {
    this.authCheck(this.props.authToken);
  }

  componentWillReceiveProps(nextProps) {
    this.authCheck(nextProps.authToken);
  }

  authCheck(authToken){
    if (authToken) {
      return authToken;
    }
  }

  renderError() {
    if(this.props.authError){
      console.log(this.props.authError);
    }
    return null;
  }

  render() {
    return(
        <Button onPress={this.props.onLoginPressed}> Login with facebook </Button>
    );
  }
}


export default Login;

And the AuthContainer :

import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { facebookLogin } from '../actions/auth';
import Login from '../components/Login';

class AuthContainer extends Component {
  onLoginPressed() {
    this.props.actions.facebookLogin();
    console.log(this.props);
  }

  render(){
    console.log(this.props);
    return (
      <Login {...this.props} onLoginPressed={this.onLoginPressed.bind(this)} />
    );
  }
}

AuthContainer.propTypes = {
  welcomeText: PropTypes.string,
  authenticating: PropTypes.bool.isRequired,
  authToken: PropTypes.oneOfType([
    PropTypes.bool,
    PropTypes.string,
  ]),
  authError: PropTypes.oneOfType([
    PropTypes.bool,
    PropTypes.string,
  ]),
  actions: PropTypes.shape({
    facebookLogin: PropTypes.func.isRequired,
  }).isRequired,
};

function mapStateToProps(state) {
  return {
    authenticating: state.auth.authenticating,
    authToken: state.auth.authToken,
    authError: state.auth.authError,
    loginText: state.auth.loginText,
  };
  console.log(state);
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators({ facebookLogin }, dispatch),
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(AuthContainer);

and the App.js :

import React, { Component } from 'react';
import { Text, View, AsyncStorage } from 'react-native';
import { createStore, compose, applyMiddleware } from 'redux';
import { connect, Provider } from 'react-redux';
import { persistStore } from 'redux-persist';
import thunkMiddleware from 'redux-thunk';
import reducers from './reducers';
import { Header, Card, CardSection } from './components/common';
import AuthContainer from './containers/AuthContainer';

const store = compose(
  applyMiddleware(thunkMiddleware)
)(createStore)(reducers);

persistStore(store, { storage: AsyncStorage });


class App extends Component {
  render() {
    return(
      <Provider store={store}>
        <View>
          <Header headerText="Kiwee" />
          <Card>
            <CardSection>
              <AuthContainer />
            </CardSection>
          </Card>
        </View>
      </Provider>
    );
  }
}

export default App;

有人可以帮助我吗?这对我来说非常重要,我通过了1个月的搜索没有任何回复的解决方案 .

1 回答

  • 3

    尝试从reducers中删除.push()函数,因为它是变异操作 . 尝试使用concat或spread运算符 . 喜欢尝试替换

    successValues.push(facebookAuthResult.accessToken);

    [... successValues,.. facebookAuthResult.accessToken]

    它是与Immutability相关的东西,你可以在redux教程中查看或者可以在google上找到(我现在不能很好地解释这种行为)

相关问题