import 'package:cloud_firestore/cloud_firestore.dart'; /// Queries assembled across statements, getters and helpers. class NotificationRepository { NotificationRepository(this._firestore) : _receipts = _firestore.collection('notificationReceipts'); final FirebaseFirestore _firestore; final CollectionReference> _receipts; late final CollectionReference> _inbox = _firestore.collection('inbox'); CollectionReference> get _collection => _firestore.collection('notifications'); Stream>> streamUserNotifications( String userId, { bool unreadOnly = false, int? limit, DocumentSnapshot? startAfter, }) { Query> query = _collection.where( 'userId', isEqualTo: userId, ); query = query.orderBy('timestamp', descending: true); if (limit != null && !unreadOnly) { query = query.limit(limit); } if (startAfter != null) { query = query.startAfterDocument(startAfter); } return query.snapshots(); } /// A clause assigned inside the same `if` as the terminal is not optional /// there; an assignment after a terminal cannot reach it. Stream>> platform({ bool onlyActive = false, }) { Query> query = _collection.where( 'userId', isNull: true, ); if (onlyActive) { query = query.where('isActive', isEqualTo: true); return query.snapshots(); } query = query.orderBy('timestamp', descending: true); return query.snapshots(); } Future fallback(Query>? custom) async { await (custom ?? _collection.where('kind', isEqualTo: 'default')).get(); } Future ternaryClause(bool newestFirst) async { final base = _collection.where('isRead', isEqualTo: false); final ordered = newestFirst ? base.orderBy('createdAt', descending: true) : base.orderBy('createdAt'); await ordered.get(); } Future receipts(String userId) async { await _receipts.where('userId', isEqualTo: userId).get(); await _inbox.limit(3).get(); } Query> _buildListingQuery({ required String userId, required String collectionName, }) { return _firestore .collectionGroup(collectionName) .where('userId', isEqualTo: userId) .orderBy('createdAt', descending: true); } Future listingPage(String userId, int pageSize) async { final orderedQuery = _buildListingQuery( userId: userId, collectionName: 'products', ); await orderedQuery.limit(pageSize).get(); } Query> _nested() => _buildListingQuery( userId: 'u', collectionName: 'services', ); Future nestedHelper() async { await _nested().get(); } Future fromParameter(Query> query) async { await query.where('visible', isEqualTo: true).limit(10).get(); } Future inLoops(List ids) async { for (final id in ids) { await _firestore.collection('stores').doc(id).collection('items').get(); } await Future.wait( ids.map( (id) => _firestore .collectionGroup('products') .where('userId', whereIn: [id]).get(), ), ); ids.forEach((id) { _firestore.collection('audit').where('id', isEqualTo: id).get(); }); await Future.wait([_firestore.collection('once').get()]); } } /// A top-level helper returning a query. Query> activeStores(FirebaseFirestore firestore) => firestore.collection('stores').where('active', isEqualTo: true); Future countActiveStores(FirebaseFirestore firestore) async { await activeStores(firestore).count().get(); }