我已经在Stackoverflow上阅读了一些很好的问题/答案 . 但是我仍然在努力让这个工作起来 . 因此,经过4个小时的尝试,我不得不在同一主题上发布另一个问题 .
其他好的QAs:
How to correctly link different Auth accounts in Firebase IOS
Firebase authentication: linking multiple accounts in Swift
也试过按照firebase文档尝试失败:https://firebase.google.com/docs/auth/ios/account-linking
所以基本上我已经设法登录电子邮件和密码和Facebook工作(尚未谷歌) . 不过我的问题是链接这些帐户 .
我基本上创建了一个电子邮件和密码帐户 . 当尝试使用Facebook登录时,我收到的错误是已存在已发送电子邮件的用户 .
我理解这样的逻辑:
-
用户选择提供商登录(例如Facebook)
-
执行代码,直到收到提供者的凭据
-
尝试将帐户与现有的电子邮件和密码帐户相关联,而不是像往常一样登录Firebase
-
(如果nr.3失败,请不要链接帐户,而是使用提供商凭据(例如Facebook)将用户登录到Firebase
-
(如果成功)返回已成功进行链接 .
下面是我对代码的实现......但它通过了一些错误 .
import UIKit
import Firebase
import FacebookCore
import FacebookLogin
class loginVC: UIViewController {
@IBOutlet weak var emailField: UITextField!
@IBOutlet weak var passwordField: UITextField!
@IBOutlet weak var facebookBtn: UIButton!
@IBOutlet weak var googleBtn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// prepare the fields to be used - requires the exention at the bottom UITextFieldDelegate
emailField.delegate = self
passwordField.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if Auth.auth().currentUser != nil {
// if already logged in - send to feedVC
self.view.window!.rootViewController?.dismiss(animated: false, completion: nil)
}
}
@IBAction func facebookBtnWasPressed(_ sender: Any) {
FacebookLoginButtonClicked()
}
@IBAction func googleBtnWasPressed(_ sender: Any) {
}
@IBAction func loginBtnWasPressed(_ sender: Any) {
if emailField.text != nil && passwordField.text != nil {
AuthService.instance.loginUser(withEmail: emailField.text!, andPassword: passwordField.text!, loginComplete: { (success, loginError) in
if success {
// if login is successful - send user to feedVC
self.view.window!.rootViewController?.dismiss(animated: false, completion: nil)
//
print("Successfully logged in user")
//self.dismiss(animated: true, completion: nil)
} else {
print(String(describing: loginError?.localizedDescription))
}
})
}
}
@IBAction func iDontHaveAnAccountBtnWasPressed(_ sender: Any) {
// Show signup view controller instead
let signupVC = storyboard?.instantiateViewController(withIdentifier: "signupVC")
present(signupVC!, animated: false, completion: nil)
}
@IBAction func forgottenMyPasswordBtnWasPressed(_ sender: Any) {
Auth.auth().sendPasswordReset(withEmail: emailField.text!) { (error) in
// ...
}
}
@objc func FacebookLoginButtonClicked() {
let loginManager = LoginManager()
loginManager.logIn(readPermissions: [.publicProfile, .email, .userFriends], viewController: self) { loginResult in // request access to user's facebook details
switch loginResult {
case .failed(let error):
print(error)
case .cancelled:
print("User cancelled login.")
case .success(let grantedPermissions, let declinedPermissions, let accessToken):
print(grantedPermissions)
print(declinedPermissions)
// Get Facebook credentials
let credential = FacebookAuthProvider.credential(withAccessToken: (AccessToken.current?.authenticationToken)!)
let FacebookAccessToken = accessToken
// Check if existing user are already logged into Firebase
let currentUser = Auth.auth().currentUser
if currentUser != nil {
// Check if user already exists in Firebase, if true link accounts
Auth.auth().currentUser!.link(with: credential) {(user, error) in
if user != nil && error == nil {
// Linking accounts was a success
print("Linking of Facebook account with existing email and password successfull")
}
if let error = error {
print(error)
return
}
}
}
else {
Auth.auth().signIn(with: credential) { (user, error) in
if let error = error {
print(error)
return
}
// User is signed in
// ...
print("User signed in with Firebase")
}
}
}
}
}
}
extension loginVC: UITextFieldDelegate {
}
当Firebase中已存在电子邮件和密码帐户时,尝试使用Facebook登录时出错 .
Error Domain = FIRAuthErrorDomain Code = 17012“已存在具有相同电子邮件地址但登录凭据不同的帐户 . 请使用与此电子邮件地址关联的提供商登录 . ” UserInfo = {error_name = ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL,FIRAuthErrorUserInfoEmailKey = test @ gmail.com,NSLocalizedDescription =已存在具有相同电子邮件地址但登录凭据不同的帐户 . 使用与此电子邮件地址关联的提供商登录 . }