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

Flutter接入Firebase时如何实现用户登录1小时后自动登出?

Flutter + Firebase 试用到期自动登出实现方案

客户端侧实现(即时触发)

这是最直接的实现方式,用户登录成功后启动倒计时,到期直接触发对应逻辑:

  • 首先定义全局定时器变量,避免重复创建和内存泄漏
Timer? _trialTimer;
  • 修改enterTrial方法,新增倒计时逻辑
Future enterTrial() async {
  final UserCredential user = await Auth.instance.googleSignInMethod();
  final User actualUser = user.user;
  try {
    //_trial is a collection for users in Trial Period
    await _trial.doc(actualUser.email).set({   
      "name": actualUser.displayName,
      "email": actualUser.email,
      "creationDate": FieldValue.serverTimestamp(),
    });
    // 启动1小时倒计时
    _trialTimer?.cancel(); // 先取消已有计时器避免重复触发
    _trialTimer = Timer(const Duration(hours: 1), () async {
      await _handleTrialExpire(actualUser.email);
    });
  } catch (e) {
    print(e);
  }
}

// 封装统一的试用到期处理逻辑
Future _handleTrialExpire(String? email) async {
  if (email == null) return;
  // 1. 登出当前账号
  await Auth.instance.signOut();
  // 2. 迁移数据到_expired集合
  final trialDoc = await _trial.doc(email).get();
  if (trialDoc.exists) {
    await _expired.doc(email).set(trialDoc.data()!);
    await _trial.doc(email).delete();
  }
  // 此处可自定义弹窗提示用户试用已到期
}
  • 补充前台唤醒校验逻辑,避免APP切后台后定时器被系统暂停导致计时不准
    继承WidgetsBindingObserver监听APP生命周期,每次APP回到前台时直接校验试用时长:
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
  super.didChangeAppLifecycleState(state);
  if (state == AppLifecycleState.resumed) {
    _checkTrialValid();
  }
}

Future _checkTrialValid() async {
  final currentUser = Auth.instance.currentUser;
  if (currentUser?.email == null) return;
  final trialDoc = await _trial.doc(currentUser!.email).get();
  // 不在试用集合直接触发到期逻辑
  if (!trialDoc.exists) {
    await _handleTrialExpire(currentUser.email);
    return;
  }
  final createTime = trialDoc.data()?['creationDate'] as Timestamp?;
  if (createTime == null) return;
  final diff = DateTime.now().difference(createTime.toDate());
  // 试用时长超过1小时触发到期逻辑
  if (diff.inHours >= 1) {
    await _handleTrialExpire(currentUser.email);
  }
}

后端侧兜底实现(避免客户端逻辑被绕过)

客户端逻辑可能被用户修改本地时间、杀进程绕过,建议搭配Firebase云函数做定时校验兜底:

  • 部署定时触发的云函数,每10分钟扫描一次_trial集合,批量迁移到期的试用用户数据
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();

exports.cleanExpiredTrials = functions.pubsub.schedule('every 10 minutes').onRun(async (context) => {
  // 计算1小时前的时间戳
  const oneHourAgo = admin.firestore.Timestamp.fromDate(new Date(Date.now() - 3600 * 1000));
  // 查出所有到期的试用用户
  const expiredTrials = await admin.firestore().collection('_trial').where('creationDate', '<=', oneHourAgo).get();
  // 批量操作提高执行性能
  const batch = admin.firestore().batch();
  expiredTrials.forEach(doc => {
    batch.set(admin.firestore().collection('_expired').doc(doc.id), doc.data());
    batch.delete(doc.ref);
  });
  await batch.commit();
  return null;
});
  • 新增APP冷启动校验逻辑,每次打开APP先校验当前登录用户是否在试用集合,不在则直接登出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 21:36:04