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
-
- Object
- ChangeNotifier
- ValueNotifier<
List< T> > - FirestoreCollectionGroupRepository
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
nullwhen 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
-
truewhen 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
-
truewhen the first query has not yet completed.no setterinherited -
isLoading
→ ValueNotifier<
bool> -
Whether the repository is currently fetching data from Firestore.
finalinherited
- isRefreshing → bool
-
truewhen a subsequent fetch is in progress after initial load.no setterinherited -
lastError
→ ValueNotifier<
Object?> -
The last terminal fetch error, or
nullwhen 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
-
truewhen initialization is complete, loading is done, the list is empty, and the emptiness is genuine (the fetch did not fail — seelastError). A failed fetch leavesvalueempty 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
*Directwrites).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_DENIEDagainst 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< doc) → StringString, dynamic> > - 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
queryBuilderand the live-window limit) for the givenuid. -
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
nullto 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