I have my firebase authentication set to prevent multiple accounts for the same email, but it doesn't seem to be doing that. See following pictures:
Has anybody experienced this issue before?
**Edit: Here's the details for reproducing this bug:
Pretty much the problem boils down to the updateEmail() function.
When a user signs up for my app I want to ensure I have an email for the user so searching for that user is easier. The problem is Facebook authentication doesn't ensure the user has an email for the following two reasons:
The user could have not allowed email permissions.
The user could have created their Facebook account only using a phone number.
Because of this, my
login code is somewhat complex but here's a link to my code with comments to explain everything (Note that I'm using custom Facebook/Google buttons which is why I had to manually do some stuff): Login Gist
If you look at the func getFBUserData() and see the comments above it, the bug is happening in the Case 1's first bullet point:
// 1) user's facebook does have email. This is common case
// - in this case, sign them into Firebase
// - could be that they previously didn't have email but now they do, so update Firebase user's email
This is the edge case where for some reason a user first didn't allow email permissions, then changed their minds and allowed them. What's interesting is that the code will still throw the .errorCodeEmailAlreadyInUse error, but the account will show up in the Firebase console as seen in the picture in the SO question and the following which I just did: http://imgur.com/yMjYXgH
Related
What I want
I have a list of people with all their personal information (name, first name, date of birth, email, etc.). I created an account for each of these people using their email/phone + a password I generated for them.
I want to send to each of these people an email/SMS with a link allowing them, once clicked :
to be directly connected on our website, without having to type a password or using a third party as Google/Facebook/etc.
and I want the link not to expire after the first use. The user must be able to click on it several times and be connected to our website each time.
What I tried
This is what I tried so far, unsuccessfully :
Passwordless Auth with email link: using both backend and frontend. Doesn't fit my needs because the signin link works only once by design.
Create a custom token with Firebase: as I understood, the token will expire 3600 seconds after creation, which is not useful for me.
Implement anonymous auth: it still need the user to type email+password at some point if you want to convert the anonymous account to a permanent account (because I don't want to use Google/Facebook/etc auth). Plus, it will need consequent changes in all my website code to work.
At this point I realized that Firebase doesn't have a solution that fits my needs. I started to fiddled around as best I could.
The idea
It works as the following:
First I create an account for the user in Firebase + a unique document in a collection in Firestore. That document contains 3 fields: magic_token, email, password.
Then, I create a link to our website with a unique token as a parameter in it. I store the token as magic_token in the document I described above. I send the link to the user.
The user clicks on the link, get redirected to my website. In the front, I detect the presence of the token in the parameters of the URL, I retrieve the document in Firestore with the corresponding token.
Using the email and password stored in this document I call: signInWithEmailAndPassword() to login the user.
PROS:
it fits my needs.
it is easy to implement
CONS:
the user password is visible in Firestore.
it's not very secure.
The question
Is there a proper way to implement a Magic Link that fit my needs? If not, how can I improve my own custom token authentication ?
How do I make it so that when a new user signs up in firebase, they can only login with that provider? Ex: a new user uses an email and password to sign up and then is rejected when trying to log in with Google.
I'm using Firebase with javascript in React if it helps.
What you're asking doesn't sound possible. The different auth providers don't know about each others' user bases. jackoboy on Google isn't at all related to jackoboy on Facebook. While they might have the same email address, that's never a guarantee that they are the same individual. So when jackoboy signs up with Google, there is nothing that can possibly stop jackoboy from also signing up with Facebook as a different account.
If you want to impose your own checks to see if the end user might be the same, you're going to have to write some code for that on a backend you control, then delete the second account if it appears to be the same person, by whatever logic you determine. Firebase Auth just isn't going to do that for you.
As said in the title, no matter how I try the Facebook login, the emailVerified field is always false. Is this by design? I've read through the whole firebase docs by now, can't seem to find any information regarding this. Just to be sure: I've tried with 4 different verified accounts, the result is always the same. Any idea what could cause this kind of behavior?
the reason why Google provider emails are verified and Facebook emails are not is because Google is considered a trusted provider (You can create an email account using Google). Let's take another example. If you set up an email with yahoo, you will get an email myself#yahoo.com. If you sign in using yahoo OAuth 2.0, you know for sure that user is verified since Yahoo is the actual owner and issuer of that email address. However, you could also use that same email to create a facebook account or some other account like github or twitter and verify using your phone number or some other means. In that case, if you sign in using Facebook, the email is not verified (facebook does not own or manage that email address). Normally if you wish to verify the email in that case, you have to send the email verification (experimental at the moment and only available in web and iOS but should eventually come to android).
The solution I provide would probably be useless to the OP since it was asked last year but hope it helps someone else. While I agree with bojeil's answer, it's somewhat annoying for real users to verify their Facebook email address when signing in with Facebook.
I encountered this problem on Android today and applied a work around since isEmailVerified() If condition always threw false and returned the user back to login page, here's the work around extracted from my code:
FirebaseUser mUser = mAuth.getCurrentUser();
if(!mUser.getProviders().get(0).equals("facebook.com")) {
if (mUser.isEmailVerified()) {
Intent mainIntent = new Intent(getActivity(), MainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(mainIntent);
} else {
Snackbar.make(getView().findViewById(R.id.loginLayout), "Please verify your account!", Snackbar.LENGTH_LONG).show();
}
}else{
Intent mainIntent = new Intent(getActivity(), MainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(mainIntent);
}
The first If statement checks if the user is signing in with Facebook,if yes the user is taken to the MainActivity, if not the isEmailVerified() method is invoked normally for email/password users and for Google sign in usersisEmailVerified()always returns true.
Firebase provides a process for "verifying" an email address -- but NOT for all platforms yet. This feature is not available for Android ... in fact, one cannot even query whether an eMail has been verified using Android code (even if you used a web or server code to perform the verification).
The "expected" process would normally be:
Authenticate a user's email (using any of the providers)
Call the Firebase function to send an eMail for verification
Respond to a verification link by setting verified Check, using client, to see if the eMail has been verified (could be days for the
user to handle)
Until eMail is verified, disallow appropriate
functions in your code (e.g. linking different authenticated
providers)
If you use an Android client currently, you cannot instigatge step 2.
I have created an Appcelerator iPhone app based on Firebase authentication, which works very well. But now I come across some unexpected behaviour.
My setup is as follows: on app start, the user must login or register. During registration, the account is created, and the corresponding account data (uid, name, email, date etc.) is also stored in a /users/uid data entry.
When I remove a user from Firebase through the Dashboard, by removing it from both /users/uid and the "Login & Auth" tab, it looks all clear. But when the user opens the app, he still remains logged in.
How can I enforce removing a user, where he is also logged out the next time he opens the app?
According to the Firebase Google Group, this is a known bug with Firebase:
This is a known bug on our end. As you noted, after deleting a user,
existing auth tokens are still valid and can be used to read and write
to your Firebase database. Security Rules are still enforced on these
tokens and that user will still only be able to access their own
Firebase data (if your rules are set up as such). Those auth tokens
will be valid until they expire. There is currently no workaround for
this bug although we are going to be fixing this in a future release.
https://groups.google.com/d/msg/firebase-talk/Yr_wn02q0bk/eTM9hop3paoJ
The only thing I can think to do is check whether you can read to your users area, and if there's nothing there, force a log out.
From your behavior it seems like there maybe a configuration issue or just a bug. Does the users information get removed from corresponding data-source (DB or in-memory store)? I would start there then move on to researching how the corresponding cookies/tokens work and contact their support.
Though perhaps you shouldn't out right delete the user, perhaps just disable the user therefore, accomplishing the same result? Maybe this behavior will work properly.
I want to build a custom asp.net control to put on a webpage that will allow people to see a piece of information from my facebook account that requires auth. For the sake of simplicity let's just say I'd like it to display the last thing that I liked. I don't want the visitor to my site to have to be logged into facebook (nor would they have to be my friend on fb). I want my site to somehow store a token that I have authorized and then it will use this token for the access. I know this can be done initially, but I'm confused what happens when the token expires. Or for that matter if I log out from facebook. Is there some type of token or secret or something that I can request that can be auto-renewed again and again by my website independent of any login state that I have as an fb user? Does this require me creating an fb app and associating the token to it?
I don't have any code at this point, I'm looking for a higher level of guidance on the protocol that should be used here, from there I can hopefully figure out the code from existing samples, docs, etc. This is my first code interaction with facebook so don't assume that I know very much at this point :-)
EDIT: I've been reading everything I can about this topic and I can't seem to find a solution. In the past there was an RSS feed but that appears to be gone now. Then there was also the offline_access permission which is no longer available. This seems like such a simple task but I'm just not able to connect the dots. I have been able to get the initial user token with perms for reading "likes", that's easy. Now I can store that in my website's db and use it to make requests for that data anytime someone loads my page. But eventually the token will expire and I'm not seeing any automatic way to renew it that wouldn't potentially involve user "Larry", who happens to be browsing my website, being asked to supply MY facebook credentials. Basically it seems as though I could never log out from facebook or I'd be risking a broken feed on my website. Is the fb auth model just not set up to allow for thist? To summarize again - a user Bob wants to give his permission to acme.com to always be able to display Bob's most recent like regardless of whether Bob is logged in to fb or not. He would only want to have this stop working if he revoked authorization to the WhatDoesBobLike app which runs on acme.com. Possible?
-JT
You would need an extended access token. It will only last up to 60 days and from then you would need to re-extend.
If it were a page you could extend the user access token then grab the page access token which would never expire.
Read more at
http://developers.facebook.com/roadmap/offline-access-removal/