How to make firebase not create a new user for Google OAuth on sign in? - firebase

On sign in using firebase's Google OAuth provider, it automatically creates an account for the user if one does not exist. Is there a way to not create an account and return an error on sign in?
(https://firebase.google.com/docs/auth/web/google-signin)

When you call the sign-in method, it will create an account for the user if it does not exist.
If you want to check if an account exists or not, you would have to perform the "Login with Google" OAuth flow yourself (without the Firebase SDK) and then use a Cloud function to check if a user with the email exists (you might also have to maintain a list of users (their emails) in Firestore). If not, then you can create a new account with the access token you received.

Related

Is there a way to log out a specific user using firebase auth go sdk?

background of this question
I'm using firebase auth for user authentication on my app.
I realized that firebase doesn't have a log of user information changes, so I can't answer user questions about it.
So, I'm planning to move the feature of changing user account info (like email, display name, and password) from using the client-side firebase auth library to using server-side firebase auth SDK for the purpose of taking logs of these changes to use for user support. Also, I'd like to make logout a user who changes account info.
I've looked for the appropriate API on the document firebase.google.com/go/v4/auth and found UpdateUser function. The struct UserToUpdate which is a parameter of UpdateUser can set a new email address, new password and new display name, but I can't find to set the parameter to make a user logout.
my question
Is there a way to log out a specific user by firebase auth go SDK?
Firebase Authentication's client-side sign-in is based on ID tokens, which are valid until their built-in expiration (by default: an hour after they are minted). Since no server keeps a list of all the ID tokens it has minted, there is no way to mark a token as invalid on such a list either.
The common approach to revoke access for a user is to:
Revoke the refresh token, so that they can no longer mint new ID tokens with it.
Add the ID token(s) of the user to a self-managed list of revoked ID tokens.
Detect the presence of an ID token in this list from your server-side code and security rules.
Optionally detect the refresh token revocation on the client
Instead of logging the user out, you can also force-refresh their ID token/profile on the client to get the latest information from the server.

Flutter Firebase authentication - new anonymous user generated following sign-out and sign-in

The Firebase Authentication documentation states that:
If no previous anonymous account on the platform (for your specific application) has been created, when signing in anonymously Firebase will create a new unique user which will be persisted across app restarts/page reloads. If the user signs-out and reauthenticates anonymously again, they will be signed-in with the previously created account.
Yet when I sign out as an anonymous user and sign in again, I get a new anonymous user, instead of getting signed in with the previously created account. Just to be clear, the sign-in is done by calling FirebaseAuth.instance.signInAnonymously(), and the sign-out is done by calling FirebaseAuth.instance.signOut().
That looks like a mistake in the FlutterFire documentation. Once you sign out from an anonymous account, that account's UID is lost and cannot be reclaimed.
My best guess at the intention of the documentation is that calling signInAnonymously multiple times will result in the same UID. But signing the user out, clears that UID and it can't be reclaimed. I submitted a PR to improve the documentation here.

Logging in anonymous user with custom token removes the anonymous status

What is the exact definition of an anonymous user in firebase authentication?
when I call signInAnonymously() obviously the user is isAnonymous: true.
But if I create a custom token for the user via the admin sdk and then log in again with that customToken (using signInWithCustomToken(token)) the user is no longer isAnonymous.
Is this a bug or intended? And is there any workaround to persist that anonymous state?
What is the exact definition of an anonymous user in firebase authentication?
It's a user account that doesn't have a person's identity attached to it. It merely recognizes that someone (probably the same person) is using the app over time, on a specific device.
But if I create a custom token for the user via the admin sdk and then log in again with that customToken (using signInWithCustomToken(token)) the user is no longer isAnonymous.
When you sign in a new account, the prior account is always immediately signed out. This is true for all types accounts, and has nothing to do with anonymous auth. There can only be one user signed in at a time.
Is this a bug or intended?
Working as intended.
And is there any workaround to persist that anonymous state?
No, the anonymous account is signed out after you sign in a new account. If you instead want to upgrade that anonymous account with a known identity, you should look into linking a new identity to the existing anonymous account by converting the anonymous account to a permanent account. This will preserve the account, but it will no longer be anonymous (as it now contains some identity information in it).

Firebase Function onLink trigger

Is it possible to implement a function hook on when an anonymous user is linked to a normal account?
What I am trying to achieve in a secure way is:
1. DeepLink for invitation opens in the app.
2. Get invited_by from the URL and sign in the user anonymously, saving invited_by to invitations/anonymous_user_1/invited_by.
3. User registers an account and signs in so onCreate function is triggered, but we do not have access to the anonymous account there.
4. If there already is an anonymous account before registering, we link the anonymous account to the users new account.
And here is where I want to trigger a remote firebase function (don't want to trigger it on the client side, because it could be retriggered and abused to gain invitation advantages).
onLink() should do something like this:
1. Get old account (anonymous) and new account.
2. Get invitations/anonymous_user_1/invited_by from anonymous account.
3. Store it and perform actions on the new account.
4. Delete invitations/anonymous_user_1/invited_by once processed.
Is there a way to do this server side? Because onLink() would only be called once, and therefore I could process the anonymous data once.
As I said I would not want to call a function locally.
Thanks
There is no Firebase Authentication trigger for Cloud Functions when a user links accounts from multiple providers at the moment. As Doug commented, it's best to file a feature request for this.

When using Firebase Authentication service, how to throw error when login by Facebook/Google with no existing account

I'm developing a Flutter app using Firebase Authentication service.
The following Flutter plugins are used:
Firebase_auth
Google_sign_in
Facebook_login
The login flow is:
Login with either Facebook, Google or Email&Password
If account has already been created, logged in
If not, throws error
This is possible if the logging method is Email&Password. In Firebase_auth plugin, there are two separate methods for Email&Password scenario: createUserWithEmailAndPassword and signInWithEmailAndPassword. When the sign in method is called with a non existed account, it will throw a wrong id/password error.
However, for the Facebook/Google login method, the plugin only provides
signInWithFacebook and signInWithGoogle and the way they work is that the first time user uses facebook/google account to sign in, Firebase will automatically create an account and return the newly created account. (no separate sign up and sign in process)
I also read on the Firebase doc for Android Google Sign in
After a user signs in for the first time, a new user account is created and linked to the credentials—that is, the user name and password, phone number, or auth provider information—the user signed in with. This new account is stored as part of your Firebase project, and can be used to identify a user across every app in your project, regardless of how the user signs in.
So, my question is: If user logins with Fb/G account that has not yet been used to register with my app on Firebase, how do I make Firebase authentication throw error instead of automatically create a new account ?
Malcolm from the Firebase team here! Great question.
Given the functionality that currently exists in the open source Flutter plugins, you can likely get the result you desire by using the method #fetchProvidersForEmail(). Here are the logical steps you'll follow for the federated IDPs:
Do normal sign in the with IDP and get a token.
Parse that returned token for the user's email (usually using a JWT parsing library).
Call #fetchProvidersForEmail() with the extracted email.
If the providers that come back for the email are empty, then it's a new account. Otherwise, it's an existing account.
Alternatively, you could update the Flutter plugin to return more of the AuthResult, which includes whether or not the user is new. If the user is new, then you just call FirebaseAuth#getCurrentUser()#delete() and throw whatever error you wanted. (Which you would also have to add to the plugin).

Resources