Firebase-ios-sdk: invalid providers after call to fetchSignInMethodsForEmail using SignIn With Apple

Created on 20 Jan 2020  路  32Comments  路  Source: firebase/firebase-ios-sdk

Environment

  • Xcode version: 11.3.1
  • Firebase SDK version: 6.14.0
  • Firebase Component: Auth (Auth, Core, Database, Firestore, Messaging, Storage, etc)
  • Component version: 6.14.0
  • Using Carthage

Problem description

cannot retrieve the correct providers for a given email address.

Steps to reproduce:

  1. login using a Facebook account with the same email as your Apple ID
  2. login using Sign in with apple and hide your email address
  3. stop using sign in with apple in your iCloud settings
  4. login using sign with apple again but without hiding your email address
  5. try to update your user email with real email address

What happened? How can we make the problem occur?

you receive an error which is understandable, and I also know that we have to ask explicitly the user to link is social media account with his hidden email but if you go to the console then and you search for the real user email you'll see both account appear which seems logical but if your try to call - (void)fetchSignInMethodsForEmail:(NSString *)email, completion:(nullable FIRSignInMethodQueryCallback)completion; with the same mail you only get apple.com has a provider even if the mail change has failed and Facebook appear to be the provider associated to that email address.

auth

Most helpful comment

It seems the documentation on that method is incomplete and it will only return the set of sign-in methods for a single user (not for all users sharing the email).

@bojeil-google when the email update fails, is it still setting the provider-level email despite returning an error?

All 32 comments

I tried the 6.15.0 release just in case => same issue

Hello! Any news?

@renkelvin is out of office until Monday. I think this is intended (though confusing) behavior, but I'll let him confirm when he gets back.

@morganchen12 thanks for the update

I don't think I fully understand your steps to reproduce. However, fetchSignInMethodsForEmail only works on the signed in user, which is different from how console works. It is intended.

Do you want me to provide an app sample to show you my issue more clearly?

You end up with 2 accounts while fetchSignInMethodsForEmail only returns the methods for the 1 signed in user. So, it's intended.

I'm not sure to get it... fetchSignInMethodsForEmail get the last provider used for the given mail address?

@renkelvin do you want to me to send a sample app?

What he's saying is the login flow you described creates two separate users, so fetching the sign in methods is only returning a set of sign in methods for one of the users (that's why the sign in method list seems incomplete).

It's probably worth adding a bit to our docs disambiguating this situation.

if your try to call - (void)fetchSignInMethodsForEmail:(NSString *)email, completion:(nullable FIRSignInMethodQueryCallback)completion; with the same mail you only get apple.com has a provider even if the mail change has failed and Facebook appear to be the provider associated to that email address.

this the part I don't understand. Since the email change failed why does apple.com become the provider?

@bojeil-google, can you answer this last question?

I m having a hard time following the described scenario. It is quite convoluted. Can you describe it in more details and attach the observed behavior on each step?

In general, Apple emails are considered verified and Facebook emails are not. If you sign in with Facebook and then sign in with Apple using the same email (choose to share the real email). The Apple provider will overwrite the facebook provider on that account. The facebook provider will be removed.

For the sake of this example please consider the following:

  • john.[email protected] is both the user iCloud account address AND it's Facebook account address
  • The issue is not specific to Facebook, meaning that if you try to sign in using only john.[email protected] you'll have the same issue
  • Step 1: sign in with either Facebook, your email address is [email protected] => This will create a user A

  • Step 2: sign in with sign in with apple with an hidden email, let's say its [email protected] => This will create a user B

  • Step 3: Revoked your sign in with apple credential by going to your iCloud account settings

  • Step 4: Sign in using Sign in with apple again with your real email address [email protected] => This will log you the user B account

    • Step 4.1: At this point we are trying to update the user account email => This will fail because user A already uses john.[email protected]
  • Step 5: In the app code try to fetch the signIn provider for john.[email protected]

What I think I should have: Facebook (User A)
What I actually get: apple.com (User B)

Does this make it more understandable or should I send you an app sample?

Thanks for the explanation. It is clearer now to me but quite the edge case.
It seems that in this case there will be 2 users with the email john.[email protected].

fetchSignInMethodsForEmail cannot tell which user to return and will pick one user record that matches the email (when in reality there are 2).

but since the email change failed in step 4.1 there should only be one provider associated to the John.doe email address or am I getting it wrong?

There is one provider with that email but fetchSignInMethodsForEmail looks users by email at top level email and at provider level email which returns 2 results in this case.

But it doesn't give me the 2 results just one which is technically not the correct one in my scenario

I already explained. There isn't an "incorrect result". There are 2 users with different providers that have the same email. Both users have the same email but fetchSignInMethodsForEmail only returns one result.

Right... but it's still doesn't make sense. If the email change appeared to failed then the change of provider should not occurred in this specific case either that or you should add a parameter in fetchSignInMethodsForEmail to specify the which level you want to use.

Not only that but if has @bojeil-google said fetchSignInMethodsForEmail just return one result then please explain me this https://firebase.google.com/docs/reference/ios/firebaseauth/api/reference/Classes/FIRAuth?hl=en#-fetchsigninmethodsforemail:completion:

It seems the documentation on that method is incomplete and it will only return the set of sign-in methods for a single user (not for all users sharing the email).

@bojeil-google when the email update fails, is it still setting the provider-level email despite returning an error?

I agree we should document that fetchSignInMethodsForEmail returns a single user.
Update email fails because there is already a user (the Facebook user) with a top level email (not provider level email) matching the emails to be changed to. The top level email is always unique. This works as intended. 2 users can have different providers with the same email but no 2 users should share the same top level email.

This makes sense, but from what @rakesthedon described, the email update call is having an effect on the user even though it returns the error message.

I'll take care of updating the documentation.

That is not what I understood. My understanding is that the email update is failing as expected.

I see, I misread the steps.

@rakesthedon, if you sign out of User B and sign into User A after completing the steps in your scenario above, does signInMethodsForEmail return Facebook?

It gives me apple

Hey guys! any news?

Hey @rakesthedon, sorry for the slow update. Currently, we have no plans to change the behavior of the SDK since this is (from what we understand) a very uncommon edge case to run into. It is definitely weird behavior and I plan on updating the documentation soon, but I haven't found the time to do so yet.

Is this weird behavior preventing you from doing something with Firebase Auth?

At the moment no, but my QA already encounter the same bug with the same steps but using google so it's not impossible that users are going to do so as well.

Hey @rakesthedon, sorry for the slow update. Currently, we have no plans to change the behavior of the SDK since this is (from what we understand) a very uncommon edge case to run into. It is definitely weird behavior and I plan on updating the documentation soon, but I haven't found the time to do so yet.

Is this weird behavior preventing you from doing something with Firebase Auth?

Hi guys, I'm also facing this problem ... Are there any updates ??

How can we manage an Apple user with Hidden Email who for his own reasons decides to use his Apple email to access our apps?

The same thing seems to happen with Facebook when a user decides not to show his email ... If at the next login he changes his mind and wants to show the email, his Firebase account continues to show an invisible email even if the user decided to show it ..

How can we resolve the management of anonymous access for Apple and / or Facebook?

@CodeTeamLabs As @morganchen12 noted, we don't currently have plans to support this particular edge case out-of-the-box, and so this behavior is WAI.

However, please file a feature request if you want us to explore supporting this resolution automatically in the future, and we can prioritize it accordingly!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matthieuchappaz picture matthieuchappaz  路  3Comments

PierBover picture PierBover  路  3Comments

pot8os picture pot8os  路  4Comments

henrymoulton picture henrymoulton  路  3Comments

paulharter picture paulharter  路  3Comments