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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 17:13:10