ios - 在 iOS 上通过 React Native 登录 Facebook 时出现 "Exception throw"错误

标签 ios facebook react-native

我已尝试 5 次在我的 React Native 应用程序上登录 Facebook,但似乎以下方法已被弃用:

- http://brentvatne.ca/facebook-login-with-react-native/

鉴于 Facebook 不再使用“logInWithReadPermissions:”。当我使用以下似乎是最新的方法(如下所示)时,我突然收到“抛出异常”错误:

错误如下所示:

Exception thrown while invoking login on target RCTFBLoginManager with params (
    7
): App ID not found. Add a string value with your app ID for the key FacebookAppID to the Info.plist or call [FBSDKSettings setAppID:].reactConsoleError @ ExceptionsManager.js:78console.error @ YellowBox.js:49logIfNoNativeHook @ RCTLog.js:36messageHandlers.executeJSCall @ debuggerWorker.js:25onmessage @ debuggerWorker.js:42

或者这个(作为模拟器):

enter image description here

我的 info.plist 文件看起来像这样(敏感 ID 被删除 - 即 ####):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>en</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
    <key>NSLocationWhenInUseUsageDescription</key>
    <string></string>
    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    <key>UIRequiredDeviceCapabilities</key>
    <array>
        <string>armv7</string>
    </array>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UIViewControllerBasedStatusBarAppearance</key>
    <false/>
    <key>CFBundleURLTypes</key>
    <array>
      <dict>
        <key>CFBundleURLSchemes</key>
        <array>
          <string>fb############</string>
        </array>
      </dict>
    </array>
    <key>FacebookAppID</key>
    <string>#############</string>
    <key>FacebookDisplayName</key>
    <string>blaclist</string>
    <key>NSAppTransportSecurity</key>
    <dict>
      <key>NSExceptionDomains</key>
      <dict>
        <key>facebook.com</key>
        <dict>
          <key>NSIncludesSubdomains</key> <true/>        
          <key>NSThirdPartyExceptionRequiresForwardSecrecy</key> <false/>
        </dict>
        <key>fbcdn.net</key>
        <dict>
          <key>NSIncludesSubdomains</key> <true/>
          <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>  <false/>
        </dict>
        <key>akamaihd.net</key>
        <dict>
          <key>NSIncludesSubdomains</key> <true/>
          <key>NSThirdPartyExceptionRequiresForwardSecrecy</key> <false/>
        </dict>
      </dict>
    </dict>
    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>fbapi</string>
        <string>fb-messenger-api</string>
        <string>fbauth2</string>
        <string>fbshareextension</string>
    </array>
</dict>
</plist>

尝试使用该模块通过 facebook 注册用户的文件如下:

//component that opens up app to signup screen
var React = require('react-native');
var {
    View, 
    Text, 
    StyleSheet,
    Image,  
    TextInput,
} = React;

//additional libraries
var Parse = require('parse/react-native');
var FBLoginManager = require('NativeModules').FBLoginManager;

//dimensions
var Dimensions = require('Dimensions');
var window = Dimensions.get('window');

//dynamic variable components
var ImageButton = require('../common/imageButton');

module.exports = React.createClass({
    propTypes: {
        style: View.propTypes.style,
        onPress: React.PropTypes.func,
        onLogin: React.PropTypes.func,
        onLogout: React.PropTypes.func,
    },
    getInitialState: function() {
        return {
            username: '', 
            password: '', 
            errorMessage: '',
            passwordConfirmation: '',
            result: '...',
        };
    },
    componentWillMount: function(){
        var _this = this;
        FBLoginManager.getCredentials(function(error, data){
          if (!error) {
            _this.setState({ user : data})
          }
        });
    },
    render: function() {
        return (
            <View style={[styles.container]}>
                <Image 
                    style={styles.bg} 
                    source={require('./img/login_bg1_3x.png')}>
                    <View style={[styles.header, this.border('red')]} >
                        <View style={styles.headerWrapper} >
                            <Image 
                                style={[styles.login_brand]}
                                resizeMode={"contain"}
                                source={require('./img/signup_brand.png')} />
                            <ImageButton
                                style={[styles.fb_btn]}
                                resizeMode={'contain'}
                                onPress={this.onFbSignupPress}
                                source={require('./img/fb_signup_btn.png')} />
                            <Image 
                                style={[styles.loginBar]}
                                style={[styles.loginBar]} 
                                resizeMode={'contain'}
                                source={require('./img/login_bar_3x.png')} />
                        </View>
                    </View>
                    <View style={[styles.footer, this.border('blue')]} >
                        <View style={styles.footerWrapper} >
                            <TextInput 
                                placeholder={'Email'}
                                style={styles.input} 
                                value={this.state.username}
                                onChangeText={(text) => this.setState({username: text})} />
                            <TextInput 
                                placeholder={'Password'}
                                secureTextEntry={true} 
                                style={styles.input} 
                                value={this.state.password}
                                onChangeText={(text) => this.setState({password: text})} />
                            <TextInput 
                                placeholder={'Confirm Password'}
                                secureTextEntry={true} 
                                style={styles.input} 
                                value={this.state.confirmPassword}
                                onChangeText={(text) => this.setState({passwordConfirmation: text})} />
                            <ImageButton
                                style={[styles.email_btn]}
                                resizeMode={'contain'}
                                onPress={this.onCreateAcctPress}
                                source={require('./img/get_started_btn.png')} />
                            <ImageButton
                                style={[styles.email_btn]}
                                resizeMode={'contain'}
                                onPress={this.onAlreadyAcctPress}
                                source={require('./img/already_acct_btn.png')} />
                        </View>
                    </View>
                </Image>
            </View>
        );
    }, 
    onFbSignupPress: function() {
        //sign up via facebook and store credentials into parse
        var _this = this;
        FBLoginManager.login(function(error, data){
          if (!error) {
            _this.setState({ result : data});
            console.log(data);
            _this.props.onLogin && _this.props.onLogin();
          } else {
            console.log(error, data);
          }
        });
    },
    onCreateAcctPress: function() {
        if (this.state.password === this.state.passwordConfirmation)
        {   
            var user = new Parse.User();
                user.set("username", this.state.username);
                user.set("password", this.state.password);
                user.set("email", this.state.username);

                user.signUp(null, {
                  //navigate to new component (.immediatelyResetRouteStack)
                  //when doing so and we pass new views of app (routes)
                  success: (user) => { this.props.navigator.immediatelyResetRouteStack([{ name: 'home'}]); },
                  error: (user, error) => { this.setState({ errorMessage: error.message }); }
            });
        } else {
            this.setState({ errorMessage: "Your passwords are not the same!"});
        }
    },
    onAlreadyAcctPress: function() {
        this.props.navigator.pop();
    },
     //function that helps with laying out flexbox itmes 
     //takes a color argument to construct border, this is an additional 
     //style because we dont want to mess up our real styling 
     border: function(color) {
        return {
          //borderColor: color, 
          //borderWidth: 4,
        } 
     },
});

var styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'stretch',
    },
    bg: {
        flex: 1,
        width: window.width, 
        height: window.height, 
    },
    header: {
        flex: 2,
    }, 
    headerWrapper: {
        flex: 1, 
        flexDirection: 'column', 
        alignItems: 'center',
        justifyContent:'space-around',
        marginTop: window.height/35,
    }, 
    footerWrapper: {
        flexDirection: 'column', 
        alignItems: 'center',
        justifyContent:'space-around',
        marginTop: 15, 
    }, 
    footer: {
        flex: 4, 
    }, 
    loginBar: {
        width: (window.width/1.3)/1.8, 
        height: (70/553)*((window.width/1.3)/1.8),
    }, 
    fb_btn: {
        width: window.width/1.3,
        height: (147/1095)*window.width/1.3,
        margin: 10, 
    }, 
    login_brand: {
        width: window.width/5,
        height: (268/273)*window.width/5,
        margin: 6,
    },
    input: {
        padding: 4, //gives us offset to border 
        height: window.height/20, 
        backgroundColor: 'rgba(255,255,255, 0.4)', 
        borderColor: 'gray', 
        borderWidth: 1, 
        borderRadius: 2, //round input box
        margin: 2, 
        width: window.width/1.3,
        alignSelf: 'center', //center yourself on form when you have fixed widths 
    }, 
    email_btn: {
        width: window.width/1.3,
        height: (147/1095)*window.width/1.3,
        margin: 3, 
    }, 
});

我是这方面的新手,所以请理解我可能犯的任何简单错误。不过,我会非常彻底地检查我的工作,并在提出任何问题之前尝试几个小时。再次感谢!

最佳答案

关于ios - 在 iOS 上通过 React Native 登录 Facebook 时出现 "Exception throw"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34117806/

相关文章:

ios - 在 Swift 中以编程方式定位(Twitter Digits 的)按钮

apache-flex - 为什么 Facebook Actionscript API init() 不起作用?

facebook - 带有自定义图标的社交分享链接

javascript - 为什么 React Redux 中的 props 没有被映射状态更改为 props

javascript - 从无状态子组件更改父组件的状态

iphone - 是否可以为同一个应用程序在 2 个不同的地区/国家提交 2 个版本

ios - 在模拟器中单击按钮会导致应用程序崩溃

objective-c - 在表格 View 中显示特定大小的两个部分

facebook - 如何在 https 下获取 facebook 头像?

android - React Native MabBox MarkerView 问题