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

使用Flutter集成Supabase时网络故障的处理方案咨询

Flutter集成Supabase的网络异常处理方案

一、查询(Select)场景处理

  • 调用前网络检查:使用connectivity_plus库检测当前网络状态,确认存在WiFi或移动网络后再发起查询。
  • ClientException重试逻辑:捕获异常后,监听网络状态变化流,待网络恢复后自动重试。可结合指数退避策略(比如重试间隔1s、3s、5s)避免频繁请求,示例代码如下:
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:supabase/supabase.dart';

Future<List<Map<String, dynamic>>> safeQuery(String tableName) async {
  // 预检查网络
  final connResult = await Connectivity().checkConnectivity();
  if (connResult == ConnectivityResult.none) {
    throw Exception("当前无可用网络");
  }

  try {
    return await supabase.from(tableName).select();
  } on ClientException {
    // 监听网络恢复事件
    await for (final result in Connectivity().onConnectivityChanged) {
      if (result != ConnectivityResult.none) {
        // 重试查询(可添加指数退避逻辑)
        return await supabase.from(tableName).select();
      }
    }
    rethrow;
  }
}

二、插入/更新(Insert/Update)场景处理

这类操作涉及数据持久化,遇到ClientException时无法直接判断操作是否完成,需从幂等性设计和结果验证两方面解决:

核心疑问解答

  • Supabase(PostgreSQL后端)不会自动回滚已执行的操作:如果请求已到达服务器并完成执行,即使网络中断导致响应未返回,数据也已持久化;只有当请求未到达服务器,或服务器执行过程中抛出数据库异常时,操作才会回滚。
  • 如何确认操作状态?推荐以下两种方案:

方案1:实现幂等操作(最优)

给每个插入/更新请求生成唯一客户端ID(如UUID),在数据表中新增client_id字段并设置唯一约束。重试时复用该ID:

  • 若重试时触发唯一约束报错,说明操作已执行完成;
  • 若未报错,说明之前的请求未到达服务器,重试有效。

示例代码:

import 'package:uuid/uuid.dart';

Future<void> safeInsert(String tableName, Map<String, dynamic> data) async {
  final connResult = await Connectivity().checkConnectivity();
  if (connResult == ConnectivityResult.none) {
    throw Exception("当前无可用网络");
  }

  final clientId = const Uuid().v4();
  final requestData = {...data, 'client_id': clientId};

  try {
    await supabase.from(tableName).insert(requestData);
  } on ClientException catch (e) {
    // 检查是否为client_id唯一约束冲突
    if (e.message.contains('unique constraint') && e.message.contains('client_id')) {
      return; // 操作已完成,无需重试
    }
    // 网络恢复后重试
    await for (final result in Connectivity().onConnectivityChanged) {
      if (result != ConnectivityResult.none) {
        await supabase.from(tableName).insert(requestData);
        return;
      }
    }
    rethrow;
  }
}

方案2:重试后查询验证

若无法修改数据表结构,可在重试操作后,通过业务唯一标识(如用户ID、订单号)查询数据,判断操作是否成功。但此方案在高并发场景下可能存在误差,仅作为备选。

三、通用网络处理建议

  • 封装统一的API调用工具类,将网络检查、异常捕获、重试逻辑集中实现,减少重复代码;
  • 监听全局网络状态,在网络断开时向用户展示提示,网络恢复后自动处理待重试的操作(可通过队列管理);
  • 关键操作添加加载状态提示,避免用户重复触发请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 09:37:54