Skip to content

Barcode Nutrition Scanning in Flutter

With the mobile_scanner package and the barcode lookup endpoint, a Flutter app can go from camera frame to logged meal in one request. As with any mobile client, route API calls through your backend so the key stays server-side.

Scanner widget

scan_screen.dart
MobileScanner(
  onDetect: (capture) async {
    final barcode = capture.barcodes.firstOrNull?.rawValue;
    if (barcode == null) return;
    final food = await FoodApi.lookupBarcode(barcode);
    if (food == null) {
      // 404, offer manual search instead
      Navigator.pushNamed(context, '/search');
    } else {
      Navigator.pushNamed(context, '/log', arguments: food);
    }
  },
)

Typed lookup client

food_api.dart
class FoodApi {
  static const _base = 'https://your-backend.example.com/api';

  static Future<BarcodeFood?> lookupBarcode(String upc) async {
    final res = await http.get(Uri.parse('$_base/barcode/$upc'));
    if (res.statusCode == 404) return null;
    if (res.statusCode != 200) {
      throw ApiException(res.statusCode, res.body);
    }
    return BarcodeFood.fromJson(jsonDecode(res.body));
  }
}

class BarcodeFood {
  final String name;
  final String? brand;
  final double? energyKcalPer100g;

  BarcodeFood({required this.name, this.brand, this.energyKcalPer100g});

  factory BarcodeFood.fromJson(Map<String, dynamic> json) => BarcodeFood(
        name: json['product']['name'],
        brand: json['product']['brand'],
        energyKcalPer100g:
            (json['nutrition_per_100g']?['energy_kcal'] as num?)?.toDouble(),
      );
}

Handling nulls and misses

  • Label data varies by product, nutrition fields the source lacks are null, not omitted. Model them as nullable.
  • A 404 means neither the local catalog nor Open Food Facts knows the code, fall back to text search.
  • nutrition_per_serving is only present when the source provides serving data; per-100g values are always your safe base.

Frequently asked questions

Does the API care which scanner package I use?

No, it only needs the raw UPC/EAN digits. mobile_scanner is a well-maintained option, but any camera/barcode library that yields the code string works.

Do I need separate handling for local-catalog vs Open Food Facts products?

No. The response shape is normalized regardless of source, so one model class covers both.

Related resources