Firebase-Admin when updating user's email user gets logout if page is refreshed - firebase

When updating user's email using admin.auth().updateUser({email: newEmail}) the user's email gets updated (as an authentication provider). But whenever I refresh the page, the user gets logout.
Is there a way I can prevent that from happening and keeping the user logged in after its email gets updated?

Firebase treats the email address as its primary way of finding the account for a user when you don't (yet) have their UID. For that reason the email address is considered sensitive information, and changing it requires that the user reauthenticates before they can continue to use the app.
The Admin SDK documentation doesn't explicitly mention this as far as I can see, but you sort'of derive it from the documentation on setting a user's email address.

Related

Firebase Authentication Provider for a User changed automatically to E-Mail. How to change back?

In a Firebase project, I have activated multiple sign-in methods (e-mail, Google, and Microsoft), which all work fine. I also have it activated to only allow one account per e-mail address.
The problem arises when a user successfully signs in via Google or Microsoft, then signs out and then signs in via e-mail, using the same e-mail address as before using Google or Microsoft. Then his account type changes to e-Mail and it seems like a no way back.
Is there a way to change user account types from e-mail back to Microsoft or Google?
Your code must have different functions written for different signin's. When the user first logs in, store his login method on firestore. You can get this from the signin function triggered or simply by the button user clicked. Then during each login add a check that if user exists and user's current signin method is not the same as the one stored on firestore, notify the user to use the correct one.
Or you can let the user signin using whatever they please but ultimately in your code, the function which is triggered will tell you the current signin method and you'd have the first/previous method stored. So you can do stuff accordingly.
What you are writing in question seams not how it works. When you sign in using Google provider your email is verified automatly and if you try to sign in using same email authentication will throw error that account with that email allredy exists.
If you created first account using email and password and didn't verify your email addres then if you sign in using google provider with same email address in it, email and password provider will gone because of was not verified and you wont be able to login using email end password unless you will setup a new password for this email.
If email was verified and you sign in using google provider with same email address. This provider will be added to providers array and you will be able to login using email and password and google provider.
To add multiple providers to your accaunt you can use linkWithPopup() function. If you created accound with diferent email address and want to be able to log in on this account with provider who has diferent email address for example.

Weird firebase email verification

I am creating a messenger app. In order to register a new user what I want is to get email and password from the user and before creating the account I want to verify the email provided by the user.
But the problem with firebase email verification is that you have to create account/user first then you can send the email verification link to the user.
Now this can lead to major problem: Suppose if some fake user used my email and created account but failed to verify email. But still he manages to create an account with my email.
So if later I will try to register my self to the app then I am firebase is going to show me Email already used.
To solve this issue I want to delete account created if user fails to verify his email just after he tried to register himself.
To do this I created an email verification screen which is pushed as soon as new user register through his email and password. Now here app will be waiting for user to verify his/her email by clicking the link send by firebase. I have also provided a cancel verification button. So if user cancel the verification I am just deleting the account which was already created. I am also handling if user press back key without verifying email which will also delete the user account.
Main Problem: Now the the last thing I need to handle is if user force quit the app. In order to handle this I tried to delete the account in dispose method as well as I used WidgetsBindingObserver. But both of them doesn't work for me.
Please help me to solve this!
The idea of email Link verification was created to solve this problem. Instead of creating an account and then verifying the email after, the account is just directly created from your email. So obviously you must have access to the email to create the account. See https://firebase.flutter.dev/docs/auth/usage/#email-link-authentication for details on how to implement this style of link authentication.
A similar discussion of how to handle quitting the app is occurring here How to execute code before app exit flutter . However abrupt quits from an app whether done by the user or the system are hard to handle by nature.
I wouldn't recommend deleting the account when quitting/ closing etc. the app since it is something legitimate users may do before confirming their email (especially if the email is delayed in being sent for whatever reason). This will cause a lot of frustration.
You could setup a Cloud Http Task to trigger the deletion of that account after a certain time (e.g. a few hours) of the account not being registered.
If they do register in time, you can cancel the task before it runs.

Firebase Auth - After updating the user's email, Firebase Auth logs out the user

I am using Firebase Auth in my app. I update the email like follows:
firebaseAuth.currentUser?.updateEmail(email)
The email is updating 100% (I do a re-auth when necessary as well). My problem is after the e-mail has changed, the user is being logged out of his account and has to login again.
When I call
val user = firebaseAuth.currentUser
after updating the email the user is null and my app wants you to login again with the new email address.
Is this the correct behaviour? It makes for a really bad user experience having to login again after changing the account email.
I think Firebase is doing this on purpose for security reasons. You could work around this by calling the Firebase's login function automatically after changing the user's email.
However, I don't think that it is a normal behaviour if you're using the most recent version of Firebase. They explicitly state in their documentation that you need to re-authenticate the user to perform any profile change (if he hasn't signed in recently).
Some security-sensitive actions—such as deleting an account, setting a primary email address, and changing a password—require that the user has recently signed in. If you perform one of these actions, and the user signed in too long ago, the action fails with the FIRAuthErrorCodeCredentialTooOld error.
On my side, this effect only occurs on other devices on which the user has signed in, not on the device on which the edit action was performed.

Firebase recover password transforms account type

we are building an angular 5 app with Firebase.
We allow users to login with email+password or google account and we don't allow to have multiple accounts related to the same email address.
We built a form to allow users to ask for a Password Reset Email if they forgot their email password credentials and works perfectly if the user has an email+password account.
The problem arises when the reset email is asked for a google account. We'd expect for firebase to throw an error, not allowing to send the email, but the email is sent and if the user proceeds resetting the email the account is transformed from google type to an email+password.
Is there a way to prevent this behaviour ?
There is no way to prevent this. When a user resets their password, they are making a conscious decision to do so. Firebase is providing a way to recover an email account, in case it was hijacked. In the process all providers are unlinked and a password is set on the account.
You have a way to check if the email is associated with google provider or not. Checkout the fetchSignInMethodsForEmail and fetchProvidersForEmail APIs. These APIs would return the array of sign in methods or providers associated with an email.

Automatic auth linking

On our app we are using "One account per email address". We want users to sign up using a specific authentication provider, which we keep track of, and stick with it.
What I've noticed today is that if I log in using a Google or Facebook provider I can then send myself a password reset link to the associated email address, which allows me to use the email/password provider instead.
There is a slight difference in behaviour depending on the first provider:
If I use Google first, after I use the password reset link I can now user either provider to log in, and both are linked to the same firebase uid. If I debug, I can see both in the providerDetails array on the authData object I get back from Firebase.
If I use Facebook first, after I use the password link the password provider replaces the Facebook one completely, although it retains the old firebase uid. At this point I can no longer use the Facebook login.
My questions are: is this behaviour intended, and, is there any way to switch it off?
This can cause confusion if say a user logs in using Facebook (which we track) and then later forgets and sends a password reset. It isn't the end of the world because they can carry on using the password login, but it certainly muddies the water.
Thanks
The behavior is intentional.
For end users, if they had signed into the app using Google or Facebook, and later they want to recover the password, the most likely reason is they (or an attacker) can not login with that identity provider.
After the user clicks the password reset link, Firebase removes the non-email identity providers to prevent other people from accessing the account silently. If the user still wants to add Facebook/Twitter login, they can do that via manual account linking (if the app supports).
In case the user's email service is the same as identity provider (e.g. #gmail.com users login into the app using Google), Firebase has an optimization to keep the identity provider since there is no security risk.

Resources