FirestoreSessionStore class

A Firestore-backed SessionStore that persists session snapshots as incremental JSON Patch diffs anchored to periodic, sharded full-state checkpoints.

Storage layout (the <prefix> segment is the per-tenant prefix returned by snapshotPathPrefix, or "global" when none is configured):

  • <collection>/<prefix>/snapshots/<snapshotId> - one document per snapshot. A diff document holds the patch from its parent (statePatch); a checkpoint document holds a full-state materialization (sharded out of band).
  • <collection>-shards/<prefix>/shards/<checkpointId>_<index> - the sharded full state for a checkpoint.
  • <collection>-pointers/<prefix>/pointers/<sessionId> - one document per session pointing at the latest leaf snapshot and the metadata needed to reconstruct it.

Reconstruction uses only document-ID lookups (getAll), so it needs no secondary indexes and is strongly consistent. No single document approaches the 1 MiB limit (state is sharded by shardSize), and the number of diff documents touched per read/write is bounded by checkpointInterval rather than total session length.

Emulator

The underlying google_cloud_firestore client honors the FIRESTORE_EMULATOR_HOST environment variable (e.g. localhost:8080), so a store created with the default Firestore instance transparently targets a local emulator when that variable is set.

Real-time changes

Unlike the JS port (which uses Firestore's live onSnapshot listener), the Dart Firestore client has no real-time listener, so onSnapshotStateChange is implemented by polling. Tune the latency via the snapshotWatchPollInterval constructor argument.

Project ID

The default Firestore instance uses Application Default Credentials, but ADC alone does not always carry a project ID. If the client cannot discover one it throws at read/write time with "Project ID has not been discovered yet". To avoid this, either set the GOOGLE_CLOUD_PROJECT environment variable (often required even when ADC is present) or pass an explicit Firestore instance configured with a project ID to the constructor.

Annotations
  • @experimental

Constructors

FirestoreSessionStore({Firestore? db, String collection = 'genkit-sessions', int checkpointInterval = defaultCheckpointInterval, int shardSize = defaultShardSize, String snapshotPathPrefix(Map<String, dynamic>? context)?, Duration snapshotWatchPollInterval = _defaultSnapshotWatchPollInterval})
Creates a Firestore-backed session store.

Properties

checkpointInterval → int
Number of turns between full-state checkpoints.
final
collection → String
The root collection snapshot documents are stored under.
final
db → Firestore
The Firestore instance backing this store.
final
hashCode → int
The hash code for this object.
no setterinherited
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
shardSize → int
Maximum size in bytes of a single shard / diff document.
final
snapshotPathPrefix → String Function(Map<String, dynamic>? context)?
Derives the per-tenant prefix from the call's context.
final

Methods

getLatestSnapshotMetadata(String sessionId, {Map<String, dynamic>? context}) → Future<SessionSnapshot?>
SessionStore.getSnapshot by sessionId (the session's latest leaf) without the state: the same resolution, the same null-if-none contract, and a row with state null. The resolved sessionId is carried on the returned row even for a row that stored it only under state.
getSnapshot({String? snapshotId, String? sessionId, Map<String, dynamic>? context}) → Future<SessionSnapshot?>
Loads a snapshot either by its snapshotId or by sessionId.
getSnapshotMetadata(String snapshotId, {Map<String, dynamic>? context}) → Future<SessionSnapshot?>
SessionStore.getSnapshot by snapshotId without the state: the returned row carries every other field as stored, with state null, and the same null-if-not-found contract.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
onSnapshotStateChange(String snapshotId, void callback(SessionSnapshot snapshot), {Map<String, dynamic>? context}) → void Function()?
Watches a snapshot for state changes via polling and invokes callback with the reconstructed snapshot whenever it changes.
saveSnapshot(String? snapshotId, SnapshotMutator mutator, {Map<String, dynamic>? context}) → Future<String?>
Atomically reads the current snapshot (if snapshotId is provided), passes it to mutator, and persists the result.
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited