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

Flutter Firestore无网络时仅指定Source.server才抛FirebaseException是否正常?

问题解答

1. 该现象属于Firebase Firestore SDK的预期行为

Firestore默认的get()方法使用Source.serverAndCache的拉取策略,执行逻辑如下:

  • 优先尝试从服务端拉取最新数据
  • 若服务端拉取失败(无网络、权限错误等),自动降级查询本地离线缓存
  • 若缓存中也没有对应集合的存储数据,直接返回空的QuerySnapshot,不会抛出异常

你显式指定GetOptions(source: Source.server)后,SDK不会走缓存降级逻辑,服务端请求失败就会直接抛出FirebaseException,符合你预期的表现。

2. 区分空返回场景的两种方案

方案1:强制走服务端拉取(适合需要最新数据的场景)

就是你已经用到的写法,显式指定拉取源为服务端,通过异常捕获判断网络/请求失败场景,正常返回空快照即代表服务端集合真实为空。

try {
  return await FirebaseFirestore.instance.collection("songs")
      .get(const GetOptions(source: Source.server));
} on FirebaseException catch (e) {
  log(e.toString());
  // 此处可判断为网络请求失败,返回对应业务状态
  return null;
}

方案2:通过快照元数据判断(适合保留缓存降级能力的场景)

QuerySnapshot自带的metadata.isFromCache字段可以标识当前快照的数据来源:

  • 若空快照的isFromCache为true:说明数据来自本地缓存,属于网络请求失败、缓存无数据的场景
  • 若空快照的isFromCache为false:说明数据来自服务端,属于集合真实为空的场景
    示例代码如下:
try {
  final snapshot = await FirebaseFirestore.instance.collection("songs").get();
  if (snapshot.docs.isEmpty) {
    if (snapshot.metadata.isFromCache) {
      // 网络异常且无本地缓存
    } else {
      // 服务端集合确实为空
    }
  }
  return snapshot;
} on FirebaseException catch (e) {
  log(e.toString());
  return null;
}

注意:isFromCache为true仅代表当前快照不是服务端最新同步结果,极端情况下也可能是刚触发拉取、SDK还没完成同步导致,若需要100%准确判断请求结果,优先使用方案1。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 06:45:01