Flutter食品应用定时通知被覆盖问题求助
问题分析
你遇到的核心问题是通知ID重复,导致新添加的产品通知覆盖了旧的。flutter_local_notifications插件中,相同ID的定时通知会被后续同名ID的通知覆盖,这就是仅最后一个产品通知生效的原因。
你的代码里final notificationId = context.read<int>();存在明显错误:没有正确的Provider提供int类型实例,这行代码要么运行报错,要么每次获取到同一个值,完全没实现“唯一ID”的效果——你原本想用UniqueKey().hashCode生成唯一ID,但实际代码里并没有这么做。
解决步骤
1. 生成真正唯一的通知ID
推荐两种可靠方案:
- 方案一:绑定产品唯一标识(推荐):如果产品存储时会生成唯一文档ID(比如Firebase Firestore的document ID),直接用该ID的哈希值或转成整数作为通知ID,既能保证ID与产品一一对应,后续删除产品时也能方便取消对应通知。
- 方案二:用UUID生成全局唯一ID:通过
uuid包生成唯一字符串,再转为整数(插件的schedule方法要求ID为int类型)。
2. 修正代码错误
步骤一:添加依赖(若用UUID方案)
在pubspec.yaml中添加:
dependencies: uuid: ^3.0.7
步骤二:修改CandyAddPage代码
把通知ID的生成逻辑移到点击添加按钮的时机,确保每次添加产品时生成新的唯一ID:
import 'package:uuid/uuid.dart'; class _CandyAddPageState extends State<CandyAddPage> { String? _title; DateTime? _expDate; final _uuid = const Uuid(); @override Widget build(BuildContext context) { return BlocProvider( create: (context) => CandyPageCubit(CandyDocumentsRepository(CandyRemoteDataSource())), child: BlocBuilder<CandyPageCubit, CandyPageState>( builder: (context, state) { return Scaffold( appBar: AppBar( backgroundColor: const Color.fromARGB(255, 0, 51, 54), title: Text(AppLocalizations.of(context)!.addProduct), actions: [ IconButton( onPressed: _title == null || _expDate == null ? null : () async { // 生成唯一通知ID final notificationId = _uuid.v4().hashCode; // 添加产品时同步存储通知ID,方便后续管理 await context .read<CandyPageCubit>() .add(_title!, _expDate!, notificationId); // 调度通知 await context.read<CandyPageCubit>().scheduleNotification( _expDate!, context, _title, notificationId); Navigator.of(context).pop(); }, icon: const Icon(Icons.check), ), ], ), body: _AddPageBody( onTitleChanged: (newValue) { setState(() { _title = newValue; }); }, onDateChanged: (newValue) { setState(() { _expDate = newValue; }); }, selectedDateFormated: _expDate == null ? null : DateFormat.yMMMd().format(_expDate!), ), ); }, ), ); } }
步骤三:更新CandyPageCubit的add方法
确保添加产品时将notificationId作为字段存入数据库,方便后续管理通知:
// 示例CandyPageCubit的add方法 Future<void> add(String title, DateTime expDate, int notificationId) async { // 存储产品时同步保存notificationId await _repository.addCandy(title, expDate, notificationId); }
3. 额外注意事项
- 避免用临时
UniqueKey().hashCode:UniqueKey是Widget级别的,页面重建时可能生成重复哈希值,且无法与产品关联,后续无法管理通知。 - 验证ID唯一性:调度通知前打印notificationId,确认每次值都不同。
- 处理过期时间:添加判断逻辑,若
scheduleNotificationDateTime是过去的时间,插件不会触发通知,需提示用户或调整通知时间。
内容的提问来源于stack exchange,提问作者SimplePerson17
相关产品推荐
相关产品推荐

