You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 23:34:56