处理Firebase + Facebook登录流程

3

我在我的应用程序中使用了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块中,我基本上想说,在Facebook登录按钮被点击并通过Facebook授权后,如果用户有访问令牌,就直接进入应用程序。否则,前往注册屏幕,用户将在那里输入必要的信息。
我还在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凭据,我会被授权并直接进入应用程序,而不需要经过注册屏幕。这会引起各种问题。

对于那些使用Firebase的Facebook登录的人,有什么好的方法来处理这种情况?我需要涵盖以下几种情况:

  1. 如果一个新用户点击Facebook登录按钮,他们将被带到注册屏幕。
  2. 如果已注册(但已注销)的用户点击Facebook登录按钮,他们将直接进入应用程序。
  3. 如果已注册并且仍然登录的用户启动应用程序,他们将跳过登录屏幕,直接进入应用程序。

感谢任何帮助!


有点不清楚意图是什么;如果用户使用Facebook进行认证,那么他们就已经被认证了。您是想让他们使用Facebook进行身份验证,然后再进行单独的“注册”过程来访问应用程序数据吗? - Jay
是的!抱歉,重新阅读了您的问题后,我的回答不够清晰。新用户是指第一次注册我的应用程序的人。因此,当新用户在登录屏幕上点击Facebook按钮时,我需要显示注册屏幕。当已注册用户(已经使用Firebase进行授权的人)在登录屏幕上点击按钮(如果他们已经退出应用程序),他们应该直接进入应用程序,而不需要进入注册屏幕。最后,当已注册用户启动应用程序时,如果他们从未退出过,则应同时跳过登录和注册屏幕。 - KingTim
然而,如果我是第一次下载该应用程序的新用户,并且点击登录屏幕上的Facebook按钮,则会出现一个注册屏幕,在该屏幕上我需要输入一些关于自己的信息。 - KingTim
关于安全问题,我们假设任何拥有用户1手机的人都可以通过打开应用程序(如果用户1从未注销)或在登录屏幕上点击Facebook登录按钮(如果用户1已注销)来登录用户1的帐户。从技术上讲,这是一个安全问题,但老实说,这就是为什么人们在手机上设置指纹/密码访问的原因! - KingTim
是的,Tinder就是这样操作的。没有用户名/密码,只需点击Facebook按钮,如果你已注册,就会通过Facebook进行身份验证,然后回到你离开的地方。如果你是新用户,你将被带到设置屏幕。这就是我想要的。我同意在这种情况下注销相对无意义,然而这不是一个银行应用程序,也没有任何人处于任何真正的危险中,如果有人访问他们的帐户! - KingTim
显示剩余21条评论
1个回答

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
            }
        }

理想情况下,在设置页面之后,您必须将设置信息添加到FirebaseDatabase中的节点用户 -> uID。因此,请在此方法中检查是否存在任何此类节点。
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登录后->Firebase身份验证->Firdatabse节点检查->如果返回true->登录到应用程序

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

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


赢家!这似乎适用于所有用例。谢谢! - KingTim
很高兴能够帮到你! - Jen Jose

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接