ios - 处理 Firebase + Facebook 登录流程

标签 ios swift facebook firebase firebase-authentication

我的应用程序中有 Facebook 登录,我一直在兜圈子,试图在需要通过注册屏幕的新用户和应该直接进入应用程序的注册用户之间取得平衡。这是处理 Facebook 登录的函数(当点击按钮并且 Facebook 授权时):

func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
    if error != nil {
        return
    }
    FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "name"]).start { (connection, result, err) in

        let accessToken = FBSDKAccessToken.current()
        guard let accessTokenString = accessToken?.tokenString else {return}
        let credentials = FIRFacebookAuthProvider.credential(withAccessToken: accessTokenString)

        FIRAuth.auth()?.signIn(with: credentials, completion: { (user, error) in

            if error != nil {
                return
            }
            if(FBSDKAccessToken.current() != nil){
                // logged in
                self.performSegue(withIdentifier: "loginToRooms", sender: nil)
            }else{
                // not logged in
                self.performSegue(withIdentifier: "showSetupScreen", sender: nil)
            }
        })

        if err != nil {
            return
        }
    }
}

在上面的 FIRAuth.auth block 中,我基本上是说一旦点击 Facebook 登录按钮并通过 Facebook 授权,如果用户有访问 token ,直接进入应用程序。否则,转到注册屏幕,用户将在其中输入必要的信息。

我在 viewDidLoad 中也有这个,所以当应用启动时,如果用户之前登录过,他们甚至不会看到登录屏幕,他们会直接进入应用:

    // When app is launched, bring user straight in if they're already authorized. Otherwise show the login screen.
    FIRAuth.auth()?.addStateDidChangeListener { auth, user in
        if let user = user {
            // User is signed in. Show home screen
            self.performSegue(withIdentifier: "loginToRooms", sender: nil)
        } else {
            // No User is signed in. Show user the login screen
            return
        }
    }

但是我在测试过程中发现,如果我点击 Facebook 登录并以新用户身份输入 Facebook 凭据,我将获得授权,然后直接进入应用程序,而无需通过注册屏幕。这会导致各种问题。

对于使用 Facebook 登录和 Firebase 的人来说,处理这种情况的好方法是什么?我需要介绍几个场景:

  1. 如果新用户点击 Facebook 登录按钮,他们将被带到注册屏幕。
  2. 如果已注册(但已注销)的用户点击 Facebook 登录按钮,他们将直接进入该应用。
  3. 如果已注册但仍处于登录状态的用户启动该应用,他们将绕过登录屏幕并直接进入该应用。

感谢您的帮助!

最佳答案

当用户点击 FB 登录按钮时:

->做原生FB登录。 (就像你现在正在做的那样)

-> 进行 Firebase 身份验证。

-> 但另外,检查数据是否存在于 FirDatabase 中

      FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "name"]).start { (connection, result, err) in

            let accessToken = FBSDKAccessToken.current()
            guard let accessTokenString = accessToken?.tokenString else {return}
            let credentials = FIRFacebookAuthProvider.credential(withAccessToken: accessTokenString)

            FIRAuth.auth()?.signIn(with: credentials, completion: { (user, error) in

                if error != nil {
                    return
                }

                self.checkDataExistsinfirDataBaaseForUID(user.uid){
                  loginStaus in
                  if(loginStaus){
                        // logged in
                    self.performSegue(withIdentifier: "loginToRooms", sender: nil)
                   }else{
                        // not logged in
                    self.performSegue(withIdentifier: "showSetupScreen", sender: nil)
                   }
}

            })

            if err != nil {
                return
            }
        }

理想情况下,在设置页面之后,您必须在节点用户 -> uID 下的 FirebaseDatabase 中添加设置信息。因此,请检查此方法中是否存在任何此类节点。

func checkDataExistsinfirDataBaaseForUID(_ uid: String, completion: (result: Bool) -> Void) {
 let ref = FIRDatabase.database().reference().child("users").child(uid)

    ref.observeSingleEventOfType(.Value, withBlock: { (snapshot) in
        completion(snapshot.exists())
     })
}

测试用例:

  1. 如果新用户点击登录屏幕上的 FB 登录按钮,他们将被带到设置屏幕。

已完成。

  1. 如果现有但已注销的用户点击 FB 登录按钮,他们将绕过设置屏幕并转到应用程序的第一页。

fb登录后->firbase认证->Firdatabse节点校验->if返回true->登录app

  1. 如果现有用户注册后永远不会注销,他们将永远不会再看到登录或注册屏幕。

通过使用您的 cehcking 过程,FIRAuth.auth()?.addStateDidChangeListener {}

关于ios - 处理 Firebase + Facebook 登录流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44184770/

相关文章:

java - 安卓 Facebook "Unable to get provider"java.lang.ClassNotFoundException

android - Facebook Android SDK - 使用 UiLifecycleHelper 时,我应该使用 Activity 还是 Application 作为上下文?

ios - iPad 和 iPhone 的不同 UI

ios - 使用 Parse 作为后端在 Xcode 6 中使用 Swift 创建注册

swift +终端

swift - Swift 中的 var 和 weak var 有什么区别

c# - 在 Xamarin.iOS 中隐藏和显示控件

ios - 一个 View 中的多个 TableView

ios - 如何在 Swift 上将 HTML 代码加载到 WebView

Facebook Connect - 图形 API 与旧 JavaScript SDK(操作链接)