I have a problem with my flutter app. I want to be able to scan ingredients from a ingredient list and then match it against my database to see potentially harmful products. For this I used a live video field, where images are fed into ocr, but it seems to perform bad in comparison to other solutions, I get some items, but longer names like "c14-16 olefin sulfonate" can't be matched. Here is an example of my result string:

I/flutter (19923): NOSUCONES
I/flutter (19923): YEE
I/flutter (19923): AOUA (HAIERO, SODIUM CI4-16 OLEN SULFORAIE COHERPL
I/flutter (19923): COMEEOPA BUTGOSPEMUMPARSEABTE9N
I/flutter (19923): TAMN B9), WHCH MMN B3), CYANCCOBALAN

I/flutter (19923): NOARFINNOPARABENS
I/flutter (19923): IAQUA NAIE SOOIUM CA 16 QLEFIN SUKFONATE (OCAMDOROPL
I/flutter (19923): oHLATES -
I/flutter (19923): NO PROPYLENE GLYCOL

I/flutter (19923): PROPYLENE GLYCOL
I/flutter (19923): DENTS: AOUA WATER) SOOIUM C4-16 0LEFIN SUFONATE COCURYL
I/flutter (19923): ID (VEAMINEN MTANIN B32 OAN

Here is the relevant part of my code:

import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:csv/csv.dart';

class DatabaseHelper {
  static final DatabaseHelper instance = DatabaseHelper._init();
  static Database? _database;

  DatabaseHelper._init();

  Future<Database> get database async {
    if (_database != null) return _database!;
    _database = await _initDB('ingredients.db');
    return _database!;
  }

  Future<Database> _initDB(String filePath) async {
    final dbPath = await getDatabasesPath();
    final path = join(dbPath, filePath);

    return await openDatabase(
      path,
      version: 2,
      onCreate: _createDB,
      onUpgrade: _onUpgrade,
    );
  }

  Future<void> _createDB(Database db, int version) async {
    await db.execute('''
      CREATE TABLE ingredients (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        ingredient_name TEXT NOT NULL UNIQUE,
        ingredient_type TEXT NOT NULL,
        cg_approval_status TEXT,
        notes TEXT,
        is_cationic INTEGER NOT NULL
      )
    ''');

    await db.execute(
        'CREATE INDEX idx_ingredient_name ON ingredients (ingredient_name)');

    await _importCSVData(db);
  }

  Future<void> _onUpgrade(Database db, int oldVersion, int newVersion) async {
    // Handle future schema changes here
    await _importCSVData(db);
  }

  Future<void> _importCSVData(Database db) async {
    try {
      final String csvData =
          await rootBundle.loadString('assets/ingredients.csv');
      final List<List<dynamic>> csvTable =
          const CsvToListConverter().convert(csvData);

      await db.transaction((txn) async {
        for (var i = 1; i < csvTable.length; i++) {
          final row = csvTable[i];
          await txn.rawInsert('''
            INSERT OR REPLACE INTO ingredients 
            (ingredient_name, ingredient_type, cg_approval_status, notes, is_cationic)
            VALUES (?, ?, ?, ?, ?)
          ''', [
            row[0],
            row[1],
            row[2],
            row[3],
            row[4] == 'true' ? 1 : 0,
          ]);
        }
      });
    } catch (e) {
      print('Error importing CSV data: $e');
    }
  }

  Future<List<Map<String, dynamic>>> fetchIngredientsDetails(
      List<String> ingredients) async {
    final db = await database;
    final lowercasedIngredients =
        ingredients.map((e) => e.toLowerCase()).toList();

    try {
      final List<Map<String, dynamic>> results = await db.query(
        'ingredients',
        where:
            'LOWER(ingredient_name) IN (${List.filled(lowercasedIngredients.length, '?').join(',')})',
        whereArgs: lowercasedIngredients,
      );
      return results;
    } catch (e) {
      print('Error fetching ingredient details: $e');
      return [];
    }
  }

  Future<void> closeDatabase() async {
    final db = await instance.database;
    await db.close();
    _database = null;
  }

  Future<void> resetDatabase() async {
    final db = await instance.database;
    await db.transaction((txn) async {
      await txn.delete('ingredients');
      await _importCSVData(db);
    });
  }
}

import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:csv/csv.dart';

class DatabaseHelper {
  static final DatabaseHelper instance = DatabaseHelper._init();
  static Database? _database;

  DatabaseHelper._init();

  Future<Database> get database async {
    if (_database != null) return _database!;
    _database = await _initDB('ingredients.db');
    return _database!;
  }

  Future<Database> _initDB(String filePath) async {
    final dbPath = await getDatabasesPath();
    final path = join(dbPath, filePath);

    return await openDatabase(
      path,
      version: 2,
      onCreate: _createDB,
      onUpgrade: _onUpgrade,
    );
  }

  Future<void> _createDB(Database db, int version) async {
    await db.execute('''
      CREATE TABLE ingredients (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        ingredient_name TEXT NOT NULL UNIQUE,
        ingredient_type TEXT NOT NULL,
        cg_approval_status TEXT,
        notes TEXT,
        is_cationic INTEGER NOT NULL
      )
    ''');

    await db.execute(
        'CREATE INDEX idx_ingredient_name ON ingredients (ingredient_name)');

    await _importCSVData(db);
  }

  Future<void> _onUpgrade(Database db, int oldVersion, int newVersion) async {
    // Handle future schema changes here
    await _importCSVData(db);
  }

  Future<void> _importCSVData(Database db) async {
    try {
      final String csvData =
          await rootBundle.loadString('assets/ingredients.csv');
      final List<List<dynamic>> csvTable =
          const CsvToListConverter().convert(csvData);

      await db.transaction((txn) async {
        for (var i = 1; i < csvTable.length; i++) {
          final row = csvTable[i];
          await txn.rawInsert('''
            INSERT OR REPLACE INTO ingredients 
            (ingredient_name, ingredient_type, cg_approval_status, notes, is_cationic)
            VALUES (?, ?, ?, ?, ?)
          ''', [
            row[0],
            row[1],
            row[2],
            row[3],
            row[4] == 'true' ? 1 : 0,
          ]);
        }
      });
    } catch (e) {
      print('Error importing CSV data: $e');
    }
  }

  Future<List<Map<String, dynamic>>> fetchIngredientsDetails(
      List<String> ingredients) async {
    final db = await database;
    final lowercasedIngredients =
        ingredients.map((e) => e.toLowerCase()).toList();

    try {
      final List<Map<String, dynamic>> results = await db.query(
        'ingredients',
        where:
            'LOWER(ingredient_name) IN (${List.filled(lowercasedIngredients.length, '?').join(',')})',
        whereArgs: lowercasedIngredients,
      );
      return results;
    } catch (e) {
      print('Error fetching ingredient details: $e');
      return [];
    }
  }

  Future<void> closeDatabase() async {
    final db = await instance.database;
    await db.close();
    _database = null;
  }

  Future<void> resetDatabase() async {
    final db = await instance.database;
    await db.transaction((txn) async {
      await txn.delete('ingredients');
      await _importCSVData(db);
    });
  }
}


Do you know about any alternatives that might perform better? Or are there some other options that could improve the systems scanning functionality?