React Native FB SDK 处理身份验证拒绝

React Native FB SDK handle authentication reject

我需要在 react-native 中处理 Facebook 登录错误。

我的应用程序全新安装后尝试登录时向用户显示弹出窗口:

"Facebook. Application would like to access your basic profile info and list of friends."

有两个选项:"Don't Allow" 和 "OK"。在正常流程中,我得到了一个合适的令牌。但是,如果用户在 onLoginFinished 中拒绝,我会得到以下结果:

{
  "isCancelled": true,
  "grantedPermissions": null,
  "declinedPermissions": null
}

没有关于取消原因的信息。拒绝是获得 "isCancelled": true'system_account' 的唯一原因吗?

之后,所有使用 'system_account' 登录的连续尝试立即失败,并出现以下错误:

{
  "code": "FacebookSDK",
  "domain": "com.facebook.sdk.login",
  "framesToPop": 1,
  "nativeStackIOS": [...],
  "userInfo": {
    "NSLocalizedDescription": "Access has not been granted to the Facebook account. Verify device settings.",
    "com.facebook.sdk:FBSDKErrorLocalizedDescriptionKey": "Access has not been granted to the Facebook account. Verify device settings."
  }
}

它给了我可以向用户显示的错误,但由于本地化,我无法可靠地解析它。所以问题是我如何才能可靠地检测到用户何时未授予权限?

我的代码:

import React from 'react'
import {AccessToken, LoginManager} from 'react-native-fbsdk'

class Login extends React.Component {
    login = ()=>{
        LoginManager.setLoginBehavior('system_account')
        LoginManager.logInWithReadPermissions()
            .then(this.onLoginFinished)
            .catch(this.onLoginError)
    }
    onLoginFinished = (result)=>{
        if(result.isCancelled) {
            //
        } else {
            AccessToken.getCurrentAccessToken().then((data)=>{
                this.props.onLogin(data.accessToken.toString())
            })
        }
    }
    onLoginError = (error)=>{
        // Want to handle this case but 
        //can only show a message to the user =(
    }
    render() {
        return (
            <View>
                <TouchableHighlight onPress={this.login}>
                    <View><Text>Facebook</Text></View>
                </TouchableHighlight>
            </View>
        )
    }
}

据我所知,我只能在收到 'system_account' 取消后切换到 'native' 登录行为并单独处理其行为,这是唯一的方法吗?

使用 Facebook 登录时,有几种情况需要处理。

  1. 用户授予所有权限并登录
  2. 用户授予了一些权限并登录
  3. 用户未授予任何权限并已登录
  4. 用户取消登录尝试

如果你检查 LoginManager.logInWithReadPermissions it uses native code (for iOS) FBSDKLoginManagerLoginResult from iOS SDK. In documentation of iOS SDK isCancelled 是一个 BOOL 显示 "Whether the login was cancelled by the user."

所以如果你返回的结果中isCanceled为真,说明用户手动取消了登录请求。这可能是因为用户改变了 his/her 的想法或误按了按钮,或者只是因为当 he/she 看到您请求的权限列表时他改变了 his/her 的想法等等。当您检查并看到 isCanceled 值为 true 然后你可以假设用户不想使用 facebook 登录,你可以像这样继续 ( 重定向到另一个登录方法或显示用户应该登录的弹出窗口等).

如果用户完成 facebook 登录但未选中某些权限请求(如生日或喜欢等),权限将显示在 declinedPermissions 中。您可以检查此 属性 的 lenght 并根据需要进行处理。您可以创建一个对象,其中包含在任何权限被拒绝时需要显示的所有错误消息。

例子

const permissions = [
  {
    permissionName: 'user_likes',
    errorMessage: 'To give you better results we need your likes'
  },
  {
    permissionName: 'user_birthday',
    errorMessage: 'Would you like to receive a gift from us on your birthday?'
  },
  {
    permissionName: 'user_friends',
    errorMessage: 'We can\'t match you without knowing your friends'
  }
];



// ....
login = ()=>{
    LoginManager.setLoginBehavior('system_account')
    LoginManager.logInWithReadPermissions(permissions.map((permission) => (permission.permissionName)))
        .then(this.onLoginFinished)
        .catch(this.onLoginError)
}

onLoginFinished = (result)=>{
    if(result.isCancelled) {
        // user canceled login manually
    } else {
        if (result.declinedPermissions && result.declinedPermissions.lenght > 0) {
          // handle declined permissions
          result.declinedPermissions.forEach((declinedPermission) => {
            // match the declinedPermission with the permission object
          }
        } else {
          // user gave all the permissions
        }
        AccessToken.getCurrentAccessToken().then((data)=>{
            this.props.onLogin(data.accessToken.toString())
        })
    }
}