# How to Create an Inventory Management System in FlutterFlow

- Tool: FlutterFlow
- Difficulty: Beginner
- Time required: 30-40 min
- Compatibility: FlutterFlow Free+
- Last updated: March 2026

## TL;DR

Build an inventory management system by creating a products collection with stock levels and a stock_movements collection that logs every receive, sell, adjustment, and return event. Use FieldValue.increment for atomic stock updates so concurrent transactions never cause count drift. Add barcode scanning for fast product lookup, low-stock alerts when inventory drops below reorder levels, and a dashboard showing total inventory value and slow-moving items.

## Building an Inventory Management System in FlutterFlow

Tracking inventory accurately is essential for any product-based business. This tutorial builds a complete inventory system with product cataloging, stock movement logging, barcode scanning for fast receiving, low-stock alerts, and a management dashboard. Every stock change is logged as a movement for full audit trail visibility.

## Before you start

- A FlutterFlow project with Firestore and authentication configured
- Basic familiarity with Firestore queries and Custom Actions
- A mobile device for testing barcode scanning functionality
- Sample product data with SKU codes

## Step-by-step guide

### 1. Create the Firestore data model for products and stock movements

Create a products collection with fields: sku (String, unique), name (String), category (String), currentStock (Integer), reorderLevel (Integer), costPrice (Double), sellPrice (Double), supplierId (String), imageUrl (String), location (String for warehouse or shelf position), lastUpdatedAt (Timestamp). Create a stock_movements collection with fields: productId (String), type (String: received, sold, adjustment, return), quantity (Integer, positive for additions, negative for removals), reference (String for order number, PO number, or audit ID), userId (String, who performed the action), notes (String), timestamp (Timestamp). Add indexes on products for category plus currentStock filtering and on stock_movements for productId plus timestamp ordering.

**Expected result:** Firestore has products and stock_movements collections with indexes for efficient querying.

### 2. Build the product inventory list with stock-level indicators

Create an InventoryPage with a TextField for search at the top. Add ChoiceChips for category filtering. Below, add a ListView with a Backend Query on products, filterable by category and searchable by name or SKU. Each product row displays the name, SKU, currentStock as a number, and a stock-level color indicator: a Container with background color green when currentStock is above reorderLevel times 2, yellow when between reorderLevel and reorderLevel times 2, and red when at or below reorderLevel. Show the location text and costPrice. Tap a product to navigate to ProductDetailPage showing full details, stock movement history, and action buttons.

**Expected result:** A product list with search, category filtering, and color-coded stock level indicators at a glance.

### 3. Implement barcode scanning for product lookup and stock receiving

Add a barcode scan IconButton on the InventoryPage header. Create a Custom Widget using the mobile_scanner package that opens the camera and detects barcodes. When a barcode is scanned, query the products collection where sku equals the scanned value. If found, navigate to the ProductDetailPage. If not found, show an option to create a new product with the SKU pre-filled. For receiving stock, on the ProductDetailPage add a Receive Stock button that opens a BottomSheet with quantity TextField (numeric), reference TextField (PO number), and a Scan button that scans the product barcode for verification. On submit, call a Custom Action that uses FieldValue.increment to atomically add the quantity to currentStock and creates a stock_movement document with type 'received'.

```
// Custom Action: receiveStock
import 'package:cloud_firestore/cloud_firestore.dart';

Future<void> receiveStock(
  DocumentReference productRef,
  int quantity,
  String reference,
  String userId,
) async {
  // Atomic increment - safe for concurrent updates
  await productRef.update({
    'currentStock': FieldValue.increment(quantity),
    'lastUpdatedAt': FieldValue.serverTimestamp(),
  });
  // Log the movement
  await FirebaseFirestore.instance.collection('stock_movements').add({
    'productId': productRef.id,
    'type': 'received',
    'quantity': quantity,
    'reference': reference,
    'userId': userId,
    'timestamp': FieldValue.serverTimestamp(),
  });
}
```

**Expected result:** Scanning a barcode looks up the product instantly. Receiving stock atomically updates the count and logs a movement.

### 4. Build the stock movement log and adjustment flow

On the ProductDetailPage, add a ListView below the product details querying stock_movements where productId equals the current product, ordered by timestamp descending. Each movement row shows the type as a colored badge (green for received, red for sold, blue for adjustment, orange for return), the quantity with plus or minus prefix, the reference, the user who performed it, and the timestamp. Add a Stock Adjustment button for inventory corrections. The adjustment BottomSheet has a DropDown for adjustment reason (damage, theft, count correction, expiry), a quantity TextField (positive or negative), and a notes TextField. Submit creates a stock_movement with type 'adjustment' and updates currentStock with FieldValue.increment of the quantity value.

**Expected result:** A complete audit trail of all stock movements for each product with the ability to make corrections via adjustments.

### 5. Create the dashboard with alerts and inventory value

Create a DashboardPage with summary cards at the top: Total Products count, Total Inventory Value (sum of currentStock times costPrice across all products, calculated by a Custom Function), and Low Stock Count (products where currentStock is at or below reorderLevel). Below the summary, add a Low Stock Alerts section: a ListView querying products where currentStock is less than or equal to reorderLevel, ordered by currentStock ascending. Each alert card shows the product name, current stock in red, reorder level, and a Reorder button. Add a second section for Recent Activity: a ListView of the most recent stock_movements across all products. Optionally add a Custom Widget with fl_chart showing a BarChart of stock value by category.

**Expected result:** A management dashboard with inventory value totals, low-stock alerts for immediate action, and recent activity monitoring.

### 6. Add stock audit and reporting functionality

Create a Stock Audit flow: a page listing all products in a scrollable form where each row shows the product name, system stock count, and a TextField for the physical count entered during a warehouse walk. On submit, compare physical counts against system counts. For mismatches, automatically create stock_movement documents with type 'adjustment' and the difference as quantity. Display a summary report showing total matches, total mismatches, and net variance. Add a Cloud Function for generating reports: query stock_movements for a date range grouped by product, calculate turnover rate (sold quantity divided by average stock), and identify slow-moving items (zero sales in 30 days). Export as CSV to Firebase Storage.

**Expected result:** A stock audit process that reconciles physical counts with system records and generates movement reports.

## Complete code example

File: `FlutterFlow Inventory Management Setup`

```text
FIRESTORE DATA MODEL:
  products/{productId}
    sku: String (unique)
    name: String
    category: String
    currentStock: Integer
    reorderLevel: Integer
    costPrice: Double
    sellPrice: Double
    supplierId: String
    imageUrl: String
    location: String
    lastUpdatedAt: Timestamp

  stock_movements/{movementId}
    productId: String
    type: "received" | "sold" | "adjustment" | "return"
    quantity: Integer (+/-)
    reference: String
    userId: String
    notes: String
    timestamp: Timestamp

PAGE: InventoryPage
WIDGET TREE:
  Column
    ├── Row
    │     ├── TextField (search by name/SKU)
    │     └── IconButton (barcode scan → mobile_scanner)
    ├── ChoiceChips (category filter)
    └── ListView (products, filtered + sorted)
          └── Container (product row)
                ├── Image (product image)
                ├── Column (name + SKU + location)
                ├── Container (stock level: color-coded)
                │     └── Text (currentStock)
                └── Text (costPrice)

PAGE: ProductDetailPage
WIDGET TREE:
  Column
    ├── Container (product info card)
    ├── Row (action buttons)
    │     ├── Button (Receive Stock → BottomSheet)
    │     ├── Button (Adjust Stock → BottomSheet)
    │     └── Button (Record Sale)
    └── ListView (stock movements, ordered by timestamp desc)
          └── Container (movement row)
                ├── Badge (type, color-coded)
                ├── Text (quantity +/-)
                ├── Text (reference)
                └── Text (timestamp)

PAGE: DashboardPage
WIDGET TREE:
  Column
    ├── Row (summary cards)
    │     ├── Container (Total Products)
    │     ├── Container (Inventory Value)
    │     └── Container (Low Stock Count, red)
    ├── Text ("Low Stock Alerts")
    ├── ListView (products where currentStock <= reorderLevel)
    │     └── Container (alert card: name + stock + Reorder button)
    ├── Text ("Recent Activity")
    └── ListView (recent stock_movements, limit 20)
```

## Common mistakes

- **Using read-then-write for stock updates instead of atomic FieldValue.increment** — When two sales happen simultaneously, both read the same stock count, decrement it, and write. One sale's decrement is lost, causing the stock count to drift from reality. Fix: Always use FieldValue.increment(-quantity) for sales and FieldValue.increment(quantity) for receiving. This performs atomic operations that handle concurrent updates correctly.
- **Updating stock levels without creating a movement record** — Without movement records, there is no audit trail. When stock counts don't match physical inventory, you cannot determine what went wrong or when. Fix: Every stock change must create a stock_movement document. Use a Custom Action that performs both the stock update and movement creation together.
- **Setting reorder levels to zero or not setting them at all** — Without meaningful reorder levels, low-stock alerts never trigger until inventory hits zero. By then, it is too late to order new stock and you face stockouts. Fix: Set reorder levels based on lead time and average daily sales. For example, if it takes 5 days to receive new stock and you sell 10 per day, set the reorder level to at least 50.

## Best practices

- Use FieldValue.increment for all stock updates to handle concurrent operations atomically
- Log every stock change as a movement document for a complete audit trail
- Color-code stock levels (green, yellow, red) for instant visual assessment
- Implement barcode scanning for fast product lookup during receiving and audits
- Set meaningful reorder levels based on lead times and sales velocity
- Run periodic stock audits comparing physical counts to system counts
- Calculate inventory value and turnover rates for informed purchasing decisions

## Frequently asked questions

### Can I track inventory across multiple warehouse locations?

Yes. Add a location field to stock_movements and add a per-location stock map on the product document. The dashboard can then show stock breakdown by location and allow transfers between locations as a movement type.

### How do I handle products with variants like size and color?

Create a product_variants subcollection under products with fields for variant name, SKU, and currentStock. Each variant has its own stock level and movement history. The parent product aggregates total stock across all variants.

### Can I generate purchase orders automatically when stock is low?

Yes. Create a Cloud Function triggered by product updates. When currentStock drops to or below reorderLevel, generate a purchase_order document with the product, supplier, and suggested quantity. Notify the purchasing team.

### How do I prevent selling more than available stock?

In the sale Cloud Function, use a Firestore transaction: read currentStock, verify it is greater than or equal to the sale quantity, then decrement. If insufficient, throw an error and show an out-of-stock message to the user.

### Can I import products from a spreadsheet?

Yes. Create a Cloud Function that accepts a CSV file upload, parses each row, and creates product documents in Firestore. Include validation for required fields and duplicate SKU detection.

### Can RapidDev help build an enterprise inventory system?

Yes. RapidDev can implement full inventory platforms with multi-warehouse management, purchase order automation, supplier portals, batch and serial number tracking, demand forecasting, and ERP integrations.

---

Source: https://www.rapidevelopers.com/flutterflow-tutorials/how-to-create-an-inventory-management-system-in-flutterflow
© RapidDev — https://www.rapidevelopers.com/flutterflow-tutorials/how-to-create-an-inventory-management-system-in-flutterflow
