From 023ed318cf9556516182ddc708e0d22de61aa4a2 Mon Sep 17 00:00:00 2001 From: creativecreatorormaybenot <19204050+creativecreatorormaybenot@users.noreply.github.com> Date: Sun, 30 Jun 2019 13:33:41 +0000 Subject: [PATCH 1/9] initial implementation --- packages/cloud_firestore/CHANGELOG.md | 5 +++ .../cloudfirestore/CloudFirestorePlugin.java | 8 ++++ .../example/test_driver/cloud_firestore.dart | 40 +++++++++++++++++++ .../ios/Classes/CloudFirestorePlugin.m | 8 ++++ packages/cloud_firestore/pubspec.yaml | 2 +- 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/packages/cloud_firestore/CHANGELOG.md b/packages/cloud_firestore/CHANGELOG.md index fd9832e776a2..88dcdbfaf2a8 100644 --- a/packages/cloud_firestore/CHANGELOG.md +++ b/packages/cloud_firestore/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.12.6+1 + +* 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..59628eedd5ce 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,6 +129,14 @@ private Object[] getDocumentValues( if (orderBy != null) { for (List order : orderBy) { String orderByFieldName = (String) order.get(0); + 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]); + } + orderByFieldName = fieldNameParts[fieldNameParts.length - 1]; + } data.add(documentData.get(orderByFieldName)); } } diff --git a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart index 44525bae76c9..e5a78466f206 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -210,5 +210,45 @@ 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 = await messages.add( { + 'cake': { + 'flavor': { + 'type': 1, + 'name': 'test' + } + } + }); + final DocumentSnapshot snapshot1 = await doc1.get(); + final DocumentReference doc2 = await messages.add({ + 'cake': { + 'flavor': { + 'type': 2, + 'name': 'test' + } + } + }); + + QuerySnapshot snapshot; + List results; + + // startAtDocument - one is enough as all of the pagination methods use the same method to get data internally + snapshot = await messages + .orderBy('cake.flavor.type') + .startAtDocument(snapshot1) + .getDocuments(); + results = snapshot.documents; + + // Clean up - before expect in case the test fails + await doc1.delete(); + await doc2.delete(); + + expect(results.length, 2); + expect(results[0].data['cake']['flavor']['type'], 1); + expect(results[1].data['cake']['flavor']['type'], 2); + }); }); } diff --git a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m index de1620ebef6b..f3ba1747694d 100644 --- a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m +++ b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m @@ -32,6 +32,14 @@ for (id item in orderBy) { NSArray *orderByParameters = item; NSString *fieldName = orderByParameters[0]; + 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]]; + } + fieldName = [currentMap objectForKey:[fieldNameParts objectAtIndex:[fieldNameParts count] - 1]]; + } [values addObject:[documentData objectForKey:fieldName]]; } } diff --git a/packages/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/pubspec.yaml index e5b397b914db..5d5355618a2f 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+1 flutter: plugin: From b087c03e072ccb1bf2b19906393544945312f919 Mon Sep 17 00:00:00 2001 From: creativecreatorormaybenot <19204050+creativecreatorormaybenot@users.noreply.github.com> Date: Sun, 30 Jun 2019 13:49:18 +0000 Subject: [PATCH 2/9] Format --- .../example/test_driver/cloud_firestore.dart | 12 +++--------- .../ios/Classes/CloudFirestorePlugin.m | 3 ++- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart index e5a78466f206..cb62673e0e31 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -214,21 +214,15 @@ void main() { test('pagination with map', () async { // Populate the database with two test documents. final CollectionReference messages = firestore.collection('messages'); - final DocumentReference doc1 = await messages.add( { + final DocumentReference doc1 = await messages.add({ 'cake': { - 'flavor': { - 'type': 1, - 'name': 'test' - } + 'flavor': {'type': 1, 'name': 'test'} } }); final DocumentSnapshot snapshot1 = await doc1.get(); final DocumentReference doc2 = await messages.add({ 'cake': { - 'flavor': { - 'type': 2, - 'name': 'test' - } + 'flavor': {'type': 2, 'name': 'test'} } }); diff --git a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m index f3ba1747694d..9bd8be0cfd10 100644 --- a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m +++ b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m @@ -38,7 +38,8 @@ for (int i = 1; i < [fieldNameParts count] - 1; i++) { currentMap = [currentMap objectForKey:[fieldNameParts objectAtIndex:i]]; } - fieldName = [currentMap objectForKey:[fieldNameParts objectAtIndex:[fieldNameParts count] - 1]]; + fieldName = + [currentMap objectForKey:[fieldNameParts objectAtIndex:[fieldNameParts count] - 1]]; } [values addObject:[documentData objectForKey:fieldName]]; } From 21111f60a52db540b99c87c34e5faafbc15115b7 Mon Sep 17 00:00:00 2001 From: creativecreatorormaybenot <19204050+creativecreatorormaybenot@users.noreply.github.com> Date: Sun, 30 Jun 2019 13:58:45 +0000 Subject: [PATCH 3/9] Version --- packages/cloud_firestore/CHANGELOG.md | 2 +- packages/cloud_firestore/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cloud_firestore/CHANGELOG.md b/packages/cloud_firestore/CHANGELOG.md index 88dcdbfaf2a8..6b748ca18166 100644 --- a/packages/cloud_firestore/CHANGELOG.md +++ b/packages/cloud_firestore/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.12.6+1 +## 0.12.5+3 * Support for `orderBy` on map fields (e.g. `orderBy('cake.flavor')`) for `startAtDocument`, `startAfterDocument`, `endAtDocument`, and `endBeforeDocument` added. diff --git a/packages/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/pubspec.yaml index 5d5355618a2f..d784b7569875 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.6+1 +version: 0.12.5+3 flutter: plugin: From 4a75603c373b5488a1f814f5ced96f677bffa733 Mon Sep 17 00:00:00 2001 From: creativecreatorormaybenot <19204050+creativecreatorormaybenot@users.noreply.github.com> Date: Sun, 30 Jun 2019 14:16:36 +0000 Subject: [PATCH 4/9] Version --- packages/cloud_firestore/CHANGELOG.md | 2 +- packages/cloud_firestore/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cloud_firestore/CHANGELOG.md b/packages/cloud_firestore/CHANGELOG.md index 6b748ca18166..0dd48a7d10c7 100644 --- a/packages/cloud_firestore/CHANGELOG.md +++ b/packages/cloud_firestore/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.12.5+3 +## 0.12.6 * Support for `orderBy` on map fields (e.g. `orderBy('cake.flavor')`) for `startAtDocument`, `startAfterDocument`, `endAtDocument`, and `endBeforeDocument` added. diff --git a/packages/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/pubspec.yaml index d784b7569875..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+3 +version: 0.12.6 flutter: plugin: From 405b5016d6323ea41aed65663c0d5f6e1f4ff178 Mon Sep 17 00:00:00 2001 From: creativecreatorormaybenot <19204050+creativecreatorormaybenot@users.noreply.github.com> Date: Sun, 30 Jun 2019 15:16:08 +0000 Subject: [PATCH 5/9] Fix --- .../cloudfirestore/CloudFirestorePlugin.java | 5 +++-- .../example/test_driver/cloud_firestore.dart | 21 ++++++++++++------- .../ios/Classes/CloudFirestorePlugin.m | 7 ++++--- 3 files changed, 20 insertions(+), 13 deletions(-) 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 59628eedd5ce..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 @@ -135,9 +135,10 @@ private Object[] getDocumentValues( for (int i = 1; i < fieldNameParts.length - 1; i++) { current = (Map) current.get(fieldNameParts[i]); } - orderByFieldName = fieldNameParts[fieldNameParts.length - 1]; + data.add(current.get(fieldNameParts[fieldNameParts.length - 1])); + } else { + data.add(documentData.get(orderByFieldName)); } - 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 cb62673e0e31..8926dcd0dcc4 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -214,35 +214,40 @@ void main() { test('pagination with map', () async { // Populate the database with two test documents. final CollectionReference messages = firestore.collection('messages'); - final DocumentReference doc1 = await messages.add({ + 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, 'name': 'test'} + 'flavor': {'type': 1, 'test_run': testRun} } }); + final DocumentSnapshot snapshot1 = await doc1.get(); final DocumentReference doc2 = await messages.add({ 'cake': { - 'flavor': {'type': 2, 'name': 'test'} + 'flavor': {'type': 2, 'test_run': testRun} } }); QuerySnapshot snapshot; List results; - // startAtDocument - one is enough as all of the pagination methods use the same method to get data internally + // 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; - // Clean up - before expect in case the test fails - await doc1.delete(); - await doc2.delete(); - 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 9bd8be0cfd10..f5d8051d97ba 100644 --- a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m +++ b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m @@ -38,10 +38,11 @@ for (int i = 1; i < [fieldNameParts count] - 1; i++) { currentMap = [currentMap objectForKey:[fieldNameParts objectAtIndex:i]]; } - fieldName = - [currentMap objectForKey:[fieldNameParts objectAtIndex:[fieldNameParts count] - 1]]; + [values addObject:[currentMap + objectForKey:[fieldNameParts objectAtIndex:[fieldNameParts count] - 1]]]; + } else { + [values addObject:[documentData objectForKey:fieldName]]; } - [values addObject:[documentData objectForKey:fieldName]]; } } if (isCollectionGroup) { From a76ecba1d73c9c5d902943c692b5c7dd5e402b7d Mon Sep 17 00:00:00 2001 From: creativecreatorormaybenot <19204050+creativecreatorormaybenot@users.noreply.github.com> Date: Sun, 30 Jun 2019 15:24:18 +0000 Subject: [PATCH 6/9] Format --- packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m index f5d8051d97ba..a18c809d4098 100644 --- a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m +++ b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m @@ -38,8 +38,8 @@ for (int i = 1; i < [fieldNameParts count] - 1; i++) { currentMap = [currentMap objectForKey:[fieldNameParts objectAtIndex:i]]; } - [values addObject:[currentMap - objectForKey:[fieldNameParts objectAtIndex:[fieldNameParts count] - 1]]]; + [values addObject:[currentMap objectForKey:[fieldNameParts + objectAtIndex:[fieldNameParts count] - 1]]]; } else { [values addObject:[documentData objectForKey:fieldName]]; } From 4ae4b2615af355b6b227526841c24d6dade89df3 Mon Sep 17 00:00:00 2001 From: creativecreatorormaybenot <19204050+creativecreatorormaybenot@users.noreply.github.com> Date: Mon, 1 Jul 2019 21:28:55 +0000 Subject: [PATCH 7/9] Version --- packages/cloud_firestore/CHANGELOG.md | 2 +- packages/cloud_firestore/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cloud_firestore/CHANGELOG.md b/packages/cloud_firestore/CHANGELOG.md index 0dd48a7d10c7..6b748ca18166 100644 --- a/packages/cloud_firestore/CHANGELOG.md +++ b/packages/cloud_firestore/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.12.6 +## 0.12.5+3 * Support for `orderBy` on map fields (e.g. `orderBy('cake.flavor')`) for `startAtDocument`, `startAfterDocument`, `endAtDocument`, and `endBeforeDocument` added. diff --git a/packages/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/pubspec.yaml index 9c70101f356f..d784b7569875 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.6 +version: 0.12.5+3 flutter: plugin: From 91366f6725dbc9a8f00ac15ce370bf257e4f0dfc Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Tue, 2 Jul 2019 16:46:08 -0700 Subject: [PATCH 8/9] Update CHANGELOG.md --- packages/cloud_firestore/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_firestore/CHANGELOG.md b/packages/cloud_firestore/CHANGELOG.md index 6b748ca18166..0dd48a7d10c7 100644 --- a/packages/cloud_firestore/CHANGELOG.md +++ b/packages/cloud_firestore/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.12.5+3 +## 0.12.6 * Support for `orderBy` on map fields (e.g. `orderBy('cake.flavor')`) for `startAtDocument`, `startAfterDocument`, `endAtDocument`, and `endBeforeDocument` added. From 70213b46450d43b319e2538767af15c2ca423cc0 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Tue, 2 Jul 2019 16:46:18 -0700 Subject: [PATCH 9/9] Update pubspec.yaml --- packages/cloud_firestore/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/pubspec.yaml index d784b7569875..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+3 +version: 0.12.6 flutter: plugin: