please help me finding correct solution in the following situation.
I am developing ios app with swift which will use Firebase as a backend.
Users should be able to login into firebase with email/password or/and with facebook. Maybe google will be added later.
It is important for me to have one firebase account for each real user as user will have reward points and it won't make sense if on one devise(with email login) he will have X points and on other device(with facebook) he will have different points.
Here is code which I am using to login with email:
//EMAIL REGISTER
@IBAction func registerAction(_ sender: Any) {
if self.emailTextField.text == "" || self.passwordTextField.text == "" {
Print( "Please enter email and password.")
} else {
FIRAuth.auth()?.createUser(withEmail: self.emailTextField.text!, password: self.passwordTextField.text!, completion: { (user, error) in
if error == nil {
self.logoutButton.isHidden = false
self.usernameLabel.text = user!.email
self.emailTextField.text = ""
self.passwordTextField.text = ""
} else {
Print("\((error?.localizedDescription)!)")
}
} )
}
}
//EMAIL LOGIN
@IBAction func loginAction(_ sender: Any) {
if self.emailTextField.text == "" || self.passwordTextField.text == "" {
print( "Please enter email and password.")
} else {
FIRAuth.auth()?.signIn(withEmail: self.emailTextField.text!, password: self.passwordTextField.text!, completion: { (user, error) in
if error == nil {
self.logoutButton.isHidden = false
self.usernameLabel.text = user!.email
self.emailTextField.text = ""
self.passwordTextField.text = ""
} else {
Print("\((error?.localizedDescription)!)")
}
})
}
}
Here is code which I am using to login with facebook:
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
self.fbLoginButton.isHidden = true
if error != nil {
self.fbLoginButton.isHidden = false
print(error.localizedDescription)
return
} else if (result.isCancelled) {
print("canceled")
self.fbLoginButton.isHidden = false
} else {
let credential = FIRFacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString)
FIRAuth.auth()?.signIn(with: credential) { (user, error) in
if let error = error {
print(error.localizedDescription)
return
}
}
}
}
Both methods work fine, but they create two separate accounts.
It is set up to allow multiple users with the same email in settings:
and I end up with the following result:
Obviously I want these two accounts to be merged automatically.
Documentation describes the way how to link auth providers, but user should be logged in with one method and only after that it will be possible to link accounts.
linkWithCredential
method is used if you already have the oauth credential. In case user was created on one device with email it wont work if he will decide to login again on other device with facebook.
After loggin in with any of these ways the FIRAuth.auth()?.addStateDidChangeListener
service is showing second view controller where I am working with database.
override func viewDidLoad() { super.viewDidLoad()
let user = FIRAuth.auth()?.currentUser
let dat = user?.providerData
let email = user?.providerData[0].email
let name = user?.displayName
if email != nil {
self.ref.child("user_profile").child("\(user!.uid)/email").setValue(email)
}
if name != {
self.ref.child("user_profile").child("\(user!.uid)/name").setValue(name)
}
}
Let say we loggin with facebook, maybe it is possible to find UID of user with same email and run updates? Not very good idea in case there are a lot of users.
Other idea is to use email as id like this:
self.ref.child("user_profile").child("\(email)/name").setValue(name)
Not sure if it is a good option?
thanks for your replies.