Flutter中sqflite+Riverpod数据持久化失效,重启APP数据丢失求助
问题分析与修复方案
1. 数据库字段名大小写不匹配
建表语句中定义的字段是CoffeeName和CoffeePrice(首字母大写),但插入和查询时使用的是coffeeName和coffeePrice(首字母小写)。SQLite在iOS系统中对字段名大小写敏感,这会导致数据无法正确写入或读取。
修复方法:统一字段名的大小写,建议全部使用小写:
修改建表语句:
return db.execute( 'CREATE TABLE cart_provider(id TEXT PRIMARY KEY, coffee_image TEXT, coffee_name TEXT, coffee_price REAL)');
同时更新插入和查询的字段名:
- 插入时:
{ 'id': coffee.id, 'coffee_image': coffee.coffeeImage, 'coffee_name': coffee.coffeeName, 'coffee_price': coffee.coffeePrice, }
- 查询时:
Coffee( id: row['id'] as String, coffeeImage: row['coffee_image'] as String, coffeeName: row['coffee_name'] as String, coffeePrice: (row['coffee_price'] as num).toDouble(), )
2. 异步方法返回值错误
addCoffee和removeCoffee方法使用了async但返回void,这会导致调用者无法等待数据库操作完成,可能出现状态更新与数据库不同步的情况。应改为返回Future<void>:
Future<void> addCoffee(Coffee coffee) async { // 原有逻辑代码 } Future<void> removeCoffee(Coffee coffee) async { // 原有逻辑代码 }
3. SQLite数值类型转换问题
SQLite中REAL类型读取后是num类型,直接强制转换为double可能引发类型错误,应先转为num再调用toDouble():
coffeePrice: (row['coffee_price'] as num).toDouble(),
4. 确保Coffee类重写==和hashCode
state.contains(coffee)依赖对象的相等性判断,需要在Coffee类中重写==和hashCode,否则会判断引用而非内容相等:
class Coffee { final String id; final String coffeeImage; final String coffeeName; final double coffeePrice; Coffee({ required this.id, required this.coffeeImage, required this.coffeeName, required this.coffeePrice, }); @override bool operator ==(Object other) => identical(this, other) || other is Coffee && runtimeType == other.runtimeType && id == other.id && coffeeImage == other.coffeeImage && coffeeName == other.coffeeName && coffeePrice == other.coffeePrice; @override int get hashCode => id.hashCode ^ coffeeImage.hashCode ^ coffeeName.hashCode ^ coffeePrice.hashCode; }
5. 数据库版本更新(可选)
如果已经运行过旧版本代码,需要更新数据库版本号来触发表重建:
final db = await sql.openDatabase( path.join(dbPath, 'coffee.db'), onCreate: (db, version) { // 新的建表语句 }, onUpgrade: (db, oldVersion, newVersion) { // 删除旧表并重建 db.execute('DROP TABLE IF EXISTS cart_provider'); db.execute('CREATE TABLE cart_provider(id TEXT PRIMARY KEY, coffee_image TEXT, coffee_name TEXT, coffee_price REAL)'); }, version: 2, // 版本号从1改为2 );
完成以上修改后,重启应用即可正常保存和读取数据。
内容的提问来源于stack exchange,提问作者Ehsan Javdan
相关产品推荐
相关产品推荐

