getSnapshot method

  1. @override
Future<SessionSnapshot?> getSnapshot({
  1. String? snapshotId,
  2. String? sessionId,
  3. Map<String, dynamic>? context,
})

Loads a snapshot either by its snapshotId or by sessionId.

Exactly one of snapshotId / sessionId must be provided. A sessionId resolves to the session's latest leaf snapshot (the most recent snapshot that no other snapshot points to as its parent). A branched history (more than one leaf) resolves to the most-recently created leaf by default, or is rejected with StatusCodes.FAILED_PRECONDITION when the store is configured to reject branching.

context carries the ambient request/action context (e.g. the authenticated user) so multi-tenant stores can route reads.

Implementation

@override
Future<SessionSnapshot?> getSnapshot({
  String? snapshotId,
  String? sessionId,
  Map<String, dynamic>? context,
}) {
  final normalized = _normalizeGetSnapshotOptions(snapshotId, sessionId);

  // Reconstruct inside a read-only transaction so the pointer read and the
  // batched shard/diff reads all observe a single, consistent point in time.
  // Without this, a concurrent checkpoint write - which overwrites a
  // checkpoint's shards in place and may delete now-stale trailing shards
  // (see `_writeShards`) - could let a reader stitch together a mix of old
  // and new chunks, yielding a `DATA_LOSS` (missing shard) error or a corrupt
  // JSON decode. A read-only transaction also avoids the contention/retries
  // of a read-write one.
  return db.runTransaction((tx) async {
    final reader = _Reader(tx);

    if (normalized.sessionId != null) {
      final pointerSnap = await tx.get(
        _pointersCol(context).doc(normalized.sessionId!),
      );
      if (!pointerSnap.exists) return null;
      final pointer = _PointerDoc.fromData(pointerSnap.data()!);
      // Reconstruct straight from the pointer's checkpoint metadata - one
      // batched round-trip, no extra read of the leaf document.
      final reconstructed = await _reconstructFrom(
        reader,
        pointer.checkpointId,
        pointer.checkpointShardCount,
        pointer.segmentPath,
        pointer.currentSnapshotId,
        context,
      );
      if (reconstructed == null) return null;
      return _toSnapshot(reconstructed.doc, reconstructed.state);
    }

    final reconstructed = await _reconstruct(
      reader,
      normalized.snapshotId!,
      context,
    );
    if (reconstructed == null) return null;
    return _toSnapshot(reconstructed.doc, reconstructed.state);
  }, transactionOptions: ReadOnlyTransactionOptions());
}