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

基于Flutter的Firebase Cloud Messaging订阅到期精准推送问题咨询

实现用户独立订阅到期推送方案

基于你已经完成的FCM基础配置,以下是实现用户独立订阅到期提醒的具体方案:

一、用户订阅数据存储设计

首先需要建立用户订阅信息的存储,推荐使用Firebase Firestore(和FCM生态无缝整合),每个用户的订阅文档需包含以下核心字段:

  • user_id:关联Firebase Auth的用户唯一ID
  • expire_at:订阅到期时间(用Timestamp格式存储,方便时间查询)
  • fcm_token:用户设备的FCM推送令牌
  • reminder_sent:布尔值,标记是否已推送到期提醒(避免重复推送)

Flutter端同步订阅数据的示例代码:

// 假设用户已完成登录,获取当前用户ID
final userId = FirebaseAuth.instance.currentUser?.uid;
if (userId != null) {
  // 获取当前设备的FCM令牌
  final fcmToken = await FirebaseMessaging.instance.getToken();
  if (fcmToken != null) {
    // 写入/更新用户订阅信息
    await FirebaseFirestore.instance.collection('user_subscriptions').doc(userId).set({
      'expire_at': Timestamp.fromDate(DateTime.now().add(const Duration(days: 30))), // 示例:30天订阅
      'fcm_token': fcmToken,
      'reminder_sent': false,
    }, SetOptions(merge: true));
  }
}

二、到期检测与推送触发逻辑

使用Firebase云函数(Cloud Functions)配合定时触发器,自动扫描并推送提醒,无需依赖客户端逻辑:

  1. 创建定时触发的云函数,比如每天运行一次(或根据需求调整频率,比如每10分钟)
  2. 在函数中查询符合条件的用户:订阅到期时间在当前时间范围内(比如接下来24小时内,或精准到期时间前后5分钟)、且未推送过提醒
  3. 生成FCM推送消息,批量推送给目标用户,同时更新reminder_sent字段为true

云函数示例(Node.js):

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

// 每天运行一次,检查即将到期的订阅
exports.sendSubscriptionExpiryReminders = functions.pubsub.schedule('every 24 hours').timeZone('Asia/Shanghai').onRun(async (context) => {
  const now = new Date();
  // 查询未来24小时内到期且未推送提醒的用户
  const expiryThreshold = new Date(now.getTime() + 24 * 60 * 60 * 1000);
  
  const snapshot = await admin.firestore()
    .collection('user_subscriptions')
    .where('expire_at', '<=', expiryThreshold)
    .where('reminder_sent', '==', false)
    .get();

  const pushMessages = [];
  const updatePromises = [];

  snapshot.forEach(doc => {
    const subscriptionData = doc.data();
    // 构造FCM推送消息
    pushMessages.push({
      token: subscriptionData.fcm_token,
      notification: {
        title: '订阅到期提醒',
        body: 'Hello, your subscription is expired!',
      },
      // 可选:添加自定义数据,方便客户端处理
      data: {
        type: 'subscription_expiry',
        userId: doc.id
      }
    });
    // 标记为已推送
    updatePromises.push(doc.ref.update({ reminder_sent: true }));
  });

  // 批量更新状态和推送消息
  if (pushMessages.length > 0) {
    await Promise.all([
      admin.messaging().sendAll(pushMessages),
      ...updatePromises
    ]);
    functions.logger.info(`成功推送${pushMessages.length}条订阅到期提醒`);
  }

  return null;
});

三、确保精准推送的核心逻辑

要避免误推或重复推送,需严格执行以下几点:

  • 唯一绑定:每个订阅文档与用户ID、FCM令牌一一对应,确保推送目标准确
  • 状态标记:reminder_sent字段必须在推送后立即更新,防止同一用户被多次推送
  • 精准查询:通过Firestore的时间范围查询筛选目标用户,只针对符合条件的用户生成推送任务
  • 令牌有效性:推送后若收到FCM返回的令牌失效错误,需从数据库中移除该令牌,避免后续无效推送

四、Flutter端的消息接收与处理

确保APP在前台、后台甚至杀死状态下都能收到推送:

  1. 配置本地通知插件(比如flutter_local_notifications),处理前台消息展示
  2. 监听FCM令牌刷新事件,及时同步到数据库,避免令牌失效导致推送失败

示例代码:

// 监听前台FCM消息
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
  final notification = message.notification;
  if (notification != null) {
    // 展示本地通知
    flutterLocalNotificationsPlugin.show(
      notification.hashCode,
      notification.title,
      notification.body,
      const NotificationDetails(
        android: AndroidNotificationDetails(
          'subscription_notification_channel',
          '订阅通知',
          channelDescription: '用于推送订阅到期提醒',
          importance: Importance.max,
          priority: Priority.high,
        ),
      ),
    );
  }
});

// 监听FCM令牌刷新,同步到数据库
FirebaseMessaging.instance.onTokenRefresh.listen((newToken) {
  final userId = FirebaseAuth.instance.currentUser?.uid;
  if (userId != null) {
    FirebaseFirestore.instance.collection('user_subscriptions').doc(userId).update({
      'fcm_token': newToken,
    });
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 23:53:35