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.