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

Flutter中Firestore网络断开时如何禁用操作缓存?

解决Firebase事务离线缓存问题,强制网络断开时直接失败

Firebase Firestore默认会缓存离线状态下的写操作(包括事务),待网络恢复后自动执行,这确实会导致你遇到的旧数据引用、批次阻塞等问题。以下是几种可行的解决方案:

1. 执行事务前先检测网络状态

通过第三方包(如connectivity_plus)在发起事务前检查当前网络连接状态,若检测到离线直接抛出错误,不进入Firebase事务流程,从根源避免操作被缓存。

修改你的sendOperations方法示例:

import 'package:connectivity_plus/connectivity_plus.dart';

Future<void> sendOperations(List<SyncedOperationMixin> operations) async {
  // 先检查网络状态
  final connectivityResult = await Connectivity().checkConnectivity();
  if (connectivityResult == ConnectivityResult.none) {
    throw Exception("网络断开,无法发送操作");
  }

  var currentStep = this.currentStepIndex;

  return firestore.runTransaction(
    (transaction) async {
      final currentStepDoc = stepsReference.doc(getStepDocumentName(currentStep + 1));  
      
      // 如果下一个步骤ID对应的文档已存在,需执行变基操作(抛出错误)
    
      // 否则,上传操作
    },
    maxAttempts: 1,
    timeout: const Duration(seconds: 2),
  ).then((r) {
    this.currentStepIndex = currentStep;
  });
}

同时可以监听网络状态变化,在全局层面维护在线状态标识,避免每次事务都重复检测。

2. 禁用Firestore的离线持久化

如果你的应用不需要整体离线功能,可以在初始化Firestore时直接关闭离线持久化,这样所有写操作(包括事务)在离线时会立即失败,不会被缓存。

初始化Firestore的代码示例:

FirebaseFirestore firestore = FirebaseFirestore.instance;
await firestore.setSettings(const Settings(
  persistenceEnabled: false,
));

注意:此设置会影响整个Firestore实例,如果你有其他需要离线支持的功能,需谨慎使用。

3. 结合事务超时与网络监听手动取消

利用timeout和网络状态监听,在检测到网络断开时手动终止事务。可以通过Completer包装事务,一旦监听到离线就触发错误:

Future<void> sendOperations(List<SyncedOperationMixin> operations) async {
  var currentStep = this.currentStepIndex;
  final completer = Completer<void>();

  // 监听网络断开事件
  final subscription = Connectivity().onConnectivityChanged.listen((result) {
    if (result == ConnectivityResult.none && !completer.isCompleted) {
      completer.completeError(Exception("网络断开,事务已取消"));
    }
  });

  try {
    await firestore.runTransaction(
      (transaction) async {
        final currentStepDoc = stepsReference.doc(getStepDocumentName(currentStep + 1));  
        
        // 事务逻辑
      },
      maxAttempts: 1,
      timeout: const Duration(seconds: 2),
    ).then((r) {
      this.currentStepIndex = currentStep;
      completer.complete();
    });
  } catch (e) {
    if (!completer.isCompleted) {
      completer.completeError(e);
    }
  } finally {
    subscription.cancel();
  }

  return completer.future;
}

以上方案中,方案1是最推荐的,它既保留了Firestore的其他离线功能,又能精准控制事务的执行时机,避免缓存问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 19:01:13