我试图让FB SDK与iOS上的React-Native应用程序一起使用,但是我遇到了错误: React-Native – 无法读取未定义的属性’logInWithReadPermissions’ 点击按钮. 我已经按照这些说明操作了: 1. npm instal
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" />
LoginButton:
'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;我使用过 react-native-fbsdk并且它有效.这个模块有;
readPermissions = {["email","user_birthday"]}
您可能需要查看组件的读取权限.