Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[firebase_auth] linkWithCredential uses current user instead of user object on which the function is called #48

Closed
jeanmatthieud opened this issue Aug 27, 2019 · 3 comments
Labels
blocked: customer-response Waiting for customer response, e.g. more information was requested. impact: customer A bug with low impact (e.g. affecting only a few customers or has a workaround). (P3) plugin: auth resolution: needs-repro This issue could not be reproduced or needs an up to date reproduction on latest FlutterFire plugin. type: bug Something isn't working

Comments

@jeanmatthieud
Copy link

jeanmatthieud commented Aug 27, 2019

I'm trying to manage the 'ERROR_CREDENTIAL_ALREADY_IN_USE' error when linking an account to another, by following the android guide: https://firebase.google.com/docs/auth/web/account-linking#link-email-address-and-password-credentials-to-a-user-account

In the last code section, when the credentials are already in use:

  • User logged in with account [A], and submitted credentials [C]
  • SignIn on the already existing account [B] with credentials [C]
  • Retrieve app's data linked to account [B]
  • Delete the existing account [B]
  • Link user account [A] to the credentials [C] and SignIn with credentials [C]
  • Import data of account [B] on the linked user

Ugly code:

AuthResult authResult;
final FirebaseUser previousUser = await FirebaseAuth.instance.currentUser();
try {
  authResult = await previousUser.linkWithCredential(credential);
} on PlatformException catch (err) {
  if (err.code == 'ERROR_CREDENTIAL_ALREADY_IN_USE') {
    // Signin to the existing account
    authResult = await FirebaseAuth.instance.signInWithCredential(credential);
    // TODO : Get data from the authResult.user account
    // Delete existing account
    // TODO : better deletion error management
    await authResult.user.delete();
    // Link previous user
    authResult = await previousUser.linkWithCredential(credential);
    // TODO : merge previous account data to current account
  } else {
    throw err;
  }
}

Sadly, calling previousUser.linkWithCredential() seems to use firebaseAuth.getCurrentUser() and not the user on which the call has been done, resulting into an USER_REQUIRED error.
See FirebaseAuthPlugin.java:275

@jeanmatthieud
Copy link
Author

After digging the source code, I realized that the plugin always uses the currentUser linked to the FirebaseApp.
The workaround I found to manage more than one user is to create a secondary FirebaseApp, FirebaseAuth and FirebaseStore.

This is far from ideal, and a call on a method of a FirebaseUser should not use the currentUser but the user on which the method has been called.

AuthResult authResult;
final FirebaseUser previousUser = await FirebaseAuth.instance.currentUser();

final firebaseAppTemp = await FirebaseApp.configure(name: 'temporaryApp', options: await FirebaseAuth.instance.app.options);
final FirebaseAuth firebaseAuthTemp = FirebaseAuth.fromApp(firebaseAppTemp);
final Firestore firestoreTemp = Firestore(app: firebaseAppTemp);

try {
  authResult = await currentUser.linkWithCredential(credential);
} on PlatformException catch (err) {
  if (err.code == 'ERROR_CREDENTIAL_ALREADY_IN_USE') {
    // Signin to the existing account
    authResult = await firebaseAuthTemp.signInWithCredential(credential);
    // TODO : Data migration - NOW USING 'firestoreTemp'
    // Delete existing account
    // TODO : better deletion error management
    await authResult.user.delete();
    // Link previous user
    authResult = await previousUser.linkWithCredential(credential);
    // TODO : merge previous account data to current account - NOW USING 'firestoreTemp'
  } else {
    throw err;
  }
}

@BondarenkoStas BondarenkoStas added the type: bug Something isn't working label Sep 11, 2019
@iapicca iapicca changed the title firebase_auth: linkWithCredential uses current user instead of user object on which the function is called [firebase_auth] linkWithCredential uses current user instead of user object on which the function is called Oct 23, 2019
@Ehesp Ehesp added plugin: auth impact: crowd Affects many people, though not necessarily a specific customer with an assigned label. (P2) labels Apr 20, 2020
@Salakar Salakar added impact: customer A bug with low impact (e.g. affecting only a few customers or has a workaround). (P3) and removed impact: crowd Affects many people, though not necessarily a specific customer with an assigned label. (P2) labels Apr 20, 2020
@Ehesp
Copy link
Member

Ehesp commented Jul 2, 2020

This is far from ideal, and a call on a method of a FirebaseUser should not use the currentUser but the user on which the method has been called.

Unfortunately this isn't possible since Dart vs Native code can't keep track of different user instances.

That being said, work is being done to pass back an updated credential via the error as expected.

@Salakar Salakar added blocked: customer-response Waiting for customer response, e.g. more information was requested. resolution: needs-repro This issue could not be reproduced or needs an up to date reproduction on latest FlutterFire plugin. labels Aug 25, 2020
@Salakar
Copy link
Member

Salakar commented Aug 25, 2020

Hey 👋

Our rework of the firebase_auth plugin as part of the FlutterFire roadmap was published over a week ago with a ton of fixes and new features.

Please could you update to the new version. If you have any problems with the updated plugins please raise a new GitHub issue.

For help migrating to the new plugins please see the new migration guide: https://firebase.flutter.dev/docs/migration

@Salakar Salakar closed this as completed Aug 25, 2020
MaikuB pushed a commit to MaikuB/flutterfire that referenced this issue Sep 2, 2020
@firebase firebase locked and limited conversation to collaborators Sep 26, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
blocked: customer-response Waiting for customer response, e.g. more information was requested. impact: customer A bug with low impact (e.g. affecting only a few customers or has a workaround). (P3) plugin: auth resolution: needs-repro This issue could not be reproduced or needs an up to date reproduction on latest FlutterFire plugin. type: bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants