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
相关产品推荐
相关产品推荐

