检查来自苹果登录的电子邮件是否在Firebase中注册

3

我的应用程序中,用户可以使用Apple登录。创建帐户很好(使用Firebase)。但是,在用户实际登录之前,我想检查用户是否已经注册。为此,我需要电子邮件地址。问题在于,由于出现found nil错误,我无法正确地访问电子邮件。

这是我的函数 ,用于处理检查/登录

// delegate functions
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
  if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
    guard let nonce = currentNonce else {
      fatalError("Invalid state: A login callback was received, but no login request was sent.")
    }
    guard let appleIDToken = appleIDCredential.identityToken else {
      print("Unable to fetch identity token")
      return
    }
    guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else {
      print("Unable to serialize token string from data: \(appleIDToken.debugDescription)")
      return
    }

    let credential = OAuthProvider.credential(withProviderID: "apple.com", idToken: idTokenString, rawNonce: nonce)
    print("email: " + appleIDCredential.email!)
    let email = appleIDCredential.email

    Auth.auth().fetchSignInMethods(forEmail: email!) { (methods, error) in

         if error != nil {
            // show error popUp
             Utilities.showErrorPopUp(labelContent: "Fehler", description: error!.localizedDescription)
         } else {
             // no error -> check email adress

             // Email is not registered -> sign up
             if methods == nil {

                 print("signed in")
                 let usernameVC = self.storyboard?.instantiateViewController(withIdentifier: "UsernameVC") as! UserNameVC
                 usernameVC.credential = credential
                 usernameVC.signInOption = "apple"
                 self.navigationController?.pushViewController(usernameVC, animated: true)

             }
             // Email is registered -> login
             else {

                Auth.auth().signIn(with: credential, completion: { (user, error) in
                    if error != nil {
                        Utilities.showErrorPopUp(labelContent: "Fehler beim Login", description: error!.localizedDescription)
                    } else {

                        // set user status to logged-in
                        UserDefaults.standard.setIsLoggedIn(value: true)
                        UserDefaults.standard.synchronize()

                        // stop animation
                        self.logoAnimation.stop()

                        //transition to home
                        self.transitionToHome()
                    }
                })
             }
         }
    }
  }
}

就像我所说的,如果用户已经登录,这个不起作用,它只在用户第一次注册时起作用,否则好像无法获取电子邮件。

有人知道解决此问题的变通方法或任何内容吗?

3个回答

4

如果您无法访问凭据中的电子邮件属性,这意味着用户之前已经使用他的Apple ID在应用程序中登录过了。因此,您可以决定该用户是否已经在此应用程序中注册:

// .....

guard let email = appleIDCredential.email else {
    // User already signed in with this appleId once
    Auth.auth().signIn(with: credential, completion: { (user, error) in
        // .......
    })
    return
}

Auth.auth().fetchSignInMethods(forEmail: email) { (methods, error) in
    // .......
})

谢谢!这解决了一半的问题。但是还存在一个问题,因为如果用户在下一个视图控制器内没有创建用户名,则我的SignUpProcess 将无法完成。通过您提供的解决方案,如果用户使用苹果登录,但取消了用户名进程(例如重新启动应用程序),他仍然可以登录。如何检查用户是否真正创建成功呢? - Chris
希望你能理解我的问题:D 如有疑问请随时提出。 - Chris
我想我解决了它。我会快速测试一下,但你绝对赢得了那个悬赏!谢谢,伙计! - Chris
@Chris,用户通过SignsInWithApple之后,您可以将电子邮件和姓名缓存到UserDefaults中,并在下一个ViewController上恢复它。 - Nikita
你可以查看我的答案,看我最终是如何完成它的。再次感谢你的帮助 :) - Chris

1

在 @Nikita 的帮助下,我终于让它工作了。正如所建议的那样,我首先检查是否可以访问 email。我的最终function如下:

let credential = OAuthProvider.credential(withProviderID: "apple.com", idToken: idTokenString, rawNonce: nonce)

    guard appleIDCredential.email != nil else {
        // User already signed in with this appleId once
        Auth.auth().signIn(with: credential, completion: { (user, error) in

            DataHandler.checkIfAppleUserExists(uid: (user?.user.uid)!) { (exists) in
                if exists { // user has firebase-profile -> login
                    if error != nil {
                        Utilities.showErrorPopUp(labelContent: "Fehler beim Login", description: error!.localizedDescription)
                    } else {

                        UserDefaults.standard.setIsLoggedIn(value: true)
                        UserDefaults.standard.synchronize()

                        self.logoAnimation.stop()

                        self.transitionToHome()
                    }
                } else { // user doesn't have firebase-profile -> create username
                    let usernameVC = self.storyboard?.instantiateViewController(withIdentifier: "UsernameVC") as! UserNameVC
                    usernameVC.credential = credential
                    usernameVC.signInOption = "appleExists"
                    self.navigationController?.pushViewController(usernameVC, animated: true)
                }
            }

        })
        return
    }

    // first time apple sign in
    let usernameVC = self.storyboard?.instantiateViewController(withIdentifier: "UsernameVC") as! UserNameVC
    usernameVC.credential = credential
    usernameVC.signInOption = "apple"
    self.navigationController?.pushViewController(usernameVC, animated: true)
  }

我还实现了辅助函数checkIfAppleUserExists,用于检查用户是否实际在Firebase中创建。如果是,则用户登录,否则进入UsernameVC,其中创建Firebase配置文件。


-1
如果您想检查用户是否已经登录,可以像这样进行检查:
import FirebaseAuth

if Auth.auth().currentUser != nil {
// the user is signed in
} else {
// the user in not signed in
}

抱歉,也许我在问题上表述不清楚:我想检查用户是否已经注册。 - Chris

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