diff --git a/firestore/lib/src/firestore_logger.dart b/firestore/lib/src/firestore_logger.dart index 674d0fd..3c4cbd2 100644 --- a/firestore/lib/src/firestore_logger.dart +++ b/firestore/lib/src/firestore_logger.dart @@ -624,6 +624,9 @@ class DocumentReferenceLogger } } } + + @override + Future> listCollections() => ref.listCollections(); } class TransactionLogger with TransactionMixin implements Transaction { @@ -745,6 +748,10 @@ class FirestoreLogger @override FirestoreService get service => firestore.service; + + @override + Future> listCollections() => + firestore.listCollections(); } class FirestoreServiceLogger diff --git a/firestore_sembast/lib/src/firestore_sembast.dart b/firestore_sembast/lib/src/firestore_sembast.dart index a786808..9732b87 100644 --- a/firestore_sembast/lib/src/firestore_sembast.dart +++ b/firestore_sembast/lib/src/firestore_sembast.dart @@ -50,6 +50,9 @@ class FirestoreServiceSembast @override bool get supportsTrackChanges => true; + + @override + bool get supportsListCollections => true; } FirestoreServiceSembast? _firestoreServiceSembastMemory; @@ -300,6 +303,25 @@ class FirestoreSembast extends Object @override FirestoreService get service => firestoreService; + + @override + Future> listCollections() async { + var db = await ready; + + var ids = {}; + for (var record in await docStore.find(db)) { + final recordPath = record.key; + + final parentPath = url.dirname(recordPath); + print(parentPath); + var collParentPath = url.dirname(parentPath); + print(collParentPath); + if (collParentPath == '.') { + ids.add(basename(parentPath)); + } + } + return ids.map((e) => collection(e)).toList(); + } } class WriteBatchSembast extends WriteBatchBase implements WriteBatch { @@ -449,6 +471,24 @@ class DocumentReferenceSembast extends FirestoreReferenceBase @override Stream onSnapshot({bool includeMetadataChanges = false}) => firestoreSembast.onSnapshot(this); + + @override + Future> listCollections() async { + var db = await firestoreSembast.ready; + + print('path: $path'); + var ids = {}; + for (var record in await docStore.find(db)) { + final recordPath = record.key; + // print('recordPath: $recordPath'); + final parentPath = url.dirname(recordPath); + var collParentPath = url.dirname(parentPath); + if (collParentPath == path) { + ids.add(basename(parentPath)); + } + } + return ids.map((e) => collection(e)).toList(); + } } class CollectionReferenceSembast extends QuerySembast diff --git a/firestore_test/lib/firestore_test.dart b/firestore_test/lib/firestore_test.dart index 08df4b1..3ce7e98 100644 --- a/firestore_test/lib/firestore_test.dart +++ b/firestore_test/lib/firestore_test.dart @@ -14,6 +14,9 @@ import 'package:tekartik_firebase_firestore_test/utils_query_test.dart'; import 'package:tekartik_firebase_firestore_test/utils_test.dart'; import 'package:test/test.dart'; +import 'list_collections_test.dart'; + +var testsRefPath = 'tests/tekartik_firestore/tests'; bool skipConcurrentTransactionTests = false; List docsKeys(List snashots) => @@ -114,8 +117,6 @@ void runApp( } }); group('firestore', () { - var testsRefPath = 'tests/tekartik_firestore/tests'; - timestampGroup(service: firestoreService, firestore: firestore); CollectionReference? getTestsRef() { return firestore.collection(testsRefPath); @@ -1808,6 +1809,7 @@ void runApp( .select([]); expect((await query.get()).docs, isNotEmpty); }, skip: true); + runListCollectionsTest(firestore: firestore); }); } diff --git a/firestore_test/lib/list_collections_test.dart b/firestore_test/lib/list_collections_test.dart new file mode 100644 index 0000000..521970c --- /dev/null +++ b/firestore_test/lib/list_collections_test.dart @@ -0,0 +1,32 @@ +// ignore_for_file: inference_failure_on_collection_literal + +import 'package:path/path.dart'; +import 'package:tekartik_firebase_firestore/firestore.dart'; +// ignore: implementation_imports +import 'package:tekartik_firebase_firestore_test/utils_test.dart'; +import 'package:test/test.dart'; + +void runListCollectionsTest({ + required Firestore firestore, +}) { + test('list root collections', () async { + var collectionId = 'tekartik_test_root_collection'; + var doc = firestore.doc('$collectionId/doc'); + await doc.set({}); + var collections = await firestore.listCollections(); + var collection = + collections.firstWhere((element) => element.id == collectionId); + expect(collection.path, collectionId); + await doc.delete(); + }, solo: true, skip: !firestore.service.supportsListCollections); + + test('list doc collections', () async { + var parent = url.join(testsRefPath, 'tekartik_test_collection'); + var collectionId = 'sub'; + var doc = firestore.doc('$parent/$collectionId/doc'); + await doc.set({}); + var collections = await firestore.doc(parent).listCollections(); + expect(collections.map((e) => e.id), contains(collectionId)); + await doc.delete(); + }, skip: !firestore.service.supportsListCollections); +} diff --git a/firestore_test/lib/utils_collection_test.dart b/firestore_test/lib/utils_collection_test.dart index 68368e6..b915dec 100644 --- a/firestore_test/lib/utils_collection_test.dart +++ b/firestore_test/lib/utils_collection_test.dart @@ -21,6 +21,7 @@ void runUtilsCollectionTests( Future findInCollection() async { var querySnapshot = await ref.get(); for (var doc in querySnapshot.docs) { + devPrint('doc ${doc.ref.path}'); if (doc.ref.path == itemDoc.path) { return true; }