use*_*856 5 firebase flutter google-cloud-firestore
当使用该方法获取集合的所有文档时,默认情况下,如果没有互联网连接,它不会抛出异常。相反,它查找缓存并返回缓存的数据。但有时您需要知道集合当前是否实际上为空或Firestore
get()
您只是无法连接到数据库。
对于仅获取数据,有一个解决方案:GetOptions
可以将参数设置为Source.server
。这样,如果无法访问服务器,就会抛出错误。
现在我正在寻找与此选项等效的方法,该snapshots()
方法返回 aStream
而不仅仅是单个数据。所以我需要流在无法连接到服务器时发出错误。
所以:
await _firestore
.collection('stuff')
.where("someBool", isEqualTo: false)
.get(const GetOptions(source: Source.server));
Run Code Online (Sandbox Code Playgroud)
将抛出一个FirebaseException
错误连接,同时:
_firestore
.collection('stuff')
.where("someBool", isEqualTo: false)
.snapshots()
.listen((snap) { ... }, onError: (e) {
//never called...
debugPrint(e.toString());
});
Run Code Online (Sandbox Code Playgroud)
在这个例子中我就是找不到。
我得到的最接近的解决方案是检查snap.metadata.isFromCache
并在值为 时抛出异常true
。但这并不可靠。False 表示保证快照与服务器保持同步。但在某些情况下,true
即使它从服务器获得了有效响应也是如此。
编辑:如果我在本地过滤而不是直接在查询中isFromCache
过滤,属性将是一个解决方案。someBool
_firestore
.collection('stuff')
.where("someBool", isEqualTo: false)
.snapshots(includeMetadataChanges: true)
.listen((snap) {
//`hasPendingWrites` is false in all these cases:
// 1. changing a document's `someBool` field from `false` to `true` and vise versa
// 2. requesting with server connection
// 3. requesting without server connection
debugPrint("snap metadata pendingWrites is: ${snap.metadata.hasPendingWrites}");
if (snap.metadata.isFromCache) {
//I thought data from cache is only used when there's trouble connecting to the server which is not the case:
//
//no internet connection will indeed cause this value to be true
//but changing a document's `someBool` field from `false` to `true` however, will cause it to be true, too
debugPrint("metadata of this snap is from cache -> throwing NoInternetException");
throw NoInternetException();
}
}, onError: (e) {
//never called...
debugPrint(e.toString());
});
Run Code Online (Sandbox Code Playgroud)
编辑:我禁用了离线持久性:
db.settings = const Settings(persistenceEnabled: false);
Run Code Online (Sandbox Code Playgroud)
实验:更新文档的someBool
字段(直接来自Firestore Console
):
有互联网:
true 到 false: pendingWrites
是false
, isFromCache
是false
假到真: pendingWrites
是false
, isFromCache
是true
Stream
当正在收听时关闭互联网时:
pendingWrites
伊斯兰false
国 isFromCache
true
因此,互联网上的“假对真”案例会导致使用该会员的误报isFromCache
。
编辑:
文档指出:
如果您调用 [DocumentReference.snapshots] 或 [Query.snapshots] 并将
includeMetadataChanges
参数设置为,一旦客户端从后端收到最新数据,true
您将收到另一个快照。isFomCache
false
现在,在这种误报情况下(将布尔值设置为false
to true
),Stream
会触发两次:
isFromCache
:true
isFromCache
:false
因此,由于某种原因,即使存在与服务器的连接,Firestore 也会从缓存中读取数据。所以在投掷时我不能依赖这个属性NoInternetException
。
即使您的应用暂时失去网络连接,Firebase 应用程序也能正常运行。此外,Firebase 还提供了用于在本地保存数据、管理状态和处理延迟的工具。
例如,您可以像这样检查互联网连接, 检测连接状态
final connectedRef = FirebaseDatabase.instance.ref(".info/connected");
connectedRef.onValue.listen((event) {
final connected = event.snapshot.value as bool? ?? false;
if (connected) {
debugPrint("Connected.");
} else {
debugPrint("Not connected.");
}
});
Run Code Online (Sandbox Code Playgroud)
有关更多详细信息,您可以查看此链接:- https://firebase.google.com/docs/database/flutter/offline-capability
对于特别是 firestore 你可以遵循这个,
db
.collection('stuff')
.where("someBool", isEqualTo: false)
.snapshots(includeMetadataChanges: true)
.listen((querySnapshot) {
for (var change in querySnapshot.docChanges) {
if (change.type == DocumentChangeType.added) {
final source =
(querySnapshot.metadata.isFromCache) ? "local cache" : "server";
print("Data fetched from $source}");
}
}
});
Run Code Online (Sandbox Code Playgroud)
有关更多详细信息,请点击此链接(对于 firestore):- https://firebase.google.com/docs/firestore/manage-data/enable-offline#dart_2
归档时间: |
|
查看次数: |
1517 次 |
最近记录: |