如何基于Flutter与Firebase实现「回顾往昔」推送通知功能?
「Look Back」回溯推送功能优化方案(适配Firebase+Flutter栈)
一、后端核心方案(基于现有Firebase架构,兼顾扩展性与成本)
1. 新条目预约逻辑(保留原构想并优化)
- 触发时机:
Entries集合新增文档时,通过Firestore文档触发器启动Cloud Functions - 处理流程:
- 提取条目的
创建时间与用户ID,计算需预约的回溯周期(如1周、1个月、1年) - 针对每个周期,在
Tasks集合中按{userID}_{周期类型}_{目标日期}(例:user_123_week_20240615)的规则创建/更新任务文档:- 用
FieldValue.increment(1)原子更新entryCount字段,避免并发冲突 - 文档包含
userID、targetTime(结合用户偏好的推送时间)、cycleType、status(待推送/已推送)字段
- 用
- 此规则可避免重复创建任务,减少Firestore写入操作
- 提取条目的
2. 旧条目补预约方案(覆盖历史数据)
通过分批次异步处理实现全量覆盖:
- 创建一次性触发的Cloud Functions,按用户ID哈希值拆分批次(每批次100-200个用户),避免单实例超时
- 对每个用户,查询其所有
Entries文档,按创建时间分组到对应回溯周期 - 按上述
Tasks文档ID规则,批量创建/更新任务,累加每个周期的条目数 - 若后续回溯规则调整,重复执行分批次逻辑即可更新历史任务
3. 定时任务执行优化(提升扩展性)
- 将原每分钟定时任务拆分为按时间分片的触发器:按小时启动Cloud Functions实例,仅处理当前小时内待推送的
Tasks - 查询
Tasks时使用复合查询:where('targetTime', '<=', 当前时间)+where('status', '==', 'pending'),配合预先创建的复合索引提升查询效率 - 对每个符合条件的任务,启动独立的Cloud Functions实例处理:
- 从
Users集合读取用户推送偏好,确认推送权限 - 通过FCM发送汇总通知(例:「您1年前的今天写了3篇日记」)
- 将任务
status更新为sent,并预约下一个周期的任务(如1周周期推送后,预约1个月后的任务)
- 从
4. 成本控制细节
- 为
Tasks集合设置自动过期规则:推送完成30天后自动删除文档,降低存储成本 - 利用Firestore原子操作减少不必要的读取,避免并发更新冲突
- 限制Cloud Functions实例的内存配置(如256MB),降低执行成本
二、客户端辅助方案(补充后端,提升可靠性)
若需客户端层面的补充触发,可采用以下方案(无需用户交互):
- 使用Flutter的
workmanager包(支持iOS/Android)实现后台定时任务:- 客户端每次启动时,注册每日一次的周期性后台任务
- 任务触发时,调用Cloud Functions的Callable函数,检查当前用户是否有遗漏的回溯任务
- iOS端配置:开启
Background Modes中的Remote notifications与Background fetch;Android端配置PeriodicWorkRequest,设置合理的重复间隔 - 注:此方案仅作为后端的补充,核心逻辑仍由后端处理,避免客户端长期未启动导致的推送失效
内容的提问来源于stack exchange,提问作者Eternity
相关产品推荐
相关产品推荐

