From c9393b6374a2f3c8b2b87717ef5ebe464a136a2d Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Wed, 7 Dec 2022 17:06:09 +0100 Subject: [PATCH] fix(ui_auth): automatically upgrade anonymous accounts --- .../firebase_ui_auth/example/lib/main.dart | 13 +++++++++++- .../flutter/generated_plugin_registrant.cc | 4 ---- .../flutter/generated_plugin_registrant.h | 6 ------ .../flutter/generated_plugin_registrant.cc | 4 ---- .../flutter/generated_plugin_registrant.h | 6 ------ .../firebase_ui_auth/lib/src/auth_flow.dart | 2 +- .../firebase_ui_auth/lib/src/auth_state.dart | 5 ++++- .../lib/src/providers/auth_provider.dart | 14 +++++++++++-- .../src/providers/email_auth_provider.dart | 21 +++++++++++++++---- 9 files changed, 46 insertions(+), 29 deletions(-) diff --git a/packages/firebase_ui_auth/example/lib/main.dart b/packages/firebase_ui_auth/example/lib/main.dart index 7187aaec4333..6c3f39659251 100644 --- a/packages/firebase_ui_auth/example/lib/main.dart +++ b/packages/firebase_ui_auth/example/lib/main.dart @@ -33,6 +33,10 @@ Future main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); + if (FirebaseAuth.instance.currentUser == null) { + await FirebaseAuth.instance.signInAnonymously(); + } + FirebaseUIAuth.configureProviders([ EmailAuthProvider(), emailLinkProviderConfig, @@ -66,7 +70,7 @@ class FirebaseAuthUIExample extends StatelessWidget { String get initialRoute { final auth = FirebaseAuth.instance; - if (auth.currentUser == null) { + if (auth.currentUser == null || auth.currentUser!.isAnonymous) { return '/'; } @@ -139,6 +143,13 @@ class FirebaseAuthUIExample extends StatelessWidget { Navigator.pushReplacementNamed(context, '/profile'); } }), + AuthStateChangeAction((context, state) { + if (!state.user.emailVerified) { + Navigator.pushNamed(context, '/verify-email'); + } else { + Navigator.pushReplacementNamed(context, '/profile'); + } + }), mfaAction, EmailLinkSignInAction((context) { Navigator.pushReplacementNamed(context, '/email-link-sign-in'); diff --git a/packages/firebase_ui_auth/example/linux/flutter/generated_plugin_registrant.cc b/packages/firebase_ui_auth/example/linux/flutter/generated_plugin_registrant.cc index 925b63790d47..1c65bab7f8ed 100644 --- a/packages/firebase_ui_auth/example/linux/flutter/generated_plugin_registrant.cc +++ b/packages/firebase_ui_auth/example/linux/flutter/generated_plugin_registrant.cc @@ -1,7 +1,3 @@ -// Copyright 2022, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - // // Generated file. Do not edit. // diff --git a/packages/firebase_ui_auth/example/linux/flutter/generated_plugin_registrant.h b/packages/firebase_ui_auth/example/linux/flutter/generated_plugin_registrant.h index 0da50bdd73cf..e0f0a47bc08f 100644 --- a/packages/firebase_ui_auth/example/linux/flutter/generated_plugin_registrant.h +++ b/packages/firebase_ui_auth/example/linux/flutter/generated_plugin_registrant.h @@ -1,9 +1,3 @@ -/* - * Copyright 2022, the Chromium project authors. Please see the AUTHORS file - * for details. All rights reserved. Use of this source code is governed by a - * BSD-style license that can be found in the LICENSE file. - */ - // // Generated file. Do not edit. // diff --git a/packages/firebase_ui_auth/example/windows/flutter/generated_plugin_registrant.cc b/packages/firebase_ui_auth/example/windows/flutter/generated_plugin_registrant.cc index a95575385941..45e2647eb8a9 100644 --- a/packages/firebase_ui_auth/example/windows/flutter/generated_plugin_registrant.cc +++ b/packages/firebase_ui_auth/example/windows/flutter/generated_plugin_registrant.cc @@ -1,7 +1,3 @@ -// Copyright 2022, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - // // Generated file. Do not edit. // diff --git a/packages/firebase_ui_auth/example/windows/flutter/generated_plugin_registrant.h b/packages/firebase_ui_auth/example/windows/flutter/generated_plugin_registrant.h index 60e38c3bed6a..dc139d85a931 100644 --- a/packages/firebase_ui_auth/example/windows/flutter/generated_plugin_registrant.h +++ b/packages/firebase_ui_auth/example/windows/flutter/generated_plugin_registrant.h @@ -1,9 +1,3 @@ -/* - * Copyright 2022, the Chromium project authors. Please see the AUTHORS file - * for details. All rights reserved. Use of this source code is governed by a - * BSD-style license that can be found in the LICENSE file. - */ - // // Generated file. Do not edit. // diff --git a/packages/firebase_ui_auth/lib/src/auth_flow.dart b/packages/firebase_ui_auth/lib/src/auth_flow.dart index 8c531a35ce44..8726dd625761 100644 --- a/packages/firebase_ui_auth/lib/src/auth_flow.dart +++ b/packages/firebase_ui_auth/lib/src/auth_flow.dart @@ -126,7 +126,7 @@ class AuthFlow extends ValueNotifier @override void onCredentialLinked(AuthCredential credential) { - value = CredentialLinked(credential); + value = CredentialLinked(credential, auth.currentUser!); } @override diff --git a/packages/firebase_ui_auth/lib/src/auth_state.dart b/packages/firebase_ui_auth/lib/src/auth_state.dart index 3661e6b2950f..47b25cd03ebf 100644 --- a/packages/firebase_ui_auth/lib/src/auth_state.dart +++ b/packages/firebase_ui_auth/lib/src/auth_state.dart @@ -107,8 +107,11 @@ class CredentialLinked extends AuthState { /// A credential that was linked with the currently signed in user account. final AuthCredential credential; + /// An instance of the [User] the credential was associated with. + final User user; + /// {@macro ui.auth.auth_state.credential_linked} - CredentialLinked(this.credential); + CredentialLinked(this.credential, this.user); } /// {@template ui.auth.auth_state.auth_failed} diff --git a/packages/firebase_ui_auth/lib/src/providers/auth_provider.dart b/packages/firebase_ui_auth/lib/src/providers/auth_provider.dart index 8811ef4c57ae..ea86cd4c9d30 100644 --- a/packages/firebase_ui_auth/lib/src/providers/auth_provider.dart +++ b/packages/firebase_ui_auth/lib/src/providers/auth_provider.dart @@ -109,8 +109,12 @@ abstract class AuthProvider { /// {@macro ui.auth.auth_provider} AuthProvider(); + /// Indicates whether the user should be upgraded and new credential should be + /// linked. + bool get shouldUpgradeAnonymous => auth.currentUser?.isAnonymous ?? false; + /// Signs the user in with the provided [AuthCredential]. - void signInWithCredential(AuthCredential credential) { + void signInWithCredential(K credential) { authListener.onBeforeSignIn(); auth .signInWithCredential(credential) @@ -120,8 +124,9 @@ abstract class AuthProvider { /// Links a provided [AuthCredential] with the currently signed in user /// account. - void linkWithCredential(AuthCredential credential) { + void linkWithCredential(K credential) { authListener.onCredentialReceived(credential); + try { final user = auth.currentUser!; user @@ -175,6 +180,11 @@ abstract class AuthProvider { // Only email provider has a different action for sign in and sign up // and implements it's own sign up logic. case AuthAction.signUp: + if (shouldUpgradeAnonymous) { + linkWithCredential(credential); + break; + } + signInWithCredential(credential); break; case AuthAction.none: diff --git a/packages/firebase_ui_auth/lib/src/providers/email_auth_provider.dart b/packages/firebase_ui_auth/lib/src/providers/email_auth_provider.dart index 6bdd0075f4af..1474b3fdd77b 100644 --- a/packages/firebase_ui_auth/lib/src/providers/email_auth_provider.dart +++ b/packages/firebase_ui_auth/lib/src/providers/email_auth_provider.dart @@ -55,10 +55,23 @@ class EmailAuthProvider fba.EmailAuthCredential credential, AuthAction action, ) { - if (action == AuthAction.signUp) { - signUpWithCredential(credential); - } else { - super.onCredentialReceived(credential, action); + switch (action) { + case AuthAction.signIn: + signInWithCredential(credential); + break; + case AuthAction.signUp: + if (shouldUpgradeAnonymous) { + return linkWithCredential(credential); + } + + signUpWithCredential(credential); + break; + case AuthAction.link: + linkWithCredential(credential); + break; + case AuthAction.none: + super.onCredentialReceived(credential, action); + break; } } }