DEV Community

Yadnesh Teli
Yadnesh Teli

Posted on AI-assisted

Building a Flutter Shopping App — Part 2: Firebase Auth, Google Sign-In, and the Account Merging Problem

Series 1 of 2 — Part 2 of 5

Building a Flutter Shopping App — Part 2: Firebase Auth, Google Sign-In, and the Account Merging Problem

Series: Building a Flutter Shopping App — From Zero to Architecture

Adding authentication to a Flutter app sounds straightforward. Firebase gives you a clean SDK, the docs are good, and there are tutorials showing you how to add a login screen in twenty minutes.

What those tutorials do not show you is what happens when a user signs up with email and password, and then later tries to sign in with Google using the same email address. Firebase throws an error. The accounts are separate. And your user is confused.

That is the problem I spent most of this phase solving.

Setting up Firebase Auth

First the straightforward part. I added firebase_auth and firebase_core to pubspec.yaml, configured the Firebase project, and set up the platform config files. I created a UserModel to hold uid, email, and display name, and an AuthProvider using Riverpod that wrapped FirebaseAuth and exposed methods for login, signup, and logout.

Refactoring the auth screens

I also refactored the login and signup screens at this stage to improve responsiveness. The original versions had hardcoded padding values that broke on smaller screens. I switched to MediaQuery-based padding and updated all error messages to be human-readable rather than showing raw Firebase error codes.

Adding Google Sign-In

Google Sign-In itself is not complicated. You use the google_sign_in package to get a GoogleSignInAccount, exchange it for a credential, and pass that to Firebase.

final googleUser = await GoogleSignIn().signIn();
final googleAuth = await googleUser?.authentication;
final credential = GoogleAuthProvider.credential(
  accessToken: googleAuth?.accessToken,
  idToken: googleAuth?.idToken,
);
await FirebaseAuth.instance.signInWithCredential(credential);
Enter fullscreen mode Exit fullscreen mode

That is the happy path. The unhappy path is where it got interesting.

The account merging problem

Here is the scenario. A user signs up with email and password. Later they tap Sign in with Google, pick the same email address. Firebase throws a FirebaseAuthException with code account-exists-with-different-credential.

Firebase treats email/password and Google as two separate sign-in providers. The same email address can have multiple providers linked to it, but they are not automatically merged when you sign in from a new provider.

My solution was to catch this exception, sign the user in with their existing email/password credential, and then link the Google credential to their account. After this they can sign in with either method.

try {
  await FirebaseAuth.instance.signInWithCredential(googleCredential);
} on FirebaseAuthException catch (e) {
  if (e.code == 'account-exists-with-different-credential') {
    final existingUser = await FirebaseAuth.instance
      .signInWithEmailAndPassword(email: email, password: existingPassword);
    await existingUser.user?.linkWithCredential(googleCredential);
  }
}
Enter fullscreen mode Exit fullscreen mode

Making the cart and favourites user-aware

With auth in place, I updated the cart and favourites providers to be scoped to the current user. Cart data was now stored under a user-specific key in SharedPreferences. When the user logged in, their previous cart was restored. When they logged out, it was cleared.

I also handled migration from the old global storage format to the new user-scoped format so existing users would not lose their data.

What I learned

  • Account merging is explicit: Firebase Auth multi-provider account merging is not automatic — you have to handle it explicitly.
  • Scope state to user ID: Always scope state to the current user when building apps with authentication.
  • User-facing errors: Error messages in auth flows matter more than in most other parts of an app.

Next: Part 3 — Integrating Cloud Firestore and Push Notifications

Top comments (0)