firebase / flutterfire

🔥 A collection of Firebase plugins for Flutter apps.
https://firebase.google.com/docs/flutter/setup
BSD 3-Clause "New" or "Revised" License
8.63k stars 3.95k forks source link

🐛 [FirebaseAuth] Apple Sign in Method when user already have Microsoft account forcefully changes provider instead of throwing account-exists-with-different-credential #10218

Open vitor-soares-iteam opened 1 year ago

vitor-soares-iteam commented 1 year ago

Bug report

We have Microsoft Sign in and Apple Sign in implemented within our app. I have an Apple ID with the same e-mail as my microsoft Azure AD e-mail. At first I had created an microsoft account

Captura de Tela 2023-01-04 às 16 51 48

Then, I tried to log in using Apple sign in using the same e-mail registered with my microsoft account. with "await FirebaseAuth.instance.signInWithCredential(appleCredential);"

The expected outcome was an exception with the code: "account-exists-with-different-credential" Since I already had a microsoft account with that e-mail.

Instead, my account was simply changed into an apple provider account, resulting in some unexpected outcomes. Including not being able to access through the microsoft credential anymore. Captura de Tela 2023-01-04 às 16 54 21

The Microsoft sign in is made calling the method "signInWithProvider(MicrosoftAuthProvider())" and it works fine and gives the expected outcome: "throws exception with code account-exists-with-different-credential".

Since this bug needs apple authentication and microsoft authentication implemented, its quite hard to provide code to reproduce this behavior.

Let me know if I can help with anything else.

Edit: When I tried doing the same with an E-mail provider account the result was that the two providers were automatically merged. Captura de Tela 2023-01-04 às 18 17 58

Apparently only when the account is based on microsoft provider the microsoft provider gets replaced.

darshankawar commented 1 year ago

Thanks for the report @vitor-soares-iteam Can you provide what platform are you seeing this behavior on ? (Android, iOS or web) ? Can you take a look at the plugin example and use the same scenario and see if using it, you get same behavior or not ?

I tried to log in using Apple sign in using the same e-mail registered with my microsoft account.

This probably could be a reason as the email id is same in your case and could be creating the conflict. Is there a way for you to verify this using different email id, ie, apple and micrsoft with different email ids ?

vitor-soares-iteam commented 1 year ago

Hello, @darshankawar . Thanks for the fast reply! Here are the follow-ups on your questions:

Best regards,

darshankawar commented 1 year ago

Thanks for the feedback.

  • The plugin example doesn't implement microsoft sign in nor apple sign in. This can't be tested with the example.

It does have both sign-in implementations as you can see below:

https://github.com/firebase/flutterfire/blob/6380a278812d2b046e59376a64df92210397282d/packages/firebase_auth/firebase_auth/example/lib/auth.dart#L105

https://github.com/firebase/flutterfire/blob/6380a278812d2b046e59376a64df92210397282d/packages/firebase_auth/firebase_auth/example/lib/auth.dart#L96

I unfortunately don't have MS and Apple accounts with same email id, so can't recreate / replicate this behavior myself. With different emails though, it works as expected.

I am keeping this issue open for team's attention and insights on expected behavior.

darshankawar commented 1 year ago

/cc @Lyokone

vitor-soares-iteam commented 1 year ago

@darshankawar thans for linking the file of the correct example. I was looking the one on pub.dev page. Sorry. Anyway, I've tested with the same implementation from the example:

      final appleProvider = AppleAuthProvider();
      appleProvider.addScope('email');
      UserCredential credential = await FirebaseAuth.instance.signInWithProvider(appleProvider);

This approach has the same problem ( Previous Microsoft account gets replaced with apple provider)

The approach I'm currently using is:

       final AuthorizationResult result = await TheAppleSignIn.performRequests([
         AppleIdRequest(requestedScopes: [Scope.email, Scope.fullName])
       ]);
       final appleIdCredential = result.credential;
       final AuthCredential appleCredential = OAuthProvider('apple.com').credential(
         accessToken: String.fromCharCodes(appleIdCredential!.authorizationCode!),
         idToken: String.fromCharCodes(appleIdCredential.identityToken!),
       );
      UserCredential credential = await FirebaseAuth.instance.signInWithCredential(appleCredential);

Notice the example implementation calls signInWithProvider, and the implementation I'm currently using calls signInWithCredential.

The problem reported about the Apple provider replacing Microsoft provider happened on both implementations.

Hope this information helps a bit.

Best regards,

P.S: Another thing I noticed is that even adding "appleProvider.addScope('full_name');" the attributes "givenName" and "familyName" returned by apple are not present on the first oficial example approach. With the approach I'm currently using that uses the "TheAppleSignIn" plugin to retrieve an AppleIdCredential gives me access to those attributes.