Why is it possible to send a password reset email to external provider with Firebase AUth Api? - firebase

I am currently developing an angular+ionic app. Everything is working ok but I got a question with the forgot password workflow: sendPasswordRestEmail -> user clicks link -> user fill form -> user submit form -> password and oobCode send with the firebase auth api, which I am accessing through angular fire package.
As I said everything is working as intended. The only "issue" I see is that firebase not only sends password reset email to user that created their account with an email/password but also users that are using an external provider like Google ( sign in with google). I havent test login with Facebook at this point but it is happening with google provider. I just want to make sure if this is the intended workflow or something may be wrong... a bug or something? before I post an issue on github, because even though the user can "change its password" when using an external provider, it is having no effect on their external account(gmail account) which of course should have no effect.

Sending a password reset email from Firebase allows the user to reset the password on their Firebase Authentication account. It has nothing to do with the password they may have with any social provider associated with that account.

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.

Is there a way to reset password with Firebase Auth INSIDE a flutter app?

Firebase Auth has a method to send a verification email so the user can reset his/her password. This link redirects the user to a website where the new password will be written and saved.
Is there a way to reset a user's password using flutter and firebase inapp? I mean, could I send a verification code through SMS or email that would be then typed into the app and the user would choose a new password all inside the app?
Thank you!
To be able to change a user's password directly through the API, the user will have to enter their current password in order to be able to update it.
If you use the Admin SDK however you can implement whatever flow you want, and update the password at the end of the flow. But of course in that case it is up to you to ensure you do it securely.
You can do so by using custom email handlers along with dynamic links to open them in your app. This might require a custom domain to do so. Once the user visits your application on the custom route/page, you can then use applyActionCode method to process the email action. Checkout my answer here for a detailed explanation on processing the email actions:
How to build a custom Email action handler in Flutter for Firebase Authentication

Firebase authentication Twitter and Google

I am using the Firebase authentication functionality. I am using Facebook, Google, Twitter and email and password as providers. The default functionality is to use a single email by authentication.
If I authenticate with an account with Facebook, Twitter or Google and then try to enter but using email and password to do it, it shows me a warning where it says that I already use another authentication method and it allows me to do it with the previous one.
If I authenticate with email and password and then try to authenticate with Google, Twitter or Facebook these authentication methods overlap, that is, take both and in the Firebase console I can see that they are both.
Now, if I authenticate with email and password, Facebook (I think) or Twitter and then try to authenticate with Google, it deletes the previous authentication methods. That is, if with the first authentication methods I had id1 after authenticating with Google, the entry with id1 is deleted and one is created with id2.
This generates a problem in my application because it is a way to lose the user's registry previously created with id1.
I'm not sure if this is the expected behavior but I do not think so. Obviously whenever I refer to doing a 'new authentication' with another method I make sure to use the same email.
It sounds like you are looking for account-linking. This is possible in Firebase-authentication. Users are identified by their Firebase Userid and you can link multiple authentication providers to a userid.
Try to check this documentation. I think this is what you are looking for: https://firebase.google.com/docs/auth/web/account-linking
I hope it helps.
The Google provider overwriting the existing providers is due to Google emails being verified as Google owns these email addresses.
To work around this, you will need to verify the email after the user signs up by sending an email verification. This guarantees that Google sign-in will not unlink the providers as the email is considered to be verified. So if a user signs up with Facebook (using a Google email), verify the email so next time the user signs in with the same Google email, the Facebook provider would remain on the user.

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.

Lose password after sign in using Google provider

I have an Android app with use Firebase authentication using email and password. Recently added Google provider now my users can sign in wih his Google account, the problem is the following
There's an existing user example#gmail.com registered on my app, later the user sign in with his Google account Firebase automatically change the provider of the account from email to Google, the problem the user sign out and try to login with his email/password and got a message
The password is invalid or the user does not have a password
I understand why happens, but users (you know they are users) get frustrated because can't login with his email/password
There's some way to tell Firebase to keep the user password or when a user login with Google and this convertion happens in order to notify to user
Note My app only allow one account per email
I found there's a method fetchProvidersForEmail I asume I can build a flow over that method that check which provider have the user and allow the user chose if want to keep if old password by asking and linking account or just continue

Resources