react-native - react native redux fbsdk 登录

标签 react-native redux facebook-javascript-sdk react-redux react-native-fbsdk

我想在我的应用程序上创建一个 facebook 登录,使用 react-native、redux 和 react-native-fbsdk。实际上,我面临一个问题,当我处于第一个状态(未登录)时,我看到以下状态:

enter image description here

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

enter image description here

身份验证设置为 true,但应用程序继续进行身份验证,即使我等了 5 分钟,之后也没有任何 react 。我认为它在我的代码中遗漏了一些东西,但我不知道是什么。

我在这里过去了我的代码。

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;

行动: (所有操作都在名为 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);
    });
  };
}

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

登录按钮:
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;

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

和 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 个月的时间寻找解决方案而没有任何回应..

最佳答案

尝试从您的 reducer 中删除 .push() 函数,因为它正在改变操作。尝试使用 concat 或 spread 运算符。喜欢尝试更换

successValues.push(facebookAuthResult.accessToken);





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



它与不变性有关,您可以在 redux 教程中查看或在谷歌上找到(我现在无法解释这种行为)

关于react-native - react native redux fbsdk 登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42497976/

相关文章:

javascript - JavaScript 函数运行时显示消息

iphone - 使用 Facebook Connect 登录后如何返回 iPhone Web 应用程序?

javascript - 读取父状态的值并将 bool 值传递给子组件React

reactjs - React/Redux - 如何在 React 组件中显示 Redux 存储中的值?

ios - 如何在 React Native 中使用 UITableViewCellStyleSubtitle 获取原生 UITableView?

redux - 为什么 Redux 不将状态传递给订阅的函数?

javascript - 使用 redux 时出现 eslint 奇怪的错误

facebook-javascript-sdk - Facebook登录所需的CSP规则

ios - react native ListView 问题

javascript - 如何在 React Native 中的按钮函数上传递函数参数?