What you'll build

In this part you'll add Firebase Authentication — email/password and Google sign-in. Browsing the catalog and filling the cart works without an account, but tapping Checkout requires sign-in. Returning users are signed in automatically.

By the end of this part:

Enable sign-in methods in Firebase

Go to the Firebase console → Authentication → Sign-in method and enable:

  1. Email/Password — toggle on, save
  2. Google — toggle on, set a project support email, save

For Google sign-in on Android, you need the SHA-1 fingerprint of your debug keystore:

keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

Copy the SHA-1 value and add it in Firebase console → Project settings → Your apps → Android app → Add fingerprint.

Add the Google Sign-In package

flutter pub add google_sign_in

Build the auth provider and service

BlocWeave prompt

Create the authentication layer for the Flutter shop app. 1. lib/services/auth_service.dart — an AuthService class with methods: - Stream<User?> get authStateChanges — wraps FirebaseAuth.instance.authStateChanges() - Future signInWithEmail(String email, String password) - Future signInWithGoogle() — uses GoogleSignIn() and FirebaseAuth credential - Future createAccount(String email, String password) - Future signOut() — signs out from both Firebase and GoogleSignIn - User? get currentUser 2. lib/features/auth/auth_provider.dart — a Riverpod StreamProvider<AsyncValue<User?>> that wraps authStateChanges. Export an authStateProvider and a currentUserProvider (derived, returns User? or null).

Build the sign-in screen

BlocWeave prompt

Build the sign-in screen at lib/features/auth/auth_screen.dart. The screen has two modes toggled by a tab or link: Sign In and Create Account. Sign In mode shows: - Email text field (keyboard type: email, autocorrect off) - Password text field (obscured, with a show/hide toggle) - A "Sign in" button - A divider with "or" - A "Continue with Google" button with the Google logo - A "Create account" link at the bottom Create Account mode shows the same fields plus a "Confirm password" field. Both modes: show a loading indicator while the request is in-flight, show an inline error message if it fails (wrong password, email already in use, etc.), and navigate to the previous screen on success. Use the boutique theme colors. The Google button should be white with a border.

Gate checkout behind auth

Update the cart screen so that tapping Checkout when signed out opens the auth screen instead:

BlocWeave prompt

Update lib/features/cart/cart_screen.dart. When the Checkout button is tapped, check currentUserProvider. If the user is null (not signed in), navigate to the auth screen and pass a returnTo: '/cart' parameter so the user is returned to the cart after signing in. If the user is signed in, proceed to the checkout flow (navigate to /checkout — we'll build that in Part 5).

Add Firestore security rules

Now that users have accounts, add security rules so users can only access their own data. In the Firebase console → Firestore → Rules:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    // Products are public — anyone can read
    match /products/{productId} {
      allow read: if true;
      allow write: if false; // Admin writes handled server-side
    }

    // Orders belong to the user who created them
    match /orders/{orderId} {
      allow read, write: if request.auth != null
        && request.auth.uid == resource.data.userId;
      allow create: if request.auth != null
        && request.auth.uid == request.resource.data.userId;
    }
  }
}

Show user state in the nav bar

BlocWeave prompt

Update lib/shared/widgets/app_scaffold.dart. Add a user avatar or "Sign in" icon to the AppBar actions. If the user is signed in (watch currentUserProvider), show their first initial in a circle. Tapping it opens a bottom sheet with their email and a Sign Out button. If not signed in, show a person icon that navigates to /auth.

Test the auth flow

  1. Open the app — you should be in guest mode (no user avatar or "Sign in" icon shows)
  2. Add something to the cart and tap Checkout — the auth screen should appear
  3. Create a new account — you should return to the cart automatically
  4. Sign out from the AppBar menu — user state resets
  5. Sign in with Google — completes and shows the user's initial in the AppBar
  6. Kill and reopen the app — you should still be signed in (Firebase persists the session)

Project structure after Part 4

lib/
  features/
    auth/
      auth_screen.dart
      auth_provider.dart
  services/
    auth_service.dart

What's next

In Part 5 we add Paystack checkout — the full payment flow from cart to confirmed order, with an order record saved in Firestore.