5

iOS の React-Native アプリで FB SDK を動作させようとしていますが、次のエラーが発生します。

React-Native - 未定義のプロパティ 'logInWithReadPermissions' を読み取ることができません

ボタンクリック時。

私はすでにこれらの指示に従いました:

1. npm install rnpm -g
2. rnpm link react-native-fbsdk
3. remove the following lines from subspecs in ios/PodFile
'Core',
'Login',
'Share',
4. pod install
5. go to https://developers.facebook.com/docs/ios/getting-started, download FB ios SDK, and unzip to ~/Documents/FacebookSDK
6. open F8v2.xcworkspac with xcode, and drag Bolts.framework,FBSDKCoreKit.framework, FBSDKLoginKit.framework, FBSDKShareKit.framework in ~/Documents/FacebookSDK to Frameworks under F8V2 project. 
7. run react-native run-ios .It should work now. If have build issue, drag the three FB...Kit.framework to RCTFBSDK.xcodeproj too.

運がない。

コンポーネント フローは次のようになります。

(ボタン)

<LoginButton source="First screen" />

ログインボタン:

'use strict';

const React = require('react');
const {StyleSheet} = require('react-native');
const F8Button = require('F8Button');

const { logInWithFacebook } = require('../actions');
const {connect} = require('react-redux');

class LoginButton extends React.Component {
  props: {
    style: any;
    source?: string; // For Analytics
    dispatch: (action: any) => Promise;
    onLoggedIn: ?() => void;
  };
  state: {
    isLoading: boolean;
  };
  _isMounted: boolean;

  constructor() {
    super();
    this.state = { isLoading: false };
  }

  componentDidMount() {
    this._isMounted = true;
  }

  componentWillUnmount() {
    this._isMounted = false;
  }

  render() {
    if (this.state.isLoading) {
      return (
        <F8Button
          style={[styles.button, this.props.style]}
          caption="Please wait..."
          onPress={() => {}}
        />
      );
    }

    return (
      <F8Button
        style={[styles.button, this.props.style]}
        icon={require('../login/img/f-logo.png')}
        caption="Log in with Facebook"
        onPress={() => this.logIn()}
      />
    );
  }

  async logIn() {
    const {dispatch, onLoggedIn} = this.props;

    this.setState({isLoading: true});
    try {
      await Promise.race([
        dispatch(logInWithFacebook(this.props.source)),
        timeout(15000),
      ]);
    } catch (e) {
      const message = e.message || e;
      if (message !== 'Timed out' && message !== 'Canceled by user') {
        alert(message);
        console.warn(e);
      }
      return;
    } finally {
      this._isMounted && this.setState({isLoading: false});
    }

    onLoggedIn && onLoggedIn();
  }
}

async function timeout(ms: number): Promise {
  return new Promise((resolve, reject) => {
    setTimeout(() => reject(new Error('Timed out')), ms);
  });
}

var styles = StyleSheet.create({
  button: {
    alignSelf: 'center',
    width: 270,
  },
});

module.exports = connect()(LoginButton);

FacebookSDK.js:

'use strict';

var {
  LoginManager,
  AccessToken,
  GraphRequest,
  GraphRequestManager,
} = require('react-native-fbsdk');

const emptyFunction = () => {};
const mapObject = require('fbjs/lib/mapObject');

type AuthResponse = {
  userID: string;
  accessToken: string;
  expiresIn: number;
};
type LoginOptions = { scope: string };
type LoginCallback = (result: {authResponse?: AuthResponse, error?: Error}) => void;

let _authResponse: ?AuthResponse = null;

async function loginWithFacebookSDK(options: LoginOptions): Promise<AuthResponse> {
  const scope = options.scope || 'public_profile';
  const permissions = scope.split(',');

  const loginResult = await LoginManager.logInWithReadPermissions(permissions);
  if (loginResult.isCancelled) {
    throw new Error('Canceled by user');
  }

  const accessToken = await AccessToken.getCurrentAccessToken();
  if (!accessToken) {
    throw new Error('No access token');
  }

  _authResponse = {
    userID: accessToken.userID, // FIXME: RNFBSDK bug: userId -> userID
    accessToken: accessToken.accessToken,
    expiresIn: Math.round((accessToken.expirationTime - Date.now()) / 1000),
  };
  return _authResponse;
}

var FacebookSDK = {
  init() {
    // This is needed by Parse
    window.FB = FacebookSDK;
  },

  login(callback: LoginCallback, options: LoginOptions) {
    loginWithFacebookSDK(options).then(
      (authResponse) => callback({authResponse}),
      (error) => callback({error})
    );
  },

  getAuthResponse(): ?AuthResponse {
    return _authResponse;
  },

  logout() {
    LoginManager.logOut();
  },

  /**
   * Make a API call to Graph server. This is the **real** RESTful API.
   *
   * Except the path, all arguments to this function are optional. So any of
   * these are valid:
   *
   *   FB.api('/me') // throw away the response
   *   FB.api('/me', function(r) { console.log(r) })
   *   FB.api('/me', { fields: 'email' }); // throw away response
   *   FB.api('/me', { fields: 'email' }, function(r) { console.log(r) });
   *   FB.api('/12345678', 'delete', function(r) { console.log(r) });
   *   FB.api(
   *     '/me/feed',
   *     'post',
   *     { body: 'hi there' },
   *     function(r) { console.log(r) }
   *   );
   *
   * param path   {String}   the url path
   * param method {String}   the http method
   * param params {Object}   the parameters for the query
   * param cb     {Function} the callback function to handle the response
   */
  api: function(path: string, ...args: Array<mixed>) {
    const argByType = {};
    args.forEach((arg) => { argByType[typeof arg] = arg; });

    const httpMethod = (argByType['string'] || 'get').toUpperCase();
    const params = argByType['object'] || {};
    const callback = argByType['function'] || emptyFunction;

    // FIXME: Move this into RNFBSDK
    // GraphRequest requires all parameters to be in {string: 'abc'}
    // or {uri: 'xyz'} format
    const parameters = mapObject(params, (value) => ({string: value}));

    function processResponse(error, result) {
      // FIXME: RNFBSDK bug: result is Object on iOS and string on Android
      if (!error && typeof result === 'string') {
        try {
          result = JSON.parse(result);
        } catch (e) {
          error = e;
        }
      }

      const data = error ? {error} : result;
      callback(data);
    }

    const request = new GraphRequest(path, {parameters, httpMethod}, processResponse);
    new GraphRequestManager().addRequest(request).start();
  }
};

module.exports = FacebookSDK;
4

2 に答える 2

0

私はreact-native-fbsdkを使用しましたが、動作します。このモジュールには次のものがあります。

readPermissions = {["email","user_birthday"]}

コンポーネントの読み取り権限を確認する必要がある場合があります。

于 2016-10-12T09:02:25.410 に答える