Facebook 登录“异常抛出”错误通过 iOS 上的 React Native

Posted

技术标签:

【中文标题】Facebook 登录“异常抛出”错误通过 iOS 上的 React Native【英文标题】:Facebook Login "Exception throw" Error via React Native on iOS 【发布时间】:2015-12-06 13:15:17 【问题描述】:

我已尝试 5 倍以在我的 react 本机应用程序上登录 Facebook,但似乎已弃用以下方法:

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

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

https://github.com/magus/react-native-facebook-login

错误如下所示:

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

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

我的 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, 
    , 
);

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

【问题讨论】:

【参考方案1】:

React Team 已经为 Facebook 提供了一个包装器

https://github.com/facebook/react-native-fbsdk

在https://github.com/facebook/react-native-fbsdk/blob/master/README.md#installation运行安装

也可以通过https://github.com/facebook/react-native-fbsdk/tree/master/Sample获取样本

【讨论】:

以上是关于Facebook 登录“异常抛出”错误通过 iOS 上的 React Native的主要内容,如果未能解决你的问题,请参考以下文章

Firebase iOS Facebook 简单登录错误

Java:如何获取错误信息?

iOS 8.3 Facebook 错误未登录

iOS Facebook 登录 - 链接器错误

iOS 6 facebook sdk 3.1.1 登录错误

Facebook登录按钮引发错误并说我无法登录