Having looked through lots of previous questions and looking on the Firebase website documentation, it keeps leading me back to the snippet of code I need in my VC, BUT not how to actually set it up?.
Firstly in the email address verification setup on Firebase
I've by mistake put my personal email address as the 'reply to' email - do I put my personal (not business) email in there/how would I change it? Apologies for any over the top censoring (not sure what is private and not)
Secondly in my SignUpViewController what do I put as the URL String and what do I put as my IOSBundleID? Many thanks!
To change the email go to Authentication and press templates. There you have some options for your mail.
Press the pen beside noreply#yourfirebase.firebaseapp.com.
There you will have a replay to line and you can change all those settings
This is all you need to register a new user :
Auth.auth().createUser(withEmail: emailText.text!, password: passwordText.text!) {
(user, error) in
if error != nil {
print(error.localizedDescripton)
}else {
print("registration successful")
}
}
To send confirmation email to user make a call after user is created and use this method :
func sendConfirmationEmail() {
// Here you check if user exist
if self.authUser != nil && !self.authUser!.isEmailVerified {
self.authUser!.sendEmailVerification(completion: { (error) in
// Send the email
})
}
else {
// ERROR
}
}
You could now call the second method after user been created and the user will get an email
Related
I was working on the user profile page of my app and I am allowing the user to change their email address. If the user email address is changed successfully, the data in the firebase database of the particular user will be updated. Also, After successfully changing the email address, firebase will send an email to the user's previous email address (the user email address before it was changed to the new one) asking if it was the actual owner of the account who changed the email address and there will be a link to reset their email. If the user chooses to reset the email (for whatever reason), the user's new email will be changed to the previous email. But the problem is that the data in the database will not be updated, how can I detect this change (email reset) and update the database?
authenticateUserAlert.addAction(UIAlertAction(title: "Done", style: .default, handler: { [weak authenticateUserAlert] (_) in
// Print the user email
let emailTextField = authenticateUserAlert?.textFields![0]
print("Email: \(emailTextField!.text!)")
// Print the user password
let passwordTextField = authenticateUserAlert?.textFields![1]
print("Password: \(passwordTextField!.text!)")
// Re-authenticate the user
let user = Auth.auth().currentUser
let credential = EmailAuthProvider.credential(withEmail: emailTextField!.text!, password: passwordTextField!.text!)
user?.reauthenticate(with: credential, completion: { (result, error) in
if error != nil {
// Alert: What ever the error
print(error!.localizedDescription)
Alerts.errorAlert(on: vc, error: error!.localizedDescription, dismissAlert: false)
} else {
print(result!)
let editProfilePage = EditUserProfile()
editProfilePage.updateUserInfo()
}
})
}))
Here is what I tried according to an answer
Auth.auth().currentUser?.reload(completion: { (Error) in
//Completion handler
if let email = Auth.auth().currentUser?.email {
UserDataRetrieval.userEmail = email
self.emailLabel.text = email
print(Auth.auth().currentUser?.email)
}
})
It depends on the type of authentication you are using but honestly you should just use the email that is part of the authenticated account and then you don't need to worry about updating it in the database.
You can always just get the users email by using Auth.auth().currentUser.email
Update
Found a workaround to the issue of the credential data, try using
Auth.auth().currentUser?.reload(completion: { (Error) in
if (Error != nil) {
//Do something with error
} else {
//Do something with success or do nothing
}
})
Just call update credentials at the start of the app if you want to always have to most up to date credentials
You can always build your own custom handler for the email change revocation landing page. In that landing page you can update your database.
Check the official docs on how to do that.
I'm working on an iOS app which will use Firebase for user management (sign up, sign in, etc.)
I'm new to Firebase, but it's mostly going ok. I've connected it, I have created users and logged in, etc.
But, I'm trying to change my UI so that the "Sign up" button is initially hidden and will only appear when:
all fields are not empty
email address is valid (using regex)
email address in not already in the database
user name is not already in the database
password and confirmPassword fields are equal
I can't figure out #3 and #4.
I've been reading documentation, watching videos, chasing links all over StackO and beyond, but I can't figure it out.
Can anyone point me in the right direction?
If you are using email & password authentication, the solution is very simple.
Firebase Authentication will not allow duplicate emails so when the createUser function is executed, if the email already exists Firebase will return a emailAlreadyInUse error in the error parameter. You can then cast this to an NSError to see which one it is and handle appropriately.
So the function is like this
Auth.auth().createUser(withEmail: createEmail, password: password ) { user, error in
if let x = error {
let err = x as NSError
switch err.code {
case AuthErrorCode.wrongPassword.rawValue:
print("wrong password")
case AuthErrorCode.invalidEmail.rawValue:
print("invalid email")
case AuthErrorCode.accountExistsWithDifferentCredential.rawValue:
print("accountExistsWithDifferentCredential")
case AuthErrorCode.emailAlreadyInUse.rawValue: //<- Your Error
print("email is alreay in use")
default:
print("unknown error: \(err.localizedDescription)")
}
//return
} else {
//continue to app
}
I threw some random errors into that case statement but check the link for a complete list of all AuthErrorCodes.
You can also do this
Auth.auth().fetchSignInMethods(forEmail: user, completion: { (signInMethods, error) in
print(signInMethods)
})
I think you can check it by using this method
let ref1 = Database.database().reference().child("Users").queryOrdered(byChild: "UserName").queryEqual(toValue: "UserName enter by user")
ref1.observeSingleEvent(of: .value) { (sanpshot) in
print(sanpshot.exists()) // it will return true or false
}
and same for email.
I have a UITableViewController and I'd like the user to be able to change their current password with a new one.
The view is very straight forward - 2 UITextFields where I'd like them to enter their current password and another one for their desired new password.
The problem is I cannot find in Firebase's documentation a method that does that. Does anyone have an idea how to accomplish this?
PS: Ignore that it says "Update your email", this will be fixed.
1. Change Password
In Order to change password for Firebase User you do not need old password. You can do it by re-authenticating user and then updating password.
i. Re-authenticate User:
let user = Auth.auth().currentUser
var credential: AuthCredential
// Prompt the user to re-provide their sign-in credentials
user?.reauthenticate(with: credential) { error in
if let error = error {
// An error happened.
} else {
// User re-authenticated.
}
}
https://firebase.google.com/docs/auth/ios/manage-users#re-authenticate_a_user
ii. Change Password
Once user is re-authenticated use following method to Change password:
Auth.auth().currentUser?.updatePassword(to: password) { (error) in
// ...
}
2. Forgot Password
To handle this case you can send password reset link to user's email. Use following method:
Auth.auth().sendPasswordReset(withEmail: email) { error in
// ...
}
source: https://firebase.google.com/docs/auth/ios/manage-users
I am trying to link Facebook and Google. So, the scenario is this:
I have already authenticated with Google. So, now I am logging in Facebook, having same email id which was used earlier with Google. So, I get the error of account Exists with a different credential. And, I did this:
func fetchUserInfo()
{
Auth.auth().signInAndRetrieveData(with:FacebookAuthProvider.credential(withAccessToken: (FBSDKAccessToken.current().tokenString)!), completion: { (result, error) in
if let error = AuthErrorCode.init(rawValue: error!._code)
{
switch error
{
case .accountExistsWithDifferentCredential :
let credential = FacebookAuthProvider.credential(withAccessToken: (FBSDKAccessToken.current()?.tokenString)!)
Auth.auth().currentUser?.linkAndRetrieveData(with: credential, completion: { (result, error) in
if let error = error
{
print("Unable to link Facebook Account", error.localizedDescription)
}
else
{
NavigationHelper.shared.moveToHome(fromVC: self)
}
})
default: break
}
}
else
{
GeneralHelper.shared.keepLoggedIn()
if let currentUser = Auth.auth().currentUser
{
print(currentUser.email!)
}
NavigationHelper.shared.moveToHome(fromVC: self)
}
})
}
Here Firebase Documentation says that we need to just link the currentUser and retrieve data. But, the issue I am facing is that the currentUser is always nil. So, how can I get the current user? I have already tried this months ago and then I was able to link Facebook, Google and Email. Do, I need to signInAndRetrieve the data from Google in order to get the currentUser?
The Error "account Exists with a different credential" is because, by default, Firebase do not allow to use the same email address for two (or more) different Sing In methods. You need to enable this option.
1 - Go to Authentication > Sign-in method
2 - Scroll down to Advanced: Multiple accounts per email address
3 - Change the option to Allow creation of multiple accounts with the same email address
FYI: You need to do whole login process for each Sign In method in your app. Each method has is own credentials.
Hope this helps.
I have an app that allows a user to reset their password by putting their old one in a textfield and their new one in the next textfield. But in the old password textfield, the password they entered has to match the one that is registered to the currently logged in user. My app keeps crashing. Can someone help me. Here is the code. An image of the error is here.
if Password.text == (PFUser.current()?.password)! {
}else{
}
Try to add exclamation after the text: -
if Password.text! == (PFUser.current()?.password)! {
}else{
}
Edit: -
There is no way to get old password from Parse. Workaround though is.. you can first try authenticate user by giving the password which user has entered.. if authentication is successful then that means the entered old password is correct.. has been described here. Although it is android code it gives the required logic.
ParseUser.logInInBackground(ParseUser.getCurrentUser().getUsername(), currentPassword, new LogInCallback() {
public void done(ParseUser user, ParseException e) {
if (user != null) {
// Hooray! The password is correct
} else {
// The password was incorrect
}
}
});