I'm stuck in a login/registration flow with Firebase. I have a simple use case where users can register/login with email-password and login with Google. If a user is registered with email-pass and tries to log in with google with the same email id, I want to link both providers with one account. I know this can be done once the user is logged in, but I want to do it when the user is trying to log in via google, and some prompt will come up as "you already have an account, please enter your password to connect".
I have tried the scenario where the user is logged in with an email pass and trying to connect their google account.
If a user is registered with email-pass and tries to log in with Google with the same email id, I want to link both providers with one account.
That is happening by default. If a user signs in using email and password and later using Google provider, their account sign-in method is automatically converted to Google. Why? Because according to the official documentation, Google is considered a trusted provider:
Trusted providers:
Google (for #gmail.com addresses)
And:
Untrusted providers:
Email / Password without email verification
In some situations, Firebase will automatically link accounts when a user signs in with different providers using the same email address.
That's because by default a user can have only one account per email address. This is done to prevent users from creating multiple accounts using the same email address with different authentication providers. However, this can be changed in the Firebase console, in the "Sign-in method" tab, inside the Authentication section.
So remember, Firebase Authentication has the concept of a preferred provider for certain email addresses, and unfortunately, there is no way to change this behavior, at least at the time I'm answering this question.
Related
I am new to firebase and I am trying to handle firebase user authentication in React.js. I did manage to create users with email and passwords. But, now I would like to send the user an Email link to reset their password.
My code currently look like this.
// This line of code belongs to the top
import { auth } from '../firebaseConfig'
//This part goes under the React component
<p onClick={async () => {
try{
await sendPasswordResetEmail(auth, // My Email Id)
alert('Password reset link has been sent to your email')
}
catch(err){
alert(err)
}
}}
>Forgot your Password ?</p>
However, I do not get any error messages and I do get the alert message that says "Password reset link has been sent to your email." Unfortunately, I didn't receive any email. Note that I have given my own email id as the parameter for testing purposes.
firebaser here
Did you check your spam folder? We recently see a lot of the emails from Firebase Authentication ending up in the user's spam folder or being marked as spam in a system along the way. This is being tracked in this status message on the Firebase dashboard and in public issue #253291461.
To reduce the chances of the messages getting marked as spam, consider taking more control of the email delivery yourself.
As a first step, consider using a custom domain with your project. Email that comes from a custom domain has less chance of being marked as span.
As a second step, consider setting up your own SMTP server.) for delivering the email, so that the emails are not being delivered from Firebase's shared infrastructure anymore.
While these steps are more involved, they typically will drastically reduce the cases where the messages from Firebase Authentication are marked as spam.
Full Guide Based on Frank's Answer
Firstly create a new email account you can use to relay the Firebase emails through the SMTP server with. I personally chose Gmail, but I tested with Outlook and it also works.
You can now find an SMTP server host that will work for your scenario. If you're sending less than 1000 emails per month you can find free and reliable hosts. I chose SMTP2GO's free option.
Now you've found the SMTP host, add the email address you've chosen as a single sender email (note that if you do own a domain, you can alternatively use that to send emails).
Note that you will have to verify the email, usually by your host sending a link to the email's inbox. Make sure to check spam.
Once verified, navigate to where you host allows you to add SMTP Users and add a new user. This will allocate an SMTP username and password.
Navigate to the Firebase console, and choose the Authentication option from the sidebar (within the Build product category).
Go to Templates → SMTP Settings and enter the details of your SMTP server. The username and password fields are to be filled with the SMTP user login you created in the step above.
It is better to use TLS, but I believe SSL should work too but it is untested.
Click save, and you're all set up - but there may still be steps to perform depending on your email provider.
Provider Specific Steps
If the emails are being sent to an account managed by Google you will have no issues with your emails being quarantined by anti-spam policies and it will work immediately.
If you are using Outlook, you will have a different problem on your hands. Outlook's built in defender will most likely have auto-quarantined your email under multiple policies - that bit is important.
These policies are likely to be both spam and phish policies. If you unblock one of them, the other will catch it and re-quarantine.
Unblock both policies for the email address, and test. You can see the status of quarantined messages in Microsoft 365 Defender app under Review → Quarantine. Please note that you will need to be an administrator to add global allow policies to your email accounts.
If this still doesn't work it is likely that your company has an additional external filter (as mine did), and you will have to add the IP's manually to the Tenant Allow/Block Lists spoofed senders tab.
I am working on a conversation using google actions conversation sdk. I want to personalize the experience, How do i get the email of the user ? I know i need to do account linking , the flow is already done using oAuth but question is how to trigger it when user is interacting with google assistant over voice. I want to check if user email is available else ask him/her to signin using my service account ( users signup over web).
Any pointers will be appreciated.
You will need to do account linking with the Streamlined account linking flow, which first requests the user's Google account and then your server can check whether that email address exists already. If so, the account linking proceeds. Otherwise you can create a flow that will let them create an account via voice.
The implementation guide steps through how to setup the project information in the Actions Console and the server-side code to write to perform this verification:
I am writing a node server where I am using the Google Project and Service account to manage Users in that G-Suite Account.
Since the service account is domain-wide delegated with administrator roles enabled, Is it possible to validate the password of the G-Suite User using its G-Suite User ID? If possible what is the API I should use from my node service with service account?
If the above is not directly supported what are the alternative ways I can consider to achieve my use case (Use case is to validate the user credential from backend service).
Please help.
Thanks,
Srini.
I am not aware of any API public or private where you can combine a User ID from any Google service and the account password to do anything.
Having domain-wide delegation to manage/access a user's account is not the same thing as having access to their login credentials.
Do not prompt users for their Google Accounts password. Do not attempt to brute force or use password dictionaries to guess user passwords. Google security services will detect this and then you will have another level of problems to fix.
How exactly would you validate a users password using a service account even if the password field was available to you which it isn't because that would be bad it would already be inserted at the time and the user would have moved on. Are you going to send them an email after the fact telling them their password is bad?
The application where they enter their password should be testing that the password is valid. Being that this is their google account then its probably already done by Google.
I'm currently developing an authentication system with Firebase. I'd like my system to accept email/password, Google and Facebook as sign-up and sign-in methods.
So far, so good. Everything works good when the user signs up with each method separately. The problem begins when a user wants to sign up with another method and I need to link the new method to same account that was previously registered by the same user using another method.
My examples will mention only the email/password and Google methods.
Note: my Firebase auth system is set to accept only 1 account per email.
Example1 (works fine):
User register for the first time with Google
Perfect! I get his details and write it to the Firestore using the userID created by the auth system.
User tries to register again, now using his email/password (the same email from his 1st register with Google)
I get an error saying that the email is in use, I let the user know that he already registered with Google and I ask him to sign-in again with Google
Then, once he's signed in with Google, I let him create a password inside his account page.
I'll take that password and link it to his pre-existing account (which he is currently signed in) that was made when he first signed up with Google.
Great! Now I have a user that can login with either Google or his password.
Example 2 (the problem):
User registers for the first time using his email/password. Note that his email is one from Google (gmail).
Perfect! I get his details and write it to Firestore using the userID created by the auth system.
User tries to register again, now using Google sign-in method (with the same email).
Apparently everything works OK and the user signs in just fine.
But the fact is that, without any warnings, Firebase authentication has discarded his email/password method and replaced it with only the Google sign-in method.
Google Group - Firebase Talk - About this issue
From the link above and some other related questions here on StackOverflow, I understood that this behavior is like this because of security issues, and that is why Google has a "higher precedence" over other auth providers, since you can really trust those users and their emails.
But to remove a password that a user has created seems wrong to me. Not to mention doing it without any warnings.
And also, this seems to be in conflict with the following Firebase help page:
Firebase Help - Allow multiple accounts with the same email address
From the help page linked above:
You can configure whether users can create multiple accounts that use
the same email address, but are linked to different sign-in methods.
For example, if you don't allow multiple accounts with the same email
address, a user cannot create a new account that signs in using a
Google Account with the email address ex#gmail.com if there already is
an account that signs in using the email address ex#gmail.com and a
password.
From the excerpt above, what I understand is that I shouldn't be able to create the account using Google, if I have created it previously using a email/password combination. But that is not what happens, as per Example 2. Very strange!
Now the real question:
Since I'll not be able to change Firebase behavior, I'm thinking about changing my Firebase auth system to allow multiple accounts per email and handle all my users data in Firestore using their email as the primary key (instead of using the userID of the Firebase auth system), since every combination of email/sign-in method will be considered a different account in the Firebase auth system and therefore each one will have a different userID.
Ex:
johndoe#gmail.com / password = UserID X
johndoe#gmail.com / Google sign-in = UserID Y
johndoe#gmail.com / Facebook sign-in = UserID Z
All of the accounts above will store and access data in the Firestore using the johndoe#gmail.com as the "primary-key" (collection).
But since I'm early in my development, this seems a bit "hacky" I might bring some complications in the future.
What do you recommend? The main goal here is to let my users sign-up and sign-in using any method that they want to. All of the methods should allow them to access their data in my application (that will be in Firestore).
I refuse to silently delete a user's password that they previously created just to let them sign-up and in with Google.
Any other ideas or comments?
Sorry for the long question, but I think it illustrated the problem well.
One option is to enforce password users to verify their email address right after they sign up. In the example #2, Firebase will keep the account's existing password if the email address has been verified e.g. by sending a verification link to the email address and the user has clicked the link.
I am creating a login for my chrome extension where I am going to be using the firebase email and password.
I am going to be putting the create User firebase code on my website and when someone can enter in there email and the script will create a random set of digits and set that as the password. It will then email that password to the user and the user uses the email he entered and the random digit password he received via email to login.
My question is If a user signs up and then logs in with his email and password. Whats to stop him from giving that email and password to his friend and he also logs in. I want to control the amount of users I allow within my chrome extension and only want the person who logged in to use the chrome extension (I want so the login can only be used once) Is this possible for firebase or not?
Also If anyone knows a simpler method than that I described above with sending the email please let me know becuase to do that above I have to create something that sends an email and creates the password.
I would also like to know if firebase has something where I can set a date on a user and after that date passes the user is logged out and has to register again.
But my main question is that if a user where to register if he has the ability to share the login with his friend or if only he can use it.
I really appreciate your reply and help on my issue in advance Thanks A lot.
You'll likely have to do this from the server side (e.g. in a Cloud Function).
One option would be to use the session management features in the auth admin SDK: https://firebase.google.com/docs/auth/admin/manage-sessions - if you report back from the extension with the logged in user, you can revoke access for users who are seen in too many places at the same time. This limit might not be 1 - you may want to allow your users to log in on multiple machines at once.
For even more control, look at the option for managing your own session cookie: https://firebase.google.com/docs/auth/admin/manage-cookies - this allows you to set your own expiry and control the logged in state more granularly.