diff --git a/packages/cloud_firestore/CHANGELOG.md b/packages/cloud_firestore/CHANGELOG.md index fd9832e776a2..0dd48a7d10c7 100644 --- a/packages/cloud_firestore/CHANGELOG.md +++ b/packages/cloud_firestore/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.12.6 + +* Support for `orderBy` on map fields (e.g. `orderBy('cake.flavor')`) for + `startAtDocument`, `startAfterDocument`, `endAtDocument`, and `endBeforeDocument` added. + ## 0.12.5+2 * Automatically use version from pubspec.yaml when reporting usage to Firebase. diff --git a/packages/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/cloudfirestore/CloudFirestorePlugin.java b/packages/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/cloudfirestore/CloudFirestorePlugin.java index c1229732e136..d0606a262ec3 100644 --- a/packages/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/cloudfirestore/CloudFirestorePlugin.java +++ b/packages/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/cloudfirestore/CloudFirestorePlugin.java @@ -129,7 +129,16 @@ private Object[] getDocumentValues( if (orderBy != null) { for (List order : orderBy) { String orderByFieldName = (String) order.get(0); - data.add(documentData.get(orderByFieldName)); + if (orderByFieldName.contains(".")) { + String[] fieldNameParts = orderByFieldName.split("\\."); + Map current = (Map) documentData.get(fieldNameParts[0]); + for (int i = 1; i < fieldNameParts.length - 1; i++) { + current = (Map) current.get(fieldNameParts[i]); + } + data.add(current.get(fieldNameParts[fieldNameParts.length - 1])); + } else { + data.add(documentData.get(orderByFieldName)); + } } } data.add((boolean) arguments.get("isCollectionGroup") ? document.get("path") : documentId); diff --git a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart index 44525bae76c9..8926dcd0dcc4 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -210,5 +210,44 @@ void main() { await doc1.delete(); await doc2.delete(); }); + + test('pagination with map', () async { + // Populate the database with two test documents. + final CollectionReference messages = firestore.collection('messages'); + final DocumentReference doc1 = messages.document(); + // Use document ID as a unique identifier to ensure that we don't + // collide with other tests running against this database. + final String testRun = doc1.documentID; + await doc1.setData({ + 'cake': { + 'flavor': {'type': 1, 'test_run': testRun} + } + }); + + final DocumentSnapshot snapshot1 = await doc1.get(); + final DocumentReference doc2 = await messages.add({ + 'cake': { + 'flavor': {'type': 2, 'test_run': testRun} + } + }); + + QuerySnapshot snapshot; + List results; + + // One pagination call is enough as all of the pagination methods use the same method to get data internally. + snapshot = await messages + .orderBy('cake.flavor.type') + .where('cake.flavor.test_run', isEqualTo: testRun) + .startAtDocument(snapshot1) + .getDocuments(); + results = snapshot.documents; + + expect(results.length, 2); + expect(results[0].data['cake']['flavor']['type'], 1); + expect(results[1].data['cake']['flavor']['type'], 2); + + await doc1.delete(); + await doc2.delete(); + }); }); } diff --git a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m index de1620ebef6b..a18c809d4098 100644 --- a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m +++ b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m @@ -32,7 +32,17 @@ for (id item in orderBy) { NSArray *orderByParameters = item; NSString *fieldName = orderByParameters[0]; - [values addObject:[documentData objectForKey:fieldName]]; + if ([fieldName rangeOfString:@"."].location != NSNotFound) { + NSArray *fieldNameParts = [fieldName componentsSeparatedByString:@"."]; + NSDictionary *currentMap = [documentData objectForKey:[fieldNameParts objectAtIndex:0]]; + for (int i = 1; i < [fieldNameParts count] - 1; i++) { + currentMap = [currentMap objectForKey:[fieldNameParts objectAtIndex:i]]; + } + [values addObject:[currentMap objectForKey:[fieldNameParts + objectAtIndex:[fieldNameParts count] - 1]]]; + } else { + [values addObject:[documentData objectForKey:fieldName]]; + } } } if (isCollectionGroup) { diff --git a/packages/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/pubspec.yaml index e5b397b914db..9c70101f356f 100755 --- a/packages/cloud_firestore/pubspec.yaml +++ b/packages/cloud_firestore/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for Cloud Firestore, a cloud-hosted, noSQL database live synchronization and offline support on Android and iOS. author: Flutter Team homepage: https://github.com/flutter/plugins/tree/master/packages/cloud_firestore -version: 0.12.5+2 +version: 0.12.6 flutter: plugin: