【问题标题】:iOS Facebook SDK: FBSDKGraphRequest doesn't return email (Swift)iOS Facebook SDK:FBSDKGraphRequest 不返回电子邮件 (Swift)
【发布时间】:2017-11-16 23:54:36
【问题描述】:

我在这里看到过类似的问题,但似乎没有一个可以解决我的问题。

我目前正在创建一个使用 Facebook SDK 登录并返回用户信息的 iOS 应用。

我已成功登录 facebook 并收到请求的信息。但是,尽管允许电子邮件的读取权限,但请求并未返回电子邮件。

    /********************
    Place Facebook login button
    *********************/
    let loginButton = FBSDKLoginButton()
    view.addSubview(loginButton)
    loginButton.delegate = self
    loginButton.readPermissions = ["email", "public_profile"]
    //add button constraints
    loginButton.center = view.center



}

/**
* Functions called when user handed back from facebook login
**/
func loginButtonDidLogOut(_ loginButton: FBSDKLoginButton!) {
    print("Did log out of facebook")
}
/**
 * Functions called when user handed back from facebook login
 **/
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
    if error != nil {
        print(error)
    } else
    {
        print("Successfully logged in with facebook")
        FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "id, name, email"]).start
            { (connection, result, err) in
            if err != nil{
                print("Failed to start graph request: ", err)
                return
            }
            print(result)
        }
    }
}

【问题讨论】:

  • 电子邮件仅在用户已经确认并验证后才会返回。此外,在极少数情况下,即使用户授予了权限,隐私设置也会使其不返回电子邮件。如果您的应用绝对需要一封电子邮件,那么您应该实施一个额外的步骤,让用户手动输入它(当然验证也成为您的责任)......并不是每个用户都有电子邮件存档使用 Facebook,例如,如果他们仅使用手机注册。

标签: ios swift facebook facebook-sdk-4.0


【解决方案1】:

好吧,我对此思考了很长时间,然后发现了this link,这表明如果您没有确认的电子邮件地址,我将不会在我的代码的登录部分将其取回。

let request = GraphRequest(graphPath: "me", parameters: ["fields": "id, email, name, first_name, last_name, picture.type(large)"], accessToken: AccessToken.current, httpMethod: .GET, apiVersion: "2.12")
                request.start { (response, result) in
                    switch result {
                    case .success(let value):
                        print(value.dictionaryValue!)
                        self.responseJSON = JSON(value.dictionaryValue!)
                        let fullName = self.responseJSON["first_name"].stringValue
                        let firstName = self.responseJSON["first_name"].stringValue
                        let lastName = self.responseJSON["last_name"].stringValue
                        let email = self.responseJSON["email"].stringValue
                        let idFb = self.responseJSON["id"].stringValue
                        let picture = self.responseJSON["picture"]["data"]["url"].stringValue

                        print("user id: \(idFb), firstName: \(firstName), fullname: \(fullName), lastname: \(lastName), picture: \(picture), email: \(email)")

                    print("ALL FIELDS PUBLISHED")


                    if let delegate = self.responseDelegate {
                        delegate.responseUpdated(self.responseJSON, forLogin: "FB")
                    }

                case .failed(let error):
                    print(error)
                }
            }
        }

因此,当我找到它并确认我的电子邮件地址时,它给了我回复电子邮件。这是一些附加的快照。

这就是我得到它的方式。后来我实现了,如果电子邮件没有被退回,我会显示一个警报,提醒用户没有与该 Facebook 帐户关联的电子邮件,他们要么确认他们的电子邮件,要么在 TextField Alert 中提供一个单独的电子邮件地址。就是这样。

【讨论】:

  • 按照您的指示,对我来说同样的问题,我挣扎了 2.3 小时,+1
  • @AbuzarManzoor 很高兴我能帮上忙 :)
【解决方案2】:
 import FBSDKCoreKit
        import FBSDKLoginKit
        import FBSDKShareKit


      @IBAction func btnFbPressed(_ sender: Any) {

            let loginManager = FBSDKLoginManager()

            loginManager.logIn(withReadPermissions: ["public_profile", "email"], from: self) { (loginResult, error) in

                if error != nil {
                    print(error!)

                }
                else {

                    if (loginResult?.grantedPermissions.contains("email"))! {
                        self.getFBUserData()
                    }

                }
            }


        }




        func getFBUserData(){
            if((FBSDKAccessToken.current()) != nil){

                UserDefaults.standard.set(FBSDKAccessToken.current().tokenString, forKey: "fbToken")

                FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).start(completionHandler: { (connection, result, error) -> Void in
                    if (error == nil) {

                        print(result as Any)

                        let dictionary = result as! NSDictionary
                        print(dictionary)

                        let hud = MBProgressHUD.showAdded(to: self.view, animated: true)
                        hud.tintColor = .black
                        hud.mode = .indeterminate
                        hud.label.text = "Loading"
                        hud.animationType = .fade
                        hud.show(animated: true)

                        let postString = String(format: "login_type=facebook&email=%@&id=%@&device=0", arguments: [dictionary.value(forKey: "email") as! String, dictionary.value(forKey: "id") as! String])
     }
                })
            }
        }

【讨论】:

    【解决方案3】:

    您无法根据Facebook Graph API tool 从 FBSDKGraphRequest 获取用户电子邮件。 Facebook 只返回用于登录的令牌。如果您在 Firebase 中使用 Facebook 登录,您可以使用 CurrentUser.currentEmail 方法获取电子邮件。

     let login = FBSDKLoginManager()
    
        login.logIn(withReadPermissions: ["email","user_posts","public_profile"], from: self, handler: {
            (result: FBSDKLoginManagerLoginResult?, error: Error?) in
            if error != nil {
                print("Process error")
                return
            }
            else if (result?.isCancelled)! {
                print("Cancelled")
            }
            else {
                //Success!
                let credential = FIRFacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString)
                self.firebaseLogin(credential)
            }
        })
    

    【讨论】:

    • 好的,谢谢。我看到用户注册时 Firebase 不存储任何电子邮件地址。我会想办法解决这个问题。再次感谢
    • 对,在 Swift 2 和较旧的 Firebase + Facebook SDK 中,上述方法是允许的,但现在您可以只写 'FIRAuth.auth()?.currentUser?.email'
    猜你喜欢
    • 2013-08-25
    • 1970-01-01
    • 1970-01-01
    • 2017-09-29
    • 1970-01-01
    • 2015-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多