Firebase signInWithPopup creates account when reauthenticating - firebase

When reauthenticating a Firebase user via the Google provider for a protected action (password reset, email change, acct deletion, etc), I notice that it creates an account if one doesn't already exist.
The problem this creates is that if a person is signed into multiple Google accounts on their machine and they select the wrong account at re-auth, Firebase will create an account and sign the user in under that account.
This could be particularly problematic at account deletion. The user expects to remove an account only to end up adding another. Also, things like TOS/privacy policy acceptance would then have to be moved to the sign in flow which means users would have to create an account, verify email, and sign in before being presented with terms and policies.
Is there any way to prevent a provider pop-up from creating an account and just return an error if the account chosen for reauth does not match the currently selected account? I thought about implementing this manually but the problem is that once the user signs in, the old token is removed from storage. Even if you store the initial email address and compare it to the address selected for reauth, you can't give the user the option to try again because they've already been unauthenticated from the original account and your only option is to sign them out entirely. This just makes for a tricky elevated auth flow.

Related

Firebase subaccounts

I'm currently building a POS/Store admin app, when a user gets into my app, the Owner of the store will then be asked to login only once for setup purpose (e.g. a new machine), the app will then display a list of staffsName that has already been added by this owner, and then everytime a staff wants to start a new transaction, he/she will only need to click on his/her name, then enter his/her 4-digit pincode to 'login' and process the transaction.
How do i go about achieving this?
I was thinking of using firebase auth for the 'login' of the staff, but then when i log in using the staff credential, I will lose access to the uid of the owner, which is needed to access the owner's store data such as his/her products.
i'm also thinking of using firestore to store the 4digit pincode, but then i'm also concerned about security
There are multiple ways you can approach this, one where you utilize the email login by simply appending a fake domain to the username to create a valid email domain. This user account could be the designated 'user' in question, or utilize credentials inside custom claims or hidden in a database that allows the client or server (depending on your preference) to then log in as the user.
Moreover if you want the manager to login once you can add Authentication State Persistence to specify whether a signed in user should be indefinitely persisted until explicit sing out, page reload etc.
Another approach requires the user also to have a valid auth that is not an email password and you link your pin auth to that main account with Firebase Auth Linking per the documentation: https://firebase.google.com/docs/auth/web/account-linking.
This does however require that the user be registered from an auth provider such as Google, Twitter, Apple, etc. then the user will have to activate this link by logging in for authentication purposes. This can in theory be automatically generated and processed without the user knowing.
It is a long way around it since this is essentially a custom solution but it does create the flow you are looking for without having to use a custom auth provider.

can I change authentication provider from google account to be anonymous in firebase authentication?

An user login using Google account as the provider for authentication like the image above. I want to make when the user performs log out, then the provider should change from Google to be anonymous. so I want to make, when user logout, they will be anonymous but with the same userID Bdf2LPraRhbnWhP24eiSN3vTQ5G3
Can I do that?
I need to make it anonymous, because I want that user to still see some contents in my app even when they logout. They need to be in the logged-in state to pass the security rules.
I want to make when the user performs log out, then the provider should change from google to be anonymous.
There is no way you can automatically do that. When the user logs out, the created account still remains and cannot be converted in any way.
Firebase lets you create those anonymous accounts so you can authenticate with Firebase. These are only temporary accounts that can be used to allow users who haven't yet signed up to use your app. It's true that you can convert an anonymous account to a permanent account with Google, but the vice versa is not available.
It's also true that you can log a user out from Google, as well as from Firebase, and delete the Firebase account entirely, but if you try to create another anonymous account, a new UID will be generated. Unfortunately, there is no way to reclaim the old token for the user.
because I want that user to still see some contents in my app even when they logout.
If you want the user to see some content even if they log out, simply display that content also for non-authenticated users. If you want to restrict that only for a particular user, then the user should be authenticated.

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.

How many time Anonymous users are created in Firebase

I would like to use the signInAnonymously feature from firebase but I'd like to know how it works exactly.
Is this anonymous user added as any other user in Firebase (but without an email or password) ?
Is it automatically removed after a certain time ?
If I call this method on each app launch. Will it create a new user everytime ? How will it know how te reuse an old one ? Local Storage ?
So will it create another user in database if my users connects from another device ?
Thanks a lot
An anonymous user account is similar to any other user account in Firebase, except that there is no way to identify the user.
Anonymous users are not automatically removed.
Each time you call the API to create an anonymous user, a new account will be created. To re-use the existing account, you should listen for the auth state when the app starts and only create a new user account if the user isn't signed in yet.
If the same (anonymous) user signs in from multiple devices, they will get a separate account on each. If that is not what you want for your use-case, you should require one of the identified authentication methods (email/password, Facebook, Google, etc)/
Frank's answer to the third question is incorrect.
From the documentation:
If there is already an anonymous user signed in, that user will be returned instead. If there is any other existing user signed in, that user will be signed out.
Therefore, this method can be safely called every time the application starts.

Is there a way to check credentials with Firebase?

I'm using Firebase Auth (web API) and am looking for a way to check the validity of a user's email / password combination for account removal.
Ideally a call like Firebase.isValidCredentials(email, password)
Problem context:
In my app, when a user requests to remove his/her account, I want to prompt to re-enter their password as confirmation. If correct, the account should be removed along with all other associated data (living under different Firebase nodes).
While the credentials check is done by Firebase.removeUser(), that also removes the auth:ed account with it, which breaks my ability to remove user data (as I've set Firebase Security to require active auth for manipulating user data nodes).
Appreciate guidance here, and if there's a Firebase recipe for removing user accounts along with user data.
Firebase.authWithPassword(email, password) can be used to confirm credentials of already authenticated users, in addition to signing in non-authenticated users.
(thanks Kato for the advice!)

Resources