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

本地时间大于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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 14:15:07