Build a Flutter based Inventory Management System with Realm - Tutorial

To create an inventory management system using Flutter and MongoDB Realm, you can follow these steps:

  1. Set up a new Flutter project and add the necessary dependencies for using MongoDB Realm with Flutter, such as flutter_realm and bson.

  2. Define a data model for the inventory items using Dart classes. You can use the @HiveType() and @HiveField() annotations to define the schema of the data model.

    import 'package:hive/hive.dart';
    
    part 'inventory_item.g.dart';
    
    @HiveType(typeId: 0)
    class InventoryItem {
      @HiveField(0)
      late String name;
    
      @HiveField(1)
      late int quantity;
    
      @HiveField(2)
      late double price;
    
      InventoryItem(this.name, this.quantity, this.price);
    }
    

    In this example, we define an InventoryItem class with fields for the name, quantity, and price of the item. We use the @HiveType() annotation to mark the class as a Hive type, and the @HiveField() annotation to mark the fields as Hive fields. We also generate the necessary code for Hive using the part directive and the inventory_item.g.dart file.

  3. Initialize the Hive database and register the InventoryItem adapter.

    import 'package:hive/hive.dart';
    import 'package:hive_flutter/hive_flutter.dart';
    
    void main() async {
      await Hive.initFlutter();
      Hive.registerAdapter(InventoryItemAdapter());
      runApp(MyApp());
    }
    

    In this example, we initialize the Hive database using Hive.initFlutter() and register the InventoryItemAdapter() using Hive.registerAdapter().

  4. Implement functionality to create, read, update, and delete inventory items using Hive.

    You can use the Box class from Hive to create, read, update, and delete inventory items. For example, you can use the put() method to create or update an inventory item, and the delete() method to delete an inventory item.

    // Create a new inventory item
    final item = InventoryItem('Product 1', 10, 5.0);
    final box = Hive.box<InventoryItem>('inventory');
    box.put('product1', item);
    
    // Read an inventory item
    final item2 = box.get('product1');
    
    // Update an inventory item
    item2?.quantity = 20;
    box.put('product1', item2);
    
    // Delete an inventory item
    box.delete('product1');
    

    In this example, we create a new InventoryItem object and store it in a Hive Box with the key “product1”. We then retrieve the item using the get() method, update its quantity, and store it back in the Box. Finally, we delete the item using the delete() method.

  5. Implement functionality to query the inventory items based on various criteria.

    You can use the Box.values property to get a list of all the inventory items in the Box, and then filter the list based on various criteria using methods such as where(), toList(), and forEach().

    // Get all inventory items
    final items = box.values.toList();
    
    // Filter inventory items by name
    final filteredItems = items.where((item) => item.name.contains('Product'));
    
    // Filter inventory items by quantity
    final lowQuantityItems = items.where((item) => item.quantity < 5);
    
    // Filter inventory
    

Here’s the completed dart code for filtering inventory items based on name and quantity:

import 'package:flutter/material.dart';
import 'package:mongodb_realm/mongodb_realm.dart';

class InventoryScreen extends StatefulWidget {
  @override
  _InventoryScreenState createState() => _InventoryScreenState();
}

class _InventoryScreenState extends State<InventoryScreen> {
  final _inventoryItems = <InventoryItem>[];
  final _filteredInventoryItems = <InventoryItem>[];
  final _nameController = TextEditingController();
  final _quantityController = TextEditingController();

  @override
  void initState() {
    super.initState();
    _loadInventoryItems();
  }

  Future<void> _loadInventoryItems() async {
    final app = RealmApp.getApp(id: 'my-app-id');
    final client = app.getMongoClient('mongodb-atlas');
    final db = client.database('my-db');
    final inventoryCollection = db.collection('inventory');

    final inventoryItems = await inventoryCollection.find().toList();

    setState(() {
      _inventoryItems.clear();
      _inventoryItems.addAll(inventoryItems);
      _filteredInventoryItems.clear();
      _filteredInventoryItems.addAll(inventoryItems);
    });
  }

  void _filterInventoryItems() {
    final name = _nameController.text.trim().toLowerCase();
    final quantity = _quantityController.text.trim().toLowerCase();

    setState(() {
      _filteredInventoryItems.clear();

      if (name.isEmpty && quantity.isEmpty) {
        _filteredInventoryItems.addAll(_inventoryItems);
      } else {
        _filteredInventoryItems.addAll(_inventoryItems.where((item) =>
            item.name.toLowerCase().contains(name) &&
            item.quantity.toString().contains(quantity)));
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Inventory'),
      ),
      body: Column(
        children: [
          Padding(
            padding: EdgeInsets.all(8.0),
            child: Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: _nameController,
                    decoration: InputDecoration(
                      hintText: 'Name',
                    ),
                  ),
                ),
                SizedBox(width: 8.0),
                Expanded(
                  child: TextField(
                    controller: _quantityController,
                    decoration: InputDecoration(
                      hintText: 'Quantity',
                    ),
                  ),
                ),
                SizedBox(width: 8.0),
                ElevatedButton(
                  onPressed: _filterInventoryItems,
                  child: Text('Filter'),
                ),
              ],
            ),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: _filteredInventoryItems.length,
              itemBuilder: (context, index) {
                final item = _filteredInventoryItems[index];
                return ListTile(
                  title: Text(item.name),
                  subtitle: Text('Quantity: ${item.quantity}'),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

class InventoryItem {
  String _id;
  String name;
  int quantity;
  double price;

  InventoryItem({
    this._id,
    this.name,
    this.quantity,
    this.price,
  });

  InventoryItem.fromJson(Map<String, dynamic> json) {
    _id = json['_id'];
    name = json['name'];
    quantity = json['quantity'];
    price = json['price'];
  }

  Map<String, dynamic> toJson() {
    final data = <String, dynamic>{};
    if (_id != null) {
      data['_id'] = _id;
    }
    data['name'] = name;
    data['quantity'] = quantity;
    data['price'] = price;
    return data;
  }
}

Note that this code assumes you have set up the necessary MongoDB Realm authentication and authorization rules and have created a MongoDB Atlas cluster with a database named “my-db” and a collection named “inventory”. You will also need to replace the placeholder Realm App ID with the ID of your actual Realm app. Once you have everything set up and the code is running, users will be able to filter the inventory items by name and/or quantity, and the results will be displayed in a list view.

Here are the items to consider for the Realm side of things:
In addition, you can also use MongoDB Realm to add synchronization to your inventory management system. With MongoDB Realm, you can synchronize the inventory data across multiple devices in real-time, and handle conflicts and errors that may arise during synchronization.

To add synchronization to your inventory management system, you can follow these steps:

  1. Set up a new MongoDB Realm app and create a new Atlas cluster to store the inventory data.

  2. Create a new MongoDB Realm app and configure it to use the Atlas cluster.

  3. Create a new MongoDB Realm application and configure it to use the Atlas cluster.

  4. Define a new Realm schema for the inventory items using the MongoDB Realm schema language.

    const InventoryItemSchema = {
      name: 'InventoryItem',
      properties: {
        _id: 'objectId',
        name: 'string',
        quantity: 'int',
        price: 'double',
      },
      primaryKey: '_id',
    };
    

    In this example, we define a new Realm schema for the InventoryItem object, with fields for the _id, name, quantity, and price of the item. We also specify the primary key as _id.

  5. Add synchronization to the inventory items using MongoDB Realm Sync.

    You can use the MongoDB Realm Sync feature to synchronize the inventory data across multiple devices in real-time. To do this, you can create a new MongoDB Realm Sync configuration and enable it for the InventoryItem object. You can also set up conflict resolution and error handling rules to handle conflicts and errors that may arise during synchronization.

    const InventoryItemSync = {
      name: 'InventoryItem',
      schema: InventoryItemSchema,
      sync: {
        partitionValue: 'inventory',
      },
    };
    
    realmApp.sync.register(InventoryItemSync);
    

    In this example, we create a new MongoDB Realm Sync configuration for the InventoryItem object, with a partition value of “inventory”. We then register the configuration with the MongoDB Realm Sync service using the realmApp.sync.register() method.

  6. Implement functionality to create, read, update, and delete inventory items using MongoDB Realm Sync.

    With MongoDB Realm Sync, you can use the same Realm APIs to create, read, update, and delete inventory items as you would without synchronization. However, when you perform these operations, the data will be automatically synchronized across all devices that are connected to the MongoDB Realm Sync service.

    // Create a new inventory item
    let item = InventoryItem()
    item.name = "Product 1"
    item.quantity = 10
    item.price = 5.0
    try! realm.write {
      realm.add(item)
    }
    
    // Read an inventory item
    let items = realm.objects(InventoryItem.self)
    let item2 = items.first
    
    // Update an inventory item
    try! realm.write {
      item2?.quantity = 20
    }
    
    // Delete an inventory item
    try! realm.write {
      realm.delete(item2!)
    }
    

    In this example, we use the Realm APIs to create, read, update, and delete inventory items. We first create a new InventoryItem object and add it to the Realm using the realm.add() method. We then retrieve the item using the realm.objects() method, update its quantity, and save the changes using the realm.write() method. Finally, we delete the item using the realm.delete() method.