From 9800435abc562fadc67a945e771591186576c34d Mon Sep 17 00:00:00 2001 From: Russell Wheatley Date: Tue, 4 Apr 2023 13:31:26 +0100 Subject: [PATCH] fix(firestore): ensure all index URLs are captured and passed to the user (#10674) --- .github/workflows/scripts/firestore.rules | 4 ++ .../FlutterFirebaseFirestoreException.java | 3 +- .../example/integration_test/query_e2e.dart | 42 +++++++++++++++++++ .../ios/Classes/FLTFirebaseFirestoreUtils.m | 4 +- 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/.github/workflows/scripts/firestore.rules b/.github/workflows/scripts/firestore.rules index 58117d5b04a8..b45531f1462c 100644 --- a/.github/workflows/scripts/firestore.rules +++ b/.github/workflows/scripts/firestore.rules @@ -9,6 +9,10 @@ service cloud.firestore { allow read, write: if true; } + match /{path=**}/collection-group/{subId} { + allow read, write: if true; + } + match /firestore-bundle-tests/{document=**} { allow read, write: if true; } diff --git a/packages/cloud_firestore/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/firestore/FlutterFirebaseFirestoreException.java b/packages/cloud_firestore/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/firestore/FlutterFirebaseFirestoreException.java index 5e5d882adb6d..759eecaf4cf7 100644 --- a/packages/cloud_firestore/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/firestore/FlutterFirebaseFirestoreException.java +++ b/packages/cloud_firestore/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/firestore/FlutterFirebaseFirestoreException.java @@ -79,8 +79,7 @@ public FlutterFirebaseFirestoreException( break; case "FAILED_PRECONDITION": code = "failed-precondition"; - if (foundMessage.contains("query requires an index") - || foundMessage.contains("ensure it has been indexed")) { + if (foundMessage.contains("index")) { message = foundMessage; } else { message = ERROR_FAILED_PRECONDITION; diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/query_e2e.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/query_e2e.dart index 896e49281c4a..71d0ad2706aa 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/query_e2e.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/query_e2e.dart @@ -115,6 +115,27 @@ void runQueryTests() { expect(groupSnapshot.docs[0].data()['foo'], equals(2)); expect(groupSnapshot.docs[1].data()['foo'], equals(1)); }); + + testWidgets( + 'should respond with a FirebaseException, the query requires an index', + (_) async { + try { + await FirebaseFirestore.instance + .collectionGroup('collection-group') + .where('number', isGreaterThan: 1, isLessThan: 3) + .where('foo', isEqualTo: 'bar') + .get(); + } catch (error) { + expect( + (error as FirebaseException).code, + equals('failed-precondition'), + ); + expect( + error.message, + 'The query requires an index', + ); + } + }); }); /** @@ -186,6 +207,27 @@ void runQueryTests() { } fail('Should have thrown a [FirebaseException]'); }); + + testWidgets( + 'should respond with a FirebaseException, the query requires an index', + (_) async { + try { + await FirebaseFirestore.instance + .collection('flutter-tests') + .where('number', isGreaterThan: 1, isLessThan: 3) + .where('foo', isEqualTo: 'bar') + .get(); + } catch (error) { + expect( + (error as FirebaseException).code, + equals('failed-precondition'), + ); + expect( + error.message, + 'The query requires an index', + ); + } + }); }); /** diff --git a/packages/cloud_firestore/cloud_firestore/ios/Classes/FLTFirebaseFirestoreUtils.m b/packages/cloud_firestore/cloud_firestore/ios/Classes/FLTFirebaseFirestoreUtils.m index 4d27547d4e61..b8e0566a3b3d 100644 --- a/packages/cloud_firestore/cloud_firestore/ios/Classes/FLTFirebaseFirestoreUtils.m +++ b/packages/cloud_firestore/cloud_firestore/ios/Classes/FLTFirebaseFirestoreUtils.m @@ -100,9 +100,7 @@ + (NSArray *)ErrorCodeAndMessageFromNSError:(NSError *)error { break; case FIRFirestoreErrorCodeFailedPrecondition: code = @"failed-precondition"; - if ([error.localizedDescription containsString:@"query requires an index"] || - [error.localizedDescription containsString:@"requires a COLLECTION_GROUP_DESC index"] || - [error.localizedDescription containsString:@"requires a COLLECTION_GROUP_ASC index"]) { + if ([error.localizedDescription containsString:@"index"]) { message = error.localizedDescription; } else { message = @"Operation was rejected because the system is not in a state required for the "