WriteAckPolicy class

Controls how long a Firewatch write waits for the Firestore server acknowledgement before resolving optimistically.

Why this exists

Firestore write futures (set, update, delete, add, WriteBatch.commit) complete only when the server acknowledges the write. While offline, the write is durably queued in Firestore's local mutation queue (and is visible to local reads immediately), but the future does not complete until connectivity returns — potentially never within the app session.

That interacts badly with command_it Commands: a Command whose wrapped function never completes stays isRunning forever, run() silently no-ops while a previous execution is in flight, and runAsync() returns the original hung future. Because repositories are typically cached (in a registry or DI container), one offline write permanently bricks that Command for the rest of the session — every later invocation is silently dropped.

Semantics

  • ackGrace == null (the default): current/legacy behavior. Write futures await the server ack indefinitely. Fully backwards compatible.
  • ackGrace set: the write future is raced against the grace duration.
    • If the server ack (or an error) arrives before the grace elapses, the future completes normally — success resolves, errors throw.
    • If the grace elapses first, the future resolves successfully. This is optimistic-resolve, not failure: the write is already committed to Firestore's local mutation queue and will sync when connectivity returns. It is not server-confirmed — a rules rejection or invalid write can still fail later. An error arriving after the grace can no longer throw (the future has already resolved); it is reported fire-and-forget to the onPostGraceError callback when one is provided (the Firewatch repositories wire their onError handler here), otherwise swallowed.

Guidance

  • Apps that want offline-safe writes should pass a grace of ~1–2 seconds: long enough that online writes normally resolve with a real server ack, short enough that offline writes don't hang UI or Commands.
  • Transactions are not covered by this policy — Firestore transactions require connectivity and have no offline mutation-queue semantics.
  • "Resolved" under a grace means durably queued locally, will sync — do not treat it as proof the server accepted the write. If you need server confirmation (e.g. security-rule-sensitive writes), use the default policy or verify via a snapshot listener.
Annotations

Constructors

WriteAckPolicy({Duration? ackGrace})
Creates a write-ack policy.
const

Properties

ackGrace Duration?
How long to wait for the server ack before resolving optimistically.
final
hashCode int
The hash code for this object.
no setteroverride
isGraced bool
Whether this policy resolves writes optimistically after ackGrace.
no setter
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

apply<T>(Future<T> write, {required T onTimeout(), FirewatchErrorHandler? onPostGraceError}) Future<T>
Applies this policy to write.
applyVoid(Future<void> write, {FirewatchErrorHandler? onPostGraceError}) Future<void>
apply specialized for Future<void> writes (the common case).
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() String
A string representation of this object.
override

Operators

operator ==(Object other) bool
The equality operator.
override