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.ackGraceset: 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
onPostGraceErrorcallback when one is provided (the Firewatch repositories wire theironErrorhandler 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