本地时间大于Firebase存储时间时仅重启App才打印如何实时触发
问题原因
你的代码目前使用get()方法单次拉取Firestore文档数据,仅在调用getTheTime()时执行一次时间判断,没有持续监听云端数据变化、也没有定时校验本地时间是否达标的逻辑,因此只有重启应用重新调用方法时才会触发判断。另外原代码中DateTime.now().isAfter()是同步方法,额外添加的await属于无用代码。
解决方案
需要同时实现两个逻辑达成实时触发效果:
- 用Firestore实时快照监听器,持续监听云端时间文档的变更,自动更新本地存储的触发时间阈值
- 启动周期性计时器,按所需精度定期校验当前本地时间是否超过触发阈值,满足条件时立即执行打印逻辑
实现代码
import 'dart:async'; import 'package:cloud_firestore/cloud_firestore.dart'; // 存储触发时间的全局/类成员变量 DateTime? _timeToTrigger; // 计时器实例,页面/功能销毁时需要释放 Timer? _checkTimer; // 初始化监听逻辑,在应用启动/对应页面初始化时调用即可 void initTimeListener() { // 1. 开启Firestore文档实时监听,云端时间修改时自动同步到本地 FirebaseFirestore.instance .collection("TimeToChange") .doc("Time") .snapshots() .listen((DocumentSnapshot doc) { if (doc.exists) { _timeToTrigger = doc["currentTime"].toDate(); // 同步到新的时间后立刻做一次判断 _checkTime(); } }); // 2. 启动周期性校验计时器,这里设置为每秒校验一次,可按需调整间隔 _checkTimer = Timer.periodic(const Duration(seconds: 1), (timer) { _checkTime(); }); } // 统一的时间判断逻辑 void _checkTime() { if (_timeToTrigger != null && DateTime.now().isAfter(_timeToTrigger!)) { print("After Time"); // 如果仅需要触发一次,打印后可取消计时器避免资源浪费 // _checkTimer?.cancel(); } } // 页面/功能销毁时调用,释放资源 void disposeListener() { _checkTimer?.cancel(); } // 原有保存时间到Firestore的逻辑可保持不变 saveTimeToFireStrone() async { await FirebaseFirestore.instance.collection("TimeToChange").doc("Time").set({ "currentTime": atSixInEvening }); }
注意事项
- 时间校验的间隔可根据你的业务精度需求调整,不需要秒级触发的话可以改成分钟级,降低性能消耗
- 如果存在跨时区的使用场景,建议统一使用UTC时间存储和校验,避免时区不同导致的判断错误
内容的提问来源于stack exchange,提问作者Ewan1276243123
相关产品推荐
相关产品推荐

