readSnapshot function
readValue, with the snapshot's child order kept.
The façade's get() needs it: DataSnapshot.children is ordered, and the
value on its own is not.
Implementation
Future<DbSnapshot?> readSnapshot(
String path, {
DbQuery? query,
Duration settle = const Duration(milliseconds: 400),
Duration timeout = const Duration(seconds: 15),
}) async {
final completer = Completer<DbSnapshot?>();
DbSnapshot? last;
var seen = false;
Timer? quiet;
final source = query == null ? onValue(path) : onQueryValue(path, query);
final sub = source.listen(
(s) {
last = s;
seen = true;
quiet?.cancel();
quiet = Timer(settle, () {
if (!completer.isCompleted) completer.complete(last);
});
},
onError: (Object e) {
if (!completer.isCompleted) completer.completeError(e);
},
);
try {
return await completer.future.timeout(
timeout,
onTimeout: () => seen ? last : null,
);
} finally {
quiet?.cancel();
await sub.cancel();
}
}