Skip to content

Commit

Permalink
feat: rest support for list collections
Browse files Browse the repository at this point in the history
  • Loading branch information
alextekartik committed Aug 21, 2023
1 parent b4beabd commit 01dad4f
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 4 deletions.
5 changes: 5 additions & 0 deletions firestore_rest/lib/src/document_reference_rest.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ class DocumentReferenceRestImpl
@override
Future update(Map<String, Object?> data) =>
firestoreRestImpl.updateDocument(path, data);

@override
Future<List<CollectionReference>> listCollections() async {
return firestoreRestImpl.listDocumentCollections(path);
}
}

class DocumentSnapshotRestImpl
Expand Down
71 changes: 71 additions & 0 deletions firestore_rest/lib/src/firestore_rest_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,74 @@ class FirestoreRestImpl
rethrow;
}
}

@override
Future<List<CollectionReference>> listCollections() async {
var request = api.ListCollectionIdsRequest();
var parent = getDocumentRootName();
var collections = <CollectionReference>[];
try {
while (true) {
// Debug
if (debugRest) {
print('listCollections: ${jsonPretty(request.toJson())}');
}
// devPrint('commitRequest: ${jsonPretty(request.toJson())}');

// ignore: unused_local_variable
var response = await firestoreApi.projects.databases.documents
.listCollectionIds(request, parent);
print('response: ${jsonPretty(response.toJson())}');
var stepCollections = (response.collectionIds ?? <String>[])
.map((e) => collection(e))
.toList();
if (stepCollections.isEmpty) {
break;
}
collections.addAll(stepCollections);
if (response.nextPageToken == null) {
break;
}
request.pageToken = response.nextPageToken;
}
} catch (e) {
if (e is api.DetailedApiRequestError) {
// devPrint(e.status);
if (e.status == httpStatusCodeNotFound) {
// return DocumentSnapshotRestImpl(this, null);
}
}
rethrow;
}
return collections;
}

Future<List<CollectionReference>> listDocumentCollections(String path) async {
var request = api.ListCollectionIdsRequest();
var parent = getDocumentName(path);
try {
// Debug
if (debugRest) {
print('listCollections: ${jsonPretty(request.toJson())}');
}
// devPrint('commitRequest: ${jsonPretty(request.toJson())}');

// ignore: unused_local_variable
var response = await firestoreApi.projects.databases.documents
.listCollectionIds(request, parent);
return (response.collectionIds ?? <String>[])
.map((e) => collection(e))
.toList();
} catch (e) {
if (e is api.DetailedApiRequestError) {
// devPrint(e.status);
if (e.status == httpStatusCodeNotFound) {
// return DocumentSnapshotRestImpl(this, null);
}
}
rethrow;
}
}
}

class FirestoreServiceRestImpl
Expand Down Expand Up @@ -752,6 +820,9 @@ class FirestoreServiceRestImpl

@override
bool get supportsTrackChanges => false;

@override
bool get supportsListCollections => true;
}

/// Join ignoring null but not both!
Expand Down
13 changes: 10 additions & 3 deletions firestore_test/lib/list_collections_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,30 @@ import 'package:test/test.dart';
void runListCollectionsTest({
required Firestore firestore,
}) {
// firestore = firestore.debugQuickLoggerWrapper();
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();
print('Existing root collections: $collections');
await doc.set({});
collections = await firestore.listCollections();
print('New root collections: $collections');
var collection =
collections.firstWhere((element) => element.id == collectionId);
expect(collection.path, collectionId);
await doc.delete();
}, solo: true, skip: !firestore.service.supportsListCollections);
}, 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();
print('Existing collections: $collections');
await doc.set({});
collections = await firestore.doc(parent).listCollections();
print('New collections: $collections');
expect(collections.map((e) => e.id), contains(collectionId));
await doc.delete();
}, skip: !firestore.service.supportsListCollections);
Expand Down
1 change: 0 additions & 1 deletion firestore_test/lib/utils_collection_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ void runUtilsCollectionTests(
Future<bool> 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;
}
Expand Down

0 comments on commit 01dad4f

Please sign in to comment.