What you'll build

In this part you'll connect Firebase to the Flutter app, set up the Firestore product data structure, and build the catalog screen — a scrollable grid of product cards that opens a detail page when tapped.

By the end of this part your app will have:

Connect Firebase

Create a Firebase project

Go to console.firebase.google.com, click Add project, name it shop-app, and follow the wizard. Disable Google Analytics if you don't need it — it simplifies setup.

Add Firebase to Flutter

Install the FlutterFire CLI:

dart pub global activate flutterfire_cli

Then run in your project root:

flutterfire configure

Select your Firebase project when prompted. This generates lib/firebase_options.dart and downloads google-services.json (Android) and GoogleService-Info.plist (iOS) automatically.

Update lib/main.dart to initialise Firebase before runApp:

await Firebase.initializeApp(
  options: DefaultFirebaseOptions.currentPlatform,
);

Enable Firestore

In the Firebase console, go to Firestore Database → Create database. Start in test mode for now (we'll add security rules in Part 4 with Auth).

Seed some products

In the Firestore console, create a products collection with a few documents. Each document should have:

{
  "name": "Ankara Print Wrap Dress",
  "description": "A vibrant wrap dress in authentic Ankara print. Fully lined, adjustable waist tie.",
  "price": 180.00,
  "currency": "GHS",
  "images": ["https://..."],
  "sizes": ["XS", "S", "M", "L", "XL"],
  "category": "dresses",
  "inStock": true,
  "createdAt": "<timestamp>"
}

Add 6–8 products so the grid looks realistic when you test.

Build the product model and service

BlocWeave prompt

Create the product data layer for the Flutter shop app. 1. lib/models/product.dart — a Product class with fields: id (String), name, description, price (double), currency (String, default 'GHS'), images (List), sizes (List), category, inStock (bool), createdAt (DateTime). Add fromFirestore and toMap methods. 2. lib/services/product_service.dart — a ProductService class with methods: - Stream> getProducts({String? category}) — streams all in-stock products, optionally filtered by category - Future getProduct(String id) — fetches a single product by ID 3. lib/features/catalog/catalog_provider.dart — a Riverpod StreamProvider that exposes the products stream from ProductService

Build the catalog screen

BlocWeave prompt

Build the catalog screen for the Flutter shop app. 1. lib/features/catalog/catalog_screen.dart — a screen that listens to the catalogProvider and shows: - A horizontal scrollable row of category filter chips at the top (All, Dresses, Tops, Trousers, Accessories) — tapping a chip filters the grid - A SliverGrid of product cards below, 2 columns, showing the product image, name, and price - A loading shimmer while data loads, and an error message if the stream fails 2. lib/features/catalog/product_card.dart — a card widget showing: product image (use CachedNetworkImage, with a placeholder), product name in Playfair Display, price in GHS formatted as "GHS 180.00", and a subtle shadow. Tapping navigates to /product/:id. Use the app theme colors. Keep widgets const where possible.

Build the product detail page

BlocWeave prompt

Build the product detail screen at lib/features/catalog/product_detail_screen.dart. The screen receives a product ID via GoRouter path parameter, fetches the product using getProduct(), and shows: - A full-width image carousel (PageView) for the product images - Product name in Playfair Display heading style - Price in rose gold color - A short description - A size selector — a row of outlined chips for each size; tapping one selects it (highlighted in rose gold) - An "Add to cart" button pinned to the bottom of the screen Handle loading and error states. The Add to Cart button should be disabled until a size is selected.

Test the catalog

Run the app and verify:

  1. The product grid loads from Firestore
  2. Tapping a category chip filters the visible products
  3. Tapping a product card opens the detail page
  4. The image carousel swipes between images
  5. Selecting a size enables the Add to Cart button

**Images in Firestore:** For testing, you can use any public image URL. In production, upload images to Firebase Storage and store the download URLs in the `images` field. Part 7 (Admin) adds an image upload flow using `image_picker` and Firebase Storage.

Project structure after Part 2

lib/
  features/
    catalog/
      catalog_screen.dart
      catalog_provider.dart
      product_card.dart
      product_detail_screen.dart
  models/
    product.dart
  services/
    product_service.dart

What's next

In Part 3 we build the shopping cart — Riverpod state for cart items, quantity controls, and a cart screen with a subtotal. The Add to Cart button on the detail page will start working.