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

Flutter中如何从table_calendar或Cloud Firestore发送日程提醒?

两种日程提醒实现方案(Flutter + table_calendar + Cloud Firestore)

两种方式都可行,且Cloud Functions完全可以配合Firestore实现服务端触发的提醒,下面是具体实现思路和代码示例:

一、基于table_calendar/Flutter客户端的提醒

核心逻辑

在客户端通过定时检查从Firestore拉取的日程数据,当事件临近时触发本地通知。依赖客户端运行环境,APP被彻底杀死后普通定时任务会失效,可借助后台任务插件优化。

实现步骤

  1. 集成本地通知插件(比如flutter_local_notifications),完成初始化配置。
  2. 从Firestore拉取用户的所有日程事件,存储到本地列表。
  3. 用Timer或Workmanager(处理后台任务)定时扫描事件列表,对比当前时间与事件开始时间的差值。
  4. 当差值达到预设提醒阈值(比如提前1小时),调用本地通知插件弹出提醒。

代码示例

import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin();

// 初始化本地通知
Future<void> initNotifications() async {
  const AndroidInitializationSettings androidSettings = AndroidInitializationSettings('@mipmap/ic_launcher');
  const InitializationSettings settings = InitializationSettings(android: androidSettings);
  await _notificationsPlugin.initialize(settings);
}

// 从Firestore获取用户日程
Future<List<Map<String, dynamic>>> getEvents() async {
  QuerySnapshot snapshot = await FirebaseFirestore.instance
      .collection('user_events')
      .where('userId', isEqualTo: '当前用户ID')
      .get();
  return snapshot.docs.map((doc) => doc.data() as Map<String, dynamic>).toList();
}

// 定时检查并发送提醒
void startReminderChecker() {
  // 每5分钟检查一次
  Timer.periodic(const Duration(minutes: 5), (timer) async {
    List<Map<String, dynamic>> events = await getEvents();
    DateTime now = DateTime.now();

    for (var event in events) {
      DateTime eventStartTime = (event['startTime'] as Timestamp).toDate();
      int timeDiff = eventStartTime.difference(now).inMinutes;

      // 提前1小时触发提醒
      if (timeDiff <= 60 && timeDiff > 0) {
        await _notificationsPlugin.show(
          event['id'].hashCode,
          '日程提醒',
          '您的「${event['title']}」即将开始',
          const NotificationDetails(
            android: AndroidNotificationDetails(
              'event_reminder_channel',
              '日程提醒频道',
              importance: Importance.high,
              priority: Priority.high,
            ),
          ),
        );
      }
    }
  });
}

二、基于Cloud Firestore + Cloud Functions的服务端提醒

核心逻辑

借助Cloud Functions的定时触发器或实时数据触发器,扫描Firestore中的日程事件,通过FCM(Firebase Cloud Messaging)向用户设备推送提醒。不受客户端APP状态影响,可靠性更高。

实现步骤

  1. 在Firebase控制台启用Cloud Functions和FCM服务。
  2. 编写Cloud Functions代码:
    • 定时触发器:每隔固定时间(比如1小时)扫描所有未发送提醒的事件,判断是否临近,发送FCM推送。
    • 实时触发器:当新日程被添加到Firestore时,计算提醒时间,延迟触发推送。
  3. 在Flutter客户端集成FCM,接收推送并展示本地通知。

代码示例(Node.js)

const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();

// 定时触发器:每小时检查一次即将到来的日程
exports.sendEventReminders = functions.pubsub.schedule('every 1 hours').onRun(async (context) => {
  const now = new Date();
  const oneHourLater = new Date(now.getTime() + 60 * 60 * 1000);

  // 查询1小时内要开始、且未发送过提醒的事件
  const eventsSnapshot = await admin.firestore()
    .collection('user_events')
    .where('startTime', '>=', now)
    .where('startTime', '<=', oneHourLater)
    .where('reminderSent', '==', false)
    .get();

  const taskPromises = [];
  eventsSnapshot.forEach(doc => {
    const event = doc.data();
    // 构造FCM推送消息
    const fcmMessage = {
      notification: {
        title: '即将到来的日程',
        body: `「${event.title}」将在1小时后开始`
      },
      token: event.userFcmToken // 提前存储用户的FCM令牌
    };

    // 发送推送+标记提醒已发送
    taskPromises.push(admin.messaging().send(fcmMessage));
    taskPromises.push(doc.ref.update({reminderSent: true}));
  });

  return Promise.all(taskPromises);
});

方案对比

  • 客户端方案:实现简单,无需额外服务端开发,但依赖APP后台存活能力,适合对提醒可靠性要求较低的场景。
  • 服务端方案:不受客户端状态限制,提醒送达率更高,但需要编写Cloud Functions代码,适合需要稳定提醒的核心场景。

内容的提问来源于stack exchange,提问作者LostTexan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 21:12:43