FirestoreCollectionGroupRepository<T extends JsonModel> class

A Firestore collection-group repository for responsive UIs:

  • Queries across all collections with the same name via collectionGroup()
  • Reacts to auth changes and extra dependencies
  • Supports live queries (subscribe) or one-shot fetches
  • Exposes pagination via a live "window" (limit that grows with loadMore)
  • Keeps per-item notifiers keyed by full document path

Unlike FirestoreCollectionRepository, this repo accepts a Query builder instead of a CollectionReference builder. Because collection-group queries return a Query (not a CollectionReference), .add() is unavailable. Write commands use full document paths instead of document IDs.

Works with or without authentication. Omit authUid for public collection groups that should query Firestore immediately without waiting for a signed-in user.

⚠️ Security: a collection-group query reads documents with the given name across every parent/tenant. This repo passes the current uid to queryRefBuilder but does not add any owner filter for you. Scope the query yourself — e.g. fs.collectionGroup('tasks').where('ownerId', isEqualTo: uid) — and back it with a matching collection-group security rule. An unfiltered builder will read other users' documents.

The auth-reactive lifecycle (cache-first swap, epoch-guarded races, live window resizing, sign-out handling, disposal) lives in QueryListRepositoryBase, shared with FirestoreCollectionRepository. This repo keys items by full document path so same-ID documents under different parents don't collide.

Inheritance

Constructors

FirestoreCollectionGroupRepository({required T fromJson(Map<String, dynamic>), required QueryRefBuilder queryRefBuilder, FirebaseFirestore? firestore, QueryMutator? queryBuilder, AuthUidListenable? authUid, List<Listenable> dependencies = const [], bool subscribe = true, int pageSize = 25, bool paginate = true, FirewatchErrorHandler? onError, WriteAckPolicy writeAckPolicy = const WriteAckPolicy()})
Creates a new FirestoreCollectionGroupRepository.

Properties

currentUserUid String?
The current user UID (or null when signed out / public).
no setterinherited
delete → Command<String, void>
Deletes a document by its full path.
latefinal
epoch int
Epoch counter used to discard stale async operations. Every swap/resize captures the current epoch and bails if it changes (a newer swap, or dispose, ran in the meantime).
getter/setter pairinherited
errorHandler FirewatchErrorHandler?
The error handler passed at construction, if any. Exposed so subclasses can route write-path errors (e.g. post-grace ack failures under a graced WriteAckPolicy) to the same handler the stream/fetch paths use.
no setterinherited
fs → FirebaseFirestore
finalinherited
hasError bool
true when the most recent fetch ended in a terminal error.
no setterinherited
hashCode int
The hash code for this object.
no setterinherited
hasInitialized ValueNotifier<bool>
Whether the repository has completed its first query.
finalinherited
hasListeners bool
Whether any listeners are currently registered.
no setterinherited
hasMore ValueNotifier<bool>
Whether there are more documents beyond the current page.
finalinherited
isAuthGated bool
Whether this repo requires authentication. True when an auth source was provided; false for public/unauthenticated repos.
no setterinherited
isFromCache ValueNotifier<bool>
Whether the most recent snapshot was served from the local cache rather than confirmed by the server (snapshot.metadata.isFromCache).
finalinherited
isInitializing bool
true when the first query has not yet completed.
no setterinherited
isLoading ValueNotifier<bool>
Whether the repository is currently fetching data from Firestore.
finalinherited
isRefreshing bool
true when a subsequent fetch is in progress after initial load.
no setterinherited
lastError ValueNotifier<Object?>
The last terminal fetch error, or null when the most recent fetch succeeded (or none has completed yet).
finalinherited
patch → Command<GroupPatch, void>
Partially updates specific fields on an existing document.
latefinal
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
set → Command<({T model, String path}), void>
Creates or merges a document at a specific path.
latefinal
showEmpty bool
true when initialization is complete, loading is done, the list is empty, and the emptiness is genuine (the fetch did not fail — see lastError). A failed fetch leaves value empty too; without the error check an "add your first item" CTA would show over a load failure.
no setterinherited
sub StreamSubscription<Object?>?
The active snapshot subscription, if any.
getter/setter pairinherited
update → Command<({T model, String path}), void>
Replaces all fields on an existing document.
latefinal
value List<T>
The current value stored in this notifier.
getter/setter pairinherited
writeAckPolicy WriteAckPolicy
The server-ack policy applied to every write on this repository (Commands and *Direct writes).
final

Methods

addListener(VoidCallback listener) → void
Register a closure to be called when the object changes.
inherited
cancelSub() Future<void>
Cancel the active subscription, awaiting the cancel. Used on sign-out so the native Firestore listener is fully torn down before the auth token is invalidated (otherwise the dying listener can fire PERMISSION_DENIED against the revoked token).
inherited
cancelSubAsync() → void
Cancel the active subscription without blocking the hot path. Safe for auth/query/dependency changes where ordering with the native layer does not matter (the epoch guard discards any late events).
inherited
deleteDirect(String path) Future<void>
Deletes a document without the Command single-execution guard.
dispose() → void
Tears down the shared lifecycle. Subclasses override dispose to dispose their own Commands and then call super.dispose().
guardAuth() → void
Throws if the repo is auth-gated and there is no signed-in user.
inherited
keyOf(DocumentSnapshot<Map<String, dynamic>> doc) String
Collection groups can contain same-ID documents under different parents, so the full document path is the cache/notifier key.
loadMore() Future<void>
Load the next page. In realtime mode this increases the live window.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
notifierFor(String key) ValueNotifier<T?>
Per-item notifier (kept in sync from the results), keyed by keyOf.
inherited
notifyListeners() → void
Call all the registered listeners.
inherited
patchDirect(GroupPatch p) Future<void>
Partially updates fields without the Command single-execution guard.
queryBase(String? uid) → Query<Map<String, dynamic>>
Resolves the base query (before queryBuilder and the live-window limit) for the given uid.
refresh() Future<void>
Re-fetch using current auth, deps, and query, keeping the already-loaded list visible while the fetch is in flight.
inherited
removeListener(VoidCallback listener) → void
Remove a previously registered closure from the list of closures that are notified when the object changes.
inherited
resetPages() Future<void>
Reset to the first page (useful when filters change).
inherited
setDirect(({T model, String path}) input) Future<void>
Creates or merges a document without the Command single-execution guard.
setQuery(QueryMutator? qb) → void
Swap the active query; pass null to clear and use the base query.
inherited
start() → void
Runs the initial query. Subclasses call this at the end of their constructor (after their own fields are initialized).
inherited
toString() String
A string representation of this object.
inherited
updateDirect(({T model, String path}) input) Future<void>
Fully updates a document without the Command single-execution guard.

Operators

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