From 2cee7432cc485c3bb801cb2f6325f9323064974b Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Fri, 28 Jun 2019 12:29:07 -0700 Subject: [PATCH 1/8] Add a test for rapidly updating in quick succession --- .../example/test_driver/cloud_firestore.dart | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart index 44525bae76c9..7057e489738e 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -90,6 +90,16 @@ void main() { }); snapshot = await ref.get(); expect(snapshot.data['message'], 42.1); + + // Call several times without awaiting the result + await Future.wait(new List.generate( + 100, + (i) => ref.updateData({ + 'message': FieldValue.increment(i), + }), + )); + snapshot = await ref.get(); + expect(snapshot.data['message'], 4992.1); await ref.delete(); }); From 68f7bec08a028ff1cbbc8b01bd1b12ca10a2edb9 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Fri, 28 Jun 2019 12:30:14 -0700 Subject: [PATCH 2/8] bump for release --- packages/cloud_firestore/CHANGELOG.md | 4 ++++ packages/cloud_firestore/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/cloud_firestore/CHANGELOG.md b/packages/cloud_firestore/CHANGELOG.md index fd9832e776a2..914ae93be6b0 100644 --- a/packages/cloud_firestore/CHANGELOG.md +++ b/packages/cloud_firestore/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.12.5+3 + +* Add an integration test for rapidly incrementing field value. + ## 0.12.5+2 * Automatically use version from pubspec.yaml when reporting usage to Firebase. diff --git a/packages/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/pubspec.yaml index e5b397b914db..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.5+2 +version: 0.12.5+3 flutter: plugin: From cec807f284529dbcf461a2b5fcbe13daf9eecdf3 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Fri, 28 Jun 2019 13:08:29 -0700 Subject: [PATCH 3/8] Teach Transaction how to await automatically --- packages/cloud_firestore/CHANGELOG.md | 6 ++- .../example/test_driver/cloud_firestore.dart | 2 +- .../cloud_firestore/lib/src/firestore.dart | 7 +-- .../cloud_firestore/lib/src/transaction.dart | 48 ++++++++++++++++++- 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/packages/cloud_firestore/CHANGELOG.md b/packages/cloud_firestore/CHANGELOG.md index 914ae93be6b0..b0d7f047c628 100644 --- a/packages/cloud_firestore/CHANGELOG.md +++ b/packages/cloud_firestore/CHANGELOG.md @@ -1,6 +1,8 @@ -## 0.12.5+3 +## 0.12.6 -* Add an integration test for rapidly incrementing field value. +* Methods of `Transaction` no longer require `await`. +* Added documentation to methods of `Transaction`. +* Added an integration test for rapidly incrementing field value. ## 0.12.5+2 diff --git a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart index 7057e489738e..4b9674d9cc4c 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -117,7 +117,7 @@ void main() { final Map updatedData = Map.from(snapshot.data); updatedData['message'] = 'testing2'; - await tx.update(ref, updatedData); + tx.update(ref, updatedData); // calling await here is now optional return updatedData; }, ); diff --git a/packages/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/lib/src/firestore.dart index e91bc47261ef..280bb905e568 100644 --- a/packages/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/lib/src/firestore.dart @@ -25,9 +25,10 @@ class Firestore { _documentObservers[call.arguments['handle']].add(snapshot); } else if (call.method == 'DoTransaction') { final int transactionId = call.arguments['transactionId']; - return _transactionHandlers[transactionId]( - Transaction(transactionId, this), - ); + final Transaction transaction = Transaction(transactionId, this); + dynamic result = await _transactionHandlers[transactionId](transaction); + await transaction._finish(); + return result; } }); _initialized = true; diff --git a/packages/cloud_firestore/lib/src/transaction.dart b/packages/cloud_firestore/lib/src/transaction.dart index d42c89d9d59e..2709bf3ed052 100644 --- a/packages/cloud_firestore/lib/src/transaction.dart +++ b/packages/cloud_firestore/lib/src/transaction.dart @@ -12,8 +12,17 @@ class Transaction { int _transactionId; Firestore _firestore; + List> _pendingResults = []; + Future _finish() => Future.wait(_pendingResults); - Future get(DocumentReference documentReference) async { + /// Reads the document referenced by the provided DocumentReference. + Future get(DocumentReference documentReference) { + final Future result = _get(documentReference); + _pendingResults.add(result); + return result; + } + + Future _get(DocumentReference documentReference) async { final Map result = await Firestore.channel .invokeMapMethod('Transaction#get', { 'app': _firestore.app.name, @@ -32,7 +41,17 @@ class Transaction { } } - Future delete(DocumentReference documentReference) async { + /// Deletes the document referred to by the provided [documentReference]. + /// + /// Awaiting the returned [Future] is optional and will be done automatically + /// when the transaction handler completes. + Future delete(DocumentReference documentReference) { + final Future result = _delete(documentReference); + _pendingResults.add(result); + return result; + } + + Future _delete(DocumentReference documentReference) async { return Firestore.channel .invokeMethod('Transaction#delete', { 'app': _firestore.app.name, @@ -41,8 +60,20 @@ class Transaction { }); } + /// Updates fields in the document referred to by [documentReference]. + /// The update will fail if applied to a document that does not exist. + /// + /// Awaiting the returned [Future] is optional and will be done automatically + /// when the transaction handler completes. Future update( DocumentReference documentReference, Map data) async { + final Future result = _update(documentReference, data); + _pendingResults.add(result); + return result; + } + + Future _update( + DocumentReference documentReference, Map data) async { return Firestore.channel .invokeMethod('Transaction#update', { 'app': _firestore.app.name, @@ -52,7 +83,20 @@ class Transaction { }); } + /// Writes to the document referred to by the provided [DocumentReference]. + /// If the document does not exist yet, it will be created. If you pass + /// SetOptions, the provided data can be merged into the existing document. + /// + /// Awaiting the returned [Future] is optional and will be done automatically + /// when the transaction handler completes. Future set( + DocumentReference documentReference, Map data) { + final Future result = _set(documentReference, data); + _pendingResults.add(result); + return result; + } + + Future _set( DocumentReference documentReference, Map data) async { return Firestore.channel .invokeMethod('Transaction#set', { From c3f6938a5b3da97cec3f6e8baf2e0ad02db996db Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Fri, 28 Jun 2019 13:59:08 -0700 Subject: [PATCH 4/8] Improve error message handling --- .../plugins/firebase/cloudfirestore/CloudFirestorePlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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..78a64277ce04 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 @@ -389,7 +389,7 @@ public void error( String errorMessage, Object errorDetails) { transactionTCS.trySetException( - new Exception("Do transaction failed.")); + new Exception("DoTransaction failed: " + errorMessage)); } @Override From 7ca8d04286d44508794ddf0757075e023da590eb Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sun, 7 Jul 2019 18:10:27 -0700 Subject: [PATCH 5/8] Fix analyzer issues --- .../cloud_firestore/example/test_driver/cloud_firestore.dart | 4 ++-- packages/cloud_firestore/lib/src/firestore.dart | 2 +- packages/cloud_firestore/lib/src/transaction.dart | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart index e18fef473592..d27827d04792 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -92,9 +92,9 @@ void main() { expect(snapshot.data['message'], 42.1); // Call several times without awaiting the result - await Future.wait(new List.generate( + await Future.wait(List>.generate( 100, - (i) => ref.updateData({ + (int i) => ref.updateData({ 'message': FieldValue.increment(i), }), )); diff --git a/packages/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/lib/src/firestore.dart index 280bb905e568..0a7a0adac546 100644 --- a/packages/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/lib/src/firestore.dart @@ -26,7 +26,7 @@ class Firestore { } else if (call.method == 'DoTransaction') { final int transactionId = call.arguments['transactionId']; final Transaction transaction = Transaction(transactionId, this); - dynamic result = await _transactionHandlers[transactionId](transaction); + final dynamic result = await _transactionHandlers[transactionId](transaction); await transaction._finish(); return result; } diff --git a/packages/cloud_firestore/lib/src/transaction.dart b/packages/cloud_firestore/lib/src/transaction.dart index 2709bf3ed052..d13e3f19f9b2 100644 --- a/packages/cloud_firestore/lib/src/transaction.dart +++ b/packages/cloud_firestore/lib/src/transaction.dart @@ -12,7 +12,7 @@ class Transaction { int _transactionId; Firestore _firestore; - List> _pendingResults = []; + List> _pendingResults = >[]; Future _finish() => Future.wait(_pendingResults); /// Reads the document referenced by the provided DocumentReference. From aed577575bfc1d068f0a54e0600b44aa83cf8729 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sun, 7 Jul 2019 18:14:06 -0700 Subject: [PATCH 6/8] Make test faster by only incrementing three times --- .../example/test_driver/cloud_firestore.dart | 6 +++--- packages/firebase_database/CHANGELOG.md | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart index d27827d04792..1b0fc2d25e56 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -93,13 +93,13 @@ void main() { // Call several times without awaiting the result await Future.wait(List>.generate( - 100, + 3, (int i) => ref.updateData({ 'message': FieldValue.increment(i), }), )); snapshot = await ref.get(); - expect(snapshot.data['message'], 4992.1); + expect(snapshot.data['message'], 45.1); await ref.delete(); }); @@ -117,7 +117,7 @@ void main() { final Map updatedData = Map.from(snapshot.data); updatedData['message'] = 'testing2'; - tx.update(ref, updatedData); // calling await here is now optional + tx.update(ref, updatedData); // calling await here is optional return updatedData; }, ); diff --git a/packages/firebase_database/CHANGELOG.md b/packages/firebase_database/CHANGELOG.md index c08e59b44483..3f8772587402 100644 --- a/packages/firebase_database/CHANGELOG.md +++ b/packages/firebase_database/CHANGELOG.md @@ -1,3 +1,7 @@ +## 3.0.4 + +* Fix transactions on + ## 3.0.3 * Automatically use version from pubspec.yaml when reporting usage to Firebase. From 126de29e5a06b3f9628530953befdabaad27b9f5 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sun, 7 Jul 2019 18:14:59 -0700 Subject: [PATCH 7/8] Reformat --- .../cloud_firestore/example/test_driver/cloud_firestore.dart | 3 ++- packages/cloud_firestore/lib/src/firestore.dart | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart index 1b0fc2d25e56..d7d85db5b000 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -117,11 +117,12 @@ void main() { final Map updatedData = Map.from(snapshot.data); updatedData['message'] = 'testing2'; - tx.update(ref, updatedData); // calling await here is optional + tx.update(ref, updatedData); // calling await here is optional return updatedData; }, ); expect(result['message'], 'testing2'); + await ref.delete(); final DocumentSnapshot nonexistentSnapshot = await ref.get(); expect(nonexistentSnapshot.data, null); diff --git a/packages/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/lib/src/firestore.dart index 0a7a0adac546..c2fa17720995 100644 --- a/packages/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/lib/src/firestore.dart @@ -26,7 +26,8 @@ class Firestore { } else if (call.method == 'DoTransaction') { final int transactionId = call.arguments['transactionId']; final Transaction transaction = Transaction(transactionId, this); - final dynamic result = await _transactionHandlers[transactionId](transaction); + final dynamic result = + await _transactionHandlers[transactionId](transaction); await transaction._finish(); return result; } From 42d50a09ba569b7ec1680595207f3139e4e16964 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sun, 7 Jul 2019 18:22:03 -0700 Subject: [PATCH 8/8] Remove log --- packages/cloud_firestore/CHANGELOG.md | 1 + .../plugins/firebase/cloudfirestore/CloudFirestorePlugin.java | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_firestore/CHANGELOG.md b/packages/cloud_firestore/CHANGELOG.md index 2fe9c42e5686..b078cfd0a41d 100644 --- a/packages/cloud_firestore/CHANGELOG.md +++ b/packages/cloud_firestore/CHANGELOG.md @@ -2,6 +2,7 @@ * Methods of `Transaction` no longer require `await`. * Added documentation to methods of `Transaction`. +* Removed an unnecessary log on Android. * Added an integration test for rapidly incrementing field value. ## 0.12.6 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 f03128278742..5254b8b1493d 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 @@ -528,7 +528,6 @@ protected Void doInBackground(Void... voids) { new Runnable() { @Override public void run() { - Log.d(TAG, "sending set success"); result.success(null); } });