From 9981b50132139dcdd540f47272638ace3a1f7c39 Mon Sep 17 00:00:00 2001 From: Razvan Cristian Lung Date: Sat, 27 Jul 2019 09:39:11 +0300 Subject: [PATCH 01/19] [cloud_firestore] add support for MetadataChanges --- packages/cloud_firestore/CHANGELOG.md | 5 ++ .../cloudfirestore/CloudFirestorePlugin.java | 17 ++++- .../cloud_firestore/example/lib/main.dart | 2 +- .../example/test_driver/cloud_firestore.dart | 4 +- .../ios/Classes/CloudFirestorePlugin.m | 75 ++++++++++++------- .../lib/src/document_reference.dart | 5 +- packages/cloud_firestore/lib/src/query.dart | 5 +- .../lib/src/snapshot_metadata.dart | 13 ++++ packages/cloud_firestore/pubspec.yaml | 2 +- .../test/cloud_firestore_test.dart | 13 +++- 10 files changed, 102 insertions(+), 39 deletions(-) diff --git a/packages/cloud_firestore/CHANGELOG.md b/packages/cloud_firestore/CHANGELOG.md index f3a81406954c..0b8c08f04588 100644 --- a/packages/cloud_firestore/CHANGELOG.md +++ b/packages/cloud_firestore/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.12.8 + +* Add support for MetadataChanges for snapshots on both Documents and Queries +* Fix example app crash when the `message` field was not a string + ## 0.12.7+1 * Update google-services Android gradle plugin to 4.3.0 in documentation and examples. 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 5254b8b1493d..aa56b3112fe3 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 @@ -31,6 +31,7 @@ import com.google.firebase.firestore.FirebaseFirestoreSettings; import com.google.firebase.firestore.GeoPoint; import com.google.firebase.firestore.ListenerRegistration; +import com.google.firebase.firestore.MetadataChanges; import com.google.firebase.firestore.Query; import com.google.firebase.firestore.QuerySnapshot; import com.google.firebase.firestore.SetOptions; @@ -121,6 +122,14 @@ private Source getSource(Map arguments) { } } + private MetadataChanges getMetadataChanges(Map arguments) { + String metadataChanges = (String) arguments.get("metadataChanges"); + if ("include".equals(metadataChanges)) { + return MetadataChanges.INCLUDE; + } + return MetadataChanges.EXCLUDE; + } + private Object[] getDocumentValues( Map document, List> orderBy, Map arguments) { String documentId = (String) document.get("id"); @@ -616,21 +625,25 @@ public void run() { case "Query#addSnapshotListener": { Map arguments = call.arguments(); + MetadataChanges metadataChanges = getMetadataChanges(arguments); int handle = nextListenerHandle++; EventObserver observer = new EventObserver(handle); observers.put(handle, observer); - listenerRegistrations.put(handle, getQuery(arguments).addSnapshotListener(observer)); + listenerRegistrations.put( + handle, getQuery(arguments).addSnapshotListener(metadataChanges, observer)); result.success(handle); break; } case "Query#addDocumentListener": { Map arguments = call.arguments(); + MetadataChanges metadataChanges = getMetadataChanges(arguments); int handle = nextListenerHandle++; DocumentObserver observer = new DocumentObserver(handle); documentObservers.put(handle, observer); listenerRegistrations.put( - handle, getDocumentReference(arguments).addSnapshotListener(observer)); + handle, + getDocumentReference(arguments).addSnapshotListener(metadataChanges, observer)); result.success(handle); break; } diff --git a/packages/cloud_firestore/example/lib/main.dart b/packages/cloud_firestore/example/lib/main.dart index 27138f2fbd9e..9c2157dc901a 100755 --- a/packages/cloud_firestore/example/lib/main.dart +++ b/packages/cloud_firestore/example/lib/main.dart @@ -42,7 +42,7 @@ class MessageList extends StatelessWidget { itemBuilder: (_, int index) { final DocumentSnapshot document = snapshot.data.documents[index]; return ListTile( - title: Text(document['message'] ?? ''), + title: Text('${document['message']}' ?? ''), subtitle: Text('Message ${index + 1} of $messageCount'), ); }, diff --git a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart index d7d85db5b000..2c2131bb6c22 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -95,8 +95,8 @@ void main() { await Future.wait(List>.generate( 3, (int i) => ref.updateData({ - 'message': FieldValue.increment(i), - }), + 'message': FieldValue.increment(i), + }), )); snapshot = await ref.get(); expect(snapshot.data['message'], 45.1); diff --git a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m index a18c809d4098..dfbbf1031cf2 100644 --- a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m +++ b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m @@ -160,6 +160,14 @@ static FIRFirestoreSource getSource(NSDictionary *arguments) { return FIRFirestoreSourceDefault; } +static BOOL getIncludeMetadataChanges(NSDictionary *arguments) { + NSString *metadataChanges = arguments[@"metadataChanges"]; + if ([@"include" isEqualToString:metadataChanges]) { + return YES; + } + return NO; +} + static NSDictionary *parseQuerySnapshot(FIRQuerySnapshot *snapshot) { NSMutableArray *paths = [NSMutableArray array]; NSMutableArray *documents = [NSMutableArray array]; @@ -515,6 +523,7 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result } else if ([@"Query#addSnapshotListener" isEqualToString:call.method]) { __block NSNumber *handle = [NSNumber numberWithInt:_nextListenerHandle++]; FIRQuery *query; + BOOL includeMetadataChanges = getIncludeMetadataChanges(call.arguments); @try { query = getQuery(call.arguments); } @catch (NSException *exception) { @@ -523,38 +532,50 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result details:[exception reason]]); } id listener = [query - addSnapshotListener:^(FIRQuerySnapshot *_Nullable snapshot, NSError *_Nullable error) { - if (snapshot == nil) { - result(getFlutterError(error)); - return; - } - NSMutableDictionary *arguments = [parseQuerySnapshot(snapshot) mutableCopy]; - [arguments setObject:handle forKey:@"handle"]; - [weakSelf.channel invokeMethod:@"QuerySnapshot" arguments:arguments]; - }]; + addSnapshotListenerWithIncludeMetadataChanges:includeMetadataChanges + listener:^(FIRQuerySnapshot *_Nullable snapshot, + NSError *_Nullable error) { + if (snapshot == nil) { + result(getFlutterError(error)); + return; + } + NSMutableDictionary *arguments = + [parseQuerySnapshot(snapshot) mutableCopy]; + [arguments setObject:handle forKey:@"handle"]; + [weakSelf.channel invokeMethod:@"QuerySnapshot" + arguments:arguments]; + }]; _listeners[handle] = listener; result(handle); } else if ([@"Query#addDocumentListener" isEqualToString:call.method]) { __block NSNumber *handle = [NSNumber numberWithInt:_nextListenerHandle++]; FIRDocumentReference *document = getDocumentReference(call.arguments); - id listener = - [document addSnapshotListener:^(FIRDocumentSnapshot *snapshot, NSError *_Nullable error) { - if (snapshot == nil) { - result(getFlutterError(error)); - return; - } - [weakSelf.channel invokeMethod:@"DocumentSnapshot" - arguments:@{ - @"handle" : handle, - @"path" : snapshot ? snapshot.reference.path : [NSNull null], - @"data" : snapshot.exists ? snapshot.data : [NSNull null], - @"metadata" : snapshot ? @{ - @"hasPendingWrites" : @(snapshot.metadata.hasPendingWrites), - @"isFromCache" : @(snapshot.metadata.isFromCache), - } - : [NSNull null], - }]; - }]; + BOOL includeMetadataChanges = getIncludeMetadataChanges(call.arguments); + id listener = [document + addSnapshotListenerWithIncludeMetadataChanges:includeMetadataChanges + listener:^(FIRDocumentSnapshot *snapshot, + NSError *_Nullable error) { + if (snapshot == nil) { + result(getFlutterError(error)); + return; + } + [weakSelf.channel + invokeMethod:@"DocumentSnapshot" + arguments:@{ + @"handle" : handle, + @"path" : snapshot ? snapshot.reference.path + : [NSNull null], + @"data" : snapshot.exists ? snapshot.data + : [NSNull null], + @"metadata" : snapshot ? @{ + @"hasPendingWrites" : + @(snapshot.metadata.hasPendingWrites), + @"isFromCache" : + @(snapshot.metadata.isFromCache), + } + : [NSNull null], + }]; + }]; _listeners[handle] = listener; result(handle); } else if ([@"Query#getDocuments" isEqualToString:call.method]) { diff --git a/packages/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/lib/src/document_reference.dart index 2edf8ac548ad..522d2ea8a2ae 100644 --- a/packages/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/lib/src/document_reference.dart @@ -116,7 +116,9 @@ class DocumentReference { /// Notifies of documents at this location // TODO(jackson): Reduce code duplication with [Query] - Stream snapshots() { + Stream snapshots( + {MetadataChanges metadataChanges = MetadataChanges.exclude}) { + assert(metadataChanges != null); Future _handle; // It's fine to let the StreamController be garbage collected once all the // subscribers have cancelled; this analyzer warning is safe to ignore. @@ -128,6 +130,7 @@ class DocumentReference { { 'app': firestore.app.name, 'path': path, + 'metadataChanges': _getMetadataChangesString(metadataChanges), }, ).then((dynamic result) => result); _handle.then((int handle) { diff --git a/packages/cloud_firestore/lib/src/query.dart b/packages/cloud_firestore/lib/src/query.dart index e1f6e2aa5a96..77844559072f 100644 --- a/packages/cloud_firestore/lib/src/query.dart +++ b/packages/cloud_firestore/lib/src/query.dart @@ -50,7 +50,9 @@ class Query { /// Notifies of query results at this location // TODO(jackson): Reduce code duplication with [DocumentReference] - Stream snapshots() { + Stream snapshots( + {MetadataChanges metadataChanges = MetadataChanges.exclude}) { + assert(metadataChanges != null); Future _handle; // It's fine to let the StreamController be garbage collected once all the // subscribers have cancelled; this analyzer warning is safe to ignore. @@ -64,6 +66,7 @@ class Query { 'path': _path, 'isCollectionGroup': _isCollectionGroup, 'parameters': _parameters, + 'metadataChanges': _getMetadataChangesString(metadataChanges), }, ).then((dynamic result) => result); _handle.then((int handle) { diff --git a/packages/cloud_firestore/lib/src/snapshot_metadata.dart b/packages/cloud_firestore/lib/src/snapshot_metadata.dart index 39f51f5928e8..7f32e968ea0c 100644 --- a/packages/cloud_firestore/lib/src/snapshot_metadata.dart +++ b/packages/cloud_firestore/lib/src/snapshot_metadata.dart @@ -26,3 +26,16 @@ class SnapshotMetadata { /// up-to-date data from the backend. final bool isFromCache; } + +/// Indicates whether metadata-only changes (i.e. only [DocumentSnapshot.metadata] +/// or [Query.metadata] changed) should trigger snapshot events. +enum MetadataChanges { exclude, include } + +/// Converts [MetadataChanges] to [String] +String _getMetadataChangesString(MetadataChanges metadataChanges) { + assert(metadataChanges != null); + if (metadataChanges == MetadataChanges.include) { + return 'include'; + } + return 'exclude'; +} diff --git a/packages/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/pubspec.yaml index 08348e413ea7..9fa89bfe045e 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.7+1 +version: 0.12.8 flutter: plugin: diff --git a/packages/cloud_firestore/test/cloud_firestore_test.dart b/packages/cloud_firestore/test/cloud_firestore_test.dart index 2b679fea6d0b..83941c5ea1c1 100755 --- a/packages/cloud_firestore/test/cloud_firestore_test.dart +++ b/packages/cloud_firestore/test/cloud_firestore_test.dart @@ -346,7 +346,8 @@ void main() { 'parameters': { 'where': >[], 'orderBy': >[], - } + }, + 'metadataChanges': 'exclude', }, ), isMethodCall( @@ -377,7 +378,8 @@ void main() { ['createdAt', '<', 100], ], 'orderBy': >[], - } + }, + 'metadataChanges': 'exclude', }, ), isMethodCall( @@ -409,7 +411,8 @@ void main() { ['profile', '==', null], ], 'orderBy': >[], - } + }, + 'metadataChanges': 'exclude', }, ), isMethodCall( @@ -441,7 +444,8 @@ void main() { 'orderBy': >[ ['createdAt', false] ], - } + }, + 'metadataChanges': 'exclude', }, ), isMethodCall( @@ -470,6 +474,7 @@ void main() { arguments: { 'app': app.name, 'path': 'path/to/foo', + 'metadataChanges': 'exclude', }, ), isMethodCall( From f2a76ff0ec62de3c2973c338af36ac63d6272933 Mon Sep 17 00:00:00 2001 From: Razvan Cristian Lung Date: Sat, 27 Jul 2019 10:51:18 +0300 Subject: [PATCH 02/19] fix: formatting issue --- packages/battery/example/lib/main.dart | 20 +++---- .../example/test_driver/cloud_firestore.dart | 4 +- .../firebase_messaging/example/lib/main.dart | 16 ++--- .../example/lib/camera_preview_scanner.dart | 50 ++++++++-------- .../example/lib/picture_scanner.dart | 50 ++++++++-------- .../example/lib/scanner_utils.dart | 4 +- .../google_maps_flutter/example/lib/main.dart | 8 +-- packages/share/example/lib/main.dart | 8 +-- packages/url_launcher/example/lib/main.dart | 36 +++++------ .../webview_flutter/example/lib/main.dart | 60 +++++++++---------- 10 files changed, 128 insertions(+), 128 deletions(-) diff --git a/packages/battery/example/lib/main.dart b/packages/battery/example/lib/main.dart index 250d458d5190..0feaa0503e45 100644 --- a/packages/battery/example/lib/main.dart +++ b/packages/battery/example/lib/main.dart @@ -66,16 +66,16 @@ class _MyHomePageState extends State { showDialog( context: context, builder: (_) => AlertDialog( - content: Text('Battery: $batteryLevel%'), - actions: [ - FlatButton( - child: const Text('OK'), - onPressed: () { - Navigator.pop(context); - }, - ) - ], - ), + content: Text('Battery: $batteryLevel%'), + actions: [ + FlatButton( + child: const Text('OK'), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ), ); }, ), diff --git a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart index 2c2131bb6c22..d7d85db5b000 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -95,8 +95,8 @@ void main() { await Future.wait(List>.generate( 3, (int i) => ref.updateData({ - 'message': FieldValue.increment(i), - }), + 'message': FieldValue.increment(i), + }), )); snapshot = await ref.get(); expect(snapshot.data['message'], 45.1); diff --git a/packages/firebase_messaging/example/lib/main.dart b/packages/firebase_messaging/example/lib/main.dart index c03e361c81db..36de611f8bd3 100644 --- a/packages/firebase_messaging/example/lib/main.dart +++ b/packages/firebase_messaging/example/lib/main.dart @@ -36,9 +36,9 @@ class Item { return routes.putIfAbsent( routeName, () => MaterialPageRoute( - settings: RouteSettings(name: routeName), - builder: (BuildContext context) => DetailPage(itemId), - ), + settings: RouteSettings(name: routeName), + builder: (BuildContext context) => DetailPage(itemId), + ), ); } } @@ -176,11 +176,11 @@ class _PushMessagingExampleState extends State { // For testing -- simulate a message being received floatingActionButton: FloatingActionButton( onPressed: () => _showItemDialog({ - "data": { - "id": "2", - "status": "out of stock", - }, - }), + "data": { + "id": "2", + "status": "out of stock", + }, + }), tooltip: 'Simulate Message', child: const Icon(Icons.message), ), diff --git a/packages/firebase_ml_vision/example/lib/camera_preview_scanner.dart b/packages/firebase_ml_vision/example/lib/camera_preview_scanner.dart index 45caa59ec43f..f40e20d6591c 100644 --- a/packages/firebase_ml_vision/example/lib/camera_preview_scanner.dart +++ b/packages/firebase_ml_vision/example/lib/camera_preview_scanner.dart @@ -185,31 +185,31 @@ class _CameraPreviewScannerState extends State { _currentDetector = result; }, itemBuilder: (BuildContext context) => >[ - const PopupMenuItem( - child: Text('Detect Barcode'), - value: Detector.barcode, - ), - const PopupMenuItem( - child: Text('Detect Face'), - value: Detector.face, - ), - const PopupMenuItem( - child: Text('Detect Label'), - value: Detector.label, - ), - const PopupMenuItem( - child: Text('Detect Cloud Label'), - value: Detector.cloudLabel, - ), - const PopupMenuItem( - child: Text('Detect Text'), - value: Detector.text, - ), - const PopupMenuItem( - child: Text('Detect Cloud Text'), - value: Detector.cloudText, - ), - ], + const PopupMenuItem( + child: Text('Detect Barcode'), + value: Detector.barcode, + ), + const PopupMenuItem( + child: Text('Detect Face'), + value: Detector.face, + ), + const PopupMenuItem( + child: Text('Detect Label'), + value: Detector.label, + ), + const PopupMenuItem( + child: Text('Detect Cloud Label'), + value: Detector.cloudLabel, + ), + const PopupMenuItem( + child: Text('Detect Text'), + value: Detector.text, + ), + const PopupMenuItem( + child: Text('Detect Cloud Text'), + value: Detector.cloudText, + ), + ], ), ], ), diff --git a/packages/firebase_ml_vision/example/lib/picture_scanner.dart b/packages/firebase_ml_vision/example/lib/picture_scanner.dart index 1ff15715ec50..182a55a46020 100644 --- a/packages/firebase_ml_vision/example/lib/picture_scanner.dart +++ b/packages/firebase_ml_vision/example/lib/picture_scanner.dart @@ -173,31 +173,31 @@ class _PictureScannerState extends State { if (_imageFile != null) _scanImage(_imageFile); }, itemBuilder: (BuildContext context) => >[ - const PopupMenuItem( - child: Text('Detect Barcode'), - value: Detector.barcode, - ), - const PopupMenuItem( - child: Text('Detect Face'), - value: Detector.face, - ), - const PopupMenuItem( - child: Text('Detect Label'), - value: Detector.label, - ), - const PopupMenuItem( - child: Text('Detect Cloud Label'), - value: Detector.cloudLabel, - ), - const PopupMenuItem( - child: Text('Detect Text'), - value: Detector.text, - ), - const PopupMenuItem( - child: Text('Detect Cloud Text'), - value: Detector.cloudText, - ), - ], + const PopupMenuItem( + child: Text('Detect Barcode'), + value: Detector.barcode, + ), + const PopupMenuItem( + child: Text('Detect Face'), + value: Detector.face, + ), + const PopupMenuItem( + child: Text('Detect Label'), + value: Detector.label, + ), + const PopupMenuItem( + child: Text('Detect Cloud Label'), + value: Detector.cloudLabel, + ), + const PopupMenuItem( + child: Text('Detect Text'), + value: Detector.text, + ), + const PopupMenuItem( + child: Text('Detect Cloud Text'), + value: Detector.cloudText, + ), + ], ), ], ), diff --git a/packages/firebase_ml_vision/example/lib/scanner_utils.dart b/packages/firebase_ml_vision/example/lib/scanner_utils.dart index c8994c42560b..6bd156448189 100644 --- a/packages/firebase_ml_vision/example/lib/scanner_utils.dart +++ b/packages/firebase_ml_vision/example/lib/scanner_utils.dart @@ -16,8 +16,8 @@ class ScannerUtils { static Future getCamera(CameraLensDirection dir) async { return await availableCameras().then( (List cameras) => cameras.firstWhere( - (CameraDescription camera) => camera.lensDirection == dir, - ), + (CameraDescription camera) => camera.lensDirection == dir, + ), ); } diff --git a/packages/google_maps_flutter/example/lib/main.dart b/packages/google_maps_flutter/example/lib/main.dart index 79f9a090d466..c082f188ff91 100644 --- a/packages/google_maps_flutter/example/lib/main.dart +++ b/packages/google_maps_flutter/example/lib/main.dart @@ -48,10 +48,10 @@ class MapsDemo extends StatelessWidget { body: ListView.builder( itemCount: _allPages.length, itemBuilder: (_, int index) => ListTile( - leading: _allPages[index].leading, - title: Text(_allPages[index].title), - onTap: () => _pushPage(context, _allPages[index]), - ), + leading: _allPages[index].leading, + title: Text(_allPages[index].title), + onTap: () => _pushPage(context, _allPages[index]), + ), ), ); } diff --git a/packages/share/example/lib/main.dart b/packages/share/example/lib/main.dart index c635370a0866..775ae18718ea 100644 --- a/packages/share/example/lib/main.dart +++ b/packages/share/example/lib/main.dart @@ -38,8 +38,8 @@ class DemoAppState extends State { ), maxLines: 2, onChanged: (String value) => setState(() { - text = value; - }), + text = value; + }), ), TextField( decoration: const InputDecoration( @@ -48,8 +48,8 @@ class DemoAppState extends State { ), maxLines: 2, onChanged: (String value) => setState(() { - subject = value; - }), + subject = value; + }), ), const Padding(padding: EdgeInsets.only(top: 24.0)), Builder( diff --git a/packages/url_launcher/example/lib/main.dart b/packages/url_launcher/example/lib/main.dart index df68c144d6e4..b4a7e4275bfc 100644 --- a/packages/url_launcher/example/lib/main.dart +++ b/packages/url_launcher/example/lib/main.dart @@ -141,8 +141,8 @@ class _MyHomePageState extends State { ), RaisedButton( onPressed: () => setState(() { - _launched = _makePhoneCall('tel:$_phone'); - }), + _launched = _makePhoneCall('tel:$_phone'); + }), child: const Text('Make phone call'), ), const Padding( @@ -151,46 +151,46 @@ class _MyHomePageState extends State { ), RaisedButton( onPressed: () => setState(() { - _launched = _launchInBrowser(toLaunch); - }), + _launched = _launchInBrowser(toLaunch); + }), child: const Text('Launch in browser'), ), const Padding(padding: EdgeInsets.all(16.0)), RaisedButton( onPressed: () => setState(() { - _launched = _launchInWebViewOrVC(toLaunch); - }), + _launched = _launchInWebViewOrVC(toLaunch); + }), child: const Text('Launch in app'), ), RaisedButton( onPressed: () => setState(() { - _launched = _launchInWebViewWithJavaScript(toLaunch); - }), + _launched = _launchInWebViewWithJavaScript(toLaunch); + }), child: const Text('Launch in app(JavaScript ON)'), ), RaisedButton( onPressed: () => setState(() { - _launched = _launchInWebViewWithDomStorage(toLaunch); - }), + _launched = _launchInWebViewWithDomStorage(toLaunch); + }), child: const Text('Launch in app(DOM storage ON)'), ), const Padding(padding: EdgeInsets.all(16.0)), RaisedButton( onPressed: () => setState(() { - _launched = _launchUniversalLinkIos(toLaunch); - }), + _launched = _launchUniversalLinkIos(toLaunch); + }), child: const Text( 'Launch a universal link in a native app, fallback to Safari.(Youtube)'), ), const Padding(padding: EdgeInsets.all(16.0)), RaisedButton( onPressed: () => setState(() { - _launched = _launchInWebViewOrVC(toLaunch); - Timer(const Duration(seconds: 5), () { - print('Closing WebView after 5 seconds...'); - closeWebView(); - }); - }), + _launched = _launchInWebViewOrVC(toLaunch); + Timer(const Duration(seconds: 5), () { + print('Closing WebView after 5 seconds...'); + closeWebView(); + }); + }), child: const Text('Launch in app + close after 5 seconds'), ), const Padding(padding: EdgeInsets.all(16.0)), diff --git a/packages/webview_flutter/example/lib/main.dart b/packages/webview_flutter/example/lib/main.dart index 7dfac5437632..5f3e0f8ff4fa 100644 --- a/packages/webview_flutter/example/lib/main.dart +++ b/packages/webview_flutter/example/lib/main.dart @@ -155,36 +155,36 @@ class SampleMenu extends StatelessWidget { } }, itemBuilder: (BuildContext context) => >[ - PopupMenuItem( - value: MenuOptions.showUserAgent, - child: const Text('Show user agent'), - enabled: controller.hasData, - ), - const PopupMenuItem( - value: MenuOptions.listCookies, - child: Text('List cookies'), - ), - const PopupMenuItem( - value: MenuOptions.clearCookies, - child: Text('Clear cookies'), - ), - const PopupMenuItem( - value: MenuOptions.addToCache, - child: Text('Add to cache'), - ), - const PopupMenuItem( - value: MenuOptions.listCache, - child: Text('List cache'), - ), - const PopupMenuItem( - value: MenuOptions.clearCache, - child: Text('Clear cache'), - ), - const PopupMenuItem( - value: MenuOptions.navigationDelegate, - child: Text('Navigation Delegate example'), - ), - ], + PopupMenuItem( + value: MenuOptions.showUserAgent, + child: const Text('Show user agent'), + enabled: controller.hasData, + ), + const PopupMenuItem( + value: MenuOptions.listCookies, + child: Text('List cookies'), + ), + const PopupMenuItem( + value: MenuOptions.clearCookies, + child: Text('Clear cookies'), + ), + const PopupMenuItem( + value: MenuOptions.addToCache, + child: Text('Add to cache'), + ), + const PopupMenuItem( + value: MenuOptions.listCache, + child: Text('List cache'), + ), + const PopupMenuItem( + value: MenuOptions.clearCache, + child: Text('Clear cache'), + ), + const PopupMenuItem( + value: MenuOptions.navigationDelegate, + child: Text('Navigation Delegate example'), + ), + ], ); }, ); From 55302f91048aea819b4978e484e90d98721fe8fd Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sat, 27 Jul 2019 12:26:11 -0700 Subject: [PATCH 03/19] Revert file that shouldn't be changed --- .../example/ios/Runner.xcodeproj/project.pbxproj | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/cloud_firestore/example/ios/Runner.xcodeproj/project.pbxproj b/packages/cloud_firestore/example/ios/Runner.xcodeproj/project.pbxproj index 80c536bb0b40..80980c30cd85 100644 --- a/packages/cloud_firestore/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/cloud_firestore/example/ios/Runner.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 5C6F5A711EC3CCCC008D64B5 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C6F5A701EC3CCCC008D64B5 /* GeneratedPluginRegistrant.m */; }; 7A1ECC911E8EDB6900309407 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7A1ECC901E8EDB6900309407 /* GoogleService-Info.plist */; }; 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; @@ -31,6 +32,7 @@ dstSubfolderSpec = 10; files = ( 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -181,7 +183,6 @@ TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; - DevelopmentTeam = DKY2FBVP6L; }; }; }; @@ -190,7 +191,6 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( - English, en, Base, ); @@ -435,7 +435,6 @@ buildSettings = { ARCHS = arm64; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = DKY2FBVP6L; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -458,7 +457,6 @@ buildSettings = { ARCHS = arm64; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = DKY2FBVP6L; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", From 095ea23747fc7b615f54216c7d6f359456faebb1 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sat, 27 Jul 2019 12:27:17 -0700 Subject: [PATCH 04/19] Revert change to example that would result in dead code --- packages/cloud_firestore/example/lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_firestore/example/lib/main.dart b/packages/cloud_firestore/example/lib/main.dart index 9c2157dc901a..27138f2fbd9e 100755 --- a/packages/cloud_firestore/example/lib/main.dart +++ b/packages/cloud_firestore/example/lib/main.dart @@ -42,7 +42,7 @@ class MessageList extends StatelessWidget { itemBuilder: (_, int index) { final DocumentSnapshot document = snapshot.data.documents[index]; return ListTile( - title: Text('${document['message']}' ?? ''), + title: Text(document['message'] ?? ''), subtitle: Text('Message ${index + 1} of $messageCount'), ); }, From 15b886219496db0fd788943965480f1c3ece47aa Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sat, 27 Jul 2019 13:04:32 -0700 Subject: [PATCH 05/19] Update to includeMetadataChanges --- packages/cloud_firestore/CHANGELOG.md | 6 ++++-- .../cloudfirestore/CloudFirestorePlugin.java | 20 ++++++------------- .../ios/Classes/CloudFirestorePlugin.m | 16 ++++----------- .../lib/src/document_reference.dart | 9 ++++----- packages/cloud_firestore/lib/src/query.dart | 9 ++++----- .../lib/src/snapshot_metadata.dart | 13 ------------ .../test/cloud_firestore_test.dart | 14 ++++++------- 7 files changed, 29 insertions(+), 58 deletions(-) diff --git a/packages/cloud_firestore/CHANGELOG.md b/packages/cloud_firestore/CHANGELOG.md index 7965a379d81f..e94f15a281c0 100644 --- a/packages/cloud_firestore/CHANGELOG.md +++ b/packages/cloud_firestore/CHANGELOG.md @@ -1,7 +1,9 @@ ## 0.12.9 -* Add support for MetadataChanges for snapshots on both Documents and Queries -* Fix example app crash when the `message` field was not a string +* New optional `includeMetadataChanges` parameter added to `DocumentReference.snapshots()` + and `Query.snapshots()` +* Fix example app crash when the `message` field was not a string +* Internal renaming of method names. ## 0.12.8 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 aa56b3112fe3..b3a451cde8d6 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 @@ -122,14 +122,6 @@ private Source getSource(Map arguments) { } } - private MetadataChanges getMetadataChanges(Map arguments) { - String metadataChanges = (String) arguments.get("metadataChanges"); - if ("include".equals(metadataChanges)) { - return MetadataChanges.INCLUDE; - } - return MetadataChanges.EXCLUDE; - } - private Object[] getDocumentValues( Map document, List> orderBy, Map arguments) { String documentId = (String) document.get("id"); @@ -625,29 +617,29 @@ public void run() { case "Query#addSnapshotListener": { Map arguments = call.arguments(); - MetadataChanges metadataChanges = getMetadataChanges(arguments); + Boolean includeMetadataChanges = (Boolean) arguments.get("includeMetadataChanges"); int handle = nextListenerHandle++; EventObserver observer = new EventObserver(handle); observers.put(handle, observer); listenerRegistrations.put( - handle, getQuery(arguments).addSnapshotListener(metadataChanges, observer)); + handle, getQuery(arguments).addSnapshotListener(includeMetadataChanges, observer)); result.success(handle); break; } - case "Query#addDocumentListener": + case "DocumentReference#addSnapshotListener": { Map arguments = call.arguments(); - MetadataChanges metadataChanges = getMetadataChanges(arguments); + Boolean includeMetadataChanges = (Boolean) arguments.get("includeMetadataChanges"); int handle = nextListenerHandle++; DocumentObserver observer = new DocumentObserver(handle); documentObservers.put(handle, observer); listenerRegistrations.put( handle, - getDocumentReference(arguments).addSnapshotListener(metadataChanges, observer)); + getDocumentReference(arguments).addSnapshotListener(includeMetadataChanges, observer)); result.success(handle); break; } - case "Query#removeListener": + case "removeListener": { Map arguments = call.arguments(); int handle = (Integer) arguments.get("handle"); diff --git a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m index dfbbf1031cf2..5ee2149e48c0 100644 --- a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m +++ b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m @@ -160,14 +160,6 @@ static FIRFirestoreSource getSource(NSDictionary *arguments) { return FIRFirestoreSourceDefault; } -static BOOL getIncludeMetadataChanges(NSDictionary *arguments) { - NSString *metadataChanges = arguments[@"metadataChanges"]; - if ([@"include" isEqualToString:metadataChanges]) { - return YES; - } - return NO; -} - static NSDictionary *parseQuerySnapshot(FIRQuerySnapshot *snapshot) { NSMutableArray *paths = [NSMutableArray array]; NSMutableArray *documents = [NSMutableArray array]; @@ -523,7 +515,6 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result } else if ([@"Query#addSnapshotListener" isEqualToString:call.method]) { __block NSNumber *handle = [NSNumber numberWithInt:_nextListenerHandle++]; FIRQuery *query; - BOOL includeMetadataChanges = getIncludeMetadataChanges(call.arguments); @try { query = getQuery(call.arguments); } @catch (NSException *exception) { @@ -531,6 +522,7 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result message:[exception name] details:[exception reason]]); } + BOOL includeMetadataChanges = call.arguments["includeMetadataChanges"].boolValue; id listener = [query addSnapshotListenerWithIncludeMetadataChanges:includeMetadataChanges listener:^(FIRQuerySnapshot *_Nullable snapshot, @@ -547,10 +539,10 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result }]; _listeners[handle] = listener; result(handle); - } else if ([@"Query#addDocumentListener" isEqualToString:call.method]) { + } else if ([@"DocumentReference#addSnapshotListener" isEqualToString:call.method]) { __block NSNumber *handle = [NSNumber numberWithInt:_nextListenerHandle++]; FIRDocumentReference *document = getDocumentReference(call.arguments); - BOOL includeMetadataChanges = getIncludeMetadataChanges(call.arguments); + BOOL includeMetadataChanges = call.arguments["includeMetadataChanges"].boolValue; id listener = [document addSnapshotListenerWithIncludeMetadataChanges:includeMetadataChanges listener:^(FIRDocumentSnapshot *snapshot, @@ -598,7 +590,7 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result } result(parseQuerySnapshot(snapshot)); }]; - } else if ([@"Query#removeListener" isEqualToString:call.method]) { + } else if ([@"removeListener" isEqualToString:call.method]) { NSNumber *handle = call.arguments[@"handle"]; [[_listeners objectForKey:handle] remove]; [_listeners removeObjectForKey:handle]; diff --git a/packages/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/lib/src/document_reference.dart index 522d2ea8a2ae..bb2592ff9034 100644 --- a/packages/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/lib/src/document_reference.dart @@ -116,8 +116,7 @@ class DocumentReference { /// Notifies of documents at this location // TODO(jackson): Reduce code duplication with [Query] - Stream snapshots( - {MetadataChanges metadataChanges = MetadataChanges.exclude}) { + Stream snapshots({bool includeMetadataChanges = false}) { assert(metadataChanges != null); Future _handle; // It's fine to let the StreamController be garbage collected once all the @@ -126,11 +125,11 @@ class DocumentReference { controller = StreamController.broadcast( onListen: () { _handle = Firestore.channel.invokeMethod( - 'Query#addDocumentListener', + 'DocumentReference#addDocumentListener', { 'app': firestore.app.name, 'path': path, - 'metadataChanges': _getMetadataChangesString(metadataChanges), + 'includeMetadataChanges': includeMetadataChanges, }, ).then((dynamic result) => result); _handle.then((int handle) { @@ -140,7 +139,7 @@ class DocumentReference { onCancel: () { _handle.then((int handle) async { await Firestore.channel.invokeMethod( - 'Query#removeListener', + 'removeListener', {'handle': handle}, ); Firestore._documentObservers.remove(handle); diff --git a/packages/cloud_firestore/lib/src/query.dart b/packages/cloud_firestore/lib/src/query.dart index 77844559072f..114b48a6df57 100644 --- a/packages/cloud_firestore/lib/src/query.dart +++ b/packages/cloud_firestore/lib/src/query.dart @@ -50,9 +50,8 @@ class Query { /// Notifies of query results at this location // TODO(jackson): Reduce code duplication with [DocumentReference] - Stream snapshots( - {MetadataChanges metadataChanges = MetadataChanges.exclude}) { - assert(metadataChanges != null); + Stream snapshots({bool includeMetadataChanges = false}) { + assert(includeMetadataChanges != null); Future _handle; // It's fine to let the StreamController be garbage collected once all the // subscribers have cancelled; this analyzer warning is safe to ignore. @@ -66,7 +65,7 @@ class Query { 'path': _path, 'isCollectionGroup': _isCollectionGroup, 'parameters': _parameters, - 'metadataChanges': _getMetadataChangesString(metadataChanges), + 'includeMetadataChanges': includeMetadataChanges, }, ).then((dynamic result) => result); _handle.then((int handle) { @@ -76,7 +75,7 @@ class Query { onCancel: () { _handle.then((int handle) async { await Firestore.channel.invokeMethod( - 'Query#removeListener', + 'removeListener', {'handle': handle}, ); Firestore._queryObservers.remove(handle); diff --git a/packages/cloud_firestore/lib/src/snapshot_metadata.dart b/packages/cloud_firestore/lib/src/snapshot_metadata.dart index 7f32e968ea0c..39f51f5928e8 100644 --- a/packages/cloud_firestore/lib/src/snapshot_metadata.dart +++ b/packages/cloud_firestore/lib/src/snapshot_metadata.dart @@ -26,16 +26,3 @@ class SnapshotMetadata { /// up-to-date data from the backend. final bool isFromCache; } - -/// Indicates whether metadata-only changes (i.e. only [DocumentSnapshot.metadata] -/// or [Query.metadata] changed) should trigger snapshot events. -enum MetadataChanges { exclude, include } - -/// Converts [MetadataChanges] to [String] -String _getMetadataChangesString(MetadataChanges metadataChanges) { - assert(metadataChanges != null); - if (metadataChanges == MetadataChanges.include) { - return 'include'; - } - return 'exclude'; -} diff --git a/packages/cloud_firestore/test/cloud_firestore_test.dart b/packages/cloud_firestore/test/cloud_firestore_test.dart index 83941c5ea1c1..1bedec5d2839 100755 --- a/packages/cloud_firestore/test/cloud_firestore_test.dart +++ b/packages/cloud_firestore/test/cloud_firestore_test.dart @@ -78,7 +78,7 @@ void main() { ); }); return handle; - case 'Query#addDocumentListener': + case 'DocumentReference#addSnapshotListener': final int handle = mockHandleId++; // Wait before sending a message back. // Otherwise the first request didn't have the time to finish. @@ -351,7 +351,7 @@ void main() { }, ), isMethodCall( - 'Query#removeListener', + 'removeListener', arguments: {'handle': 0}, ), ]); @@ -383,7 +383,7 @@ void main() { }, ), isMethodCall( - 'Query#removeListener', + 'removeListener', arguments: {'handle': 0}, ), ]), @@ -416,7 +416,7 @@ void main() { }, ), isMethodCall( - 'Query#removeListener', + 'removeListener', arguments: {'handle': 0}, ), ]), @@ -449,7 +449,7 @@ void main() { }, ), isMethodCall( - 'Query#removeListener', + 'removeListener', arguments: {'handle': 0}, ), ]), @@ -470,7 +470,7 @@ void main() { log, [ isMethodCall( - 'Query#addDocumentListener', + 'DocumentReference#addSnapshotListener', arguments: { 'app': app.name, 'path': 'path/to/foo', @@ -478,7 +478,7 @@ void main() { }, ), isMethodCall( - 'Query#removeListener', + 'removeListener', arguments: {'handle': 0}, ), ], From 4a246b08112cb96768ac86e0d56ca46052be31d3 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sat, 27 Jul 2019 13:06:32 -0700 Subject: [PATCH 06/19] Revert "Revert change to example that would result in dead code" This reverts commit 095ea23747fc7b615f54216c7d6f359456faebb1. --- packages/cloud_firestore/example/lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_firestore/example/lib/main.dart b/packages/cloud_firestore/example/lib/main.dart index 27138f2fbd9e..9c2157dc901a 100755 --- a/packages/cloud_firestore/example/lib/main.dart +++ b/packages/cloud_firestore/example/lib/main.dart @@ -42,7 +42,7 @@ class MessageList extends StatelessWidget { itemBuilder: (_, int index) { final DocumentSnapshot document = snapshot.data.documents[index]; return ListTile( - title: Text(document['message'] ?? ''), + title: Text('${document['message']}' ?? ''), subtitle: Text('Message ${index + 1} of $messageCount'), ); }, From dab7bd2fb5a3a3c526c4ac584b1b17f28d40e452 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sat, 27 Jul 2019 14:27:57 -0700 Subject: [PATCH 07/19] fix tests --- .../plugins/firebase/cloudfirestore/CloudFirestorePlugin.java | 4 ++-- packages/cloud_firestore/lib/src/document_reference.dart | 2 +- 2 files changed, 3 insertions(+), 3 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 b3a451cde8d6..23ea350fbdf1 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 @@ -31,7 +31,6 @@ import com.google.firebase.firestore.FirebaseFirestoreSettings; import com.google.firebase.firestore.GeoPoint; import com.google.firebase.firestore.ListenerRegistration; -import com.google.firebase.firestore.MetadataChanges; import com.google.firebase.firestore.Query; import com.google.firebase.firestore.QuerySnapshot; import com.google.firebase.firestore.SetOptions; @@ -635,7 +634,8 @@ public void run() { documentObservers.put(handle, observer); listenerRegistrations.put( handle, - getDocumentReference(arguments).addSnapshotListener(includeMetadataChanges, observer)); + getDocumentReference(arguments) + .addSnapshotListener(includeMetadataChanges, observer)); result.success(handle); break; } diff --git a/packages/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/lib/src/document_reference.dart index bb2592ff9034..9b332d12699f 100644 --- a/packages/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/lib/src/document_reference.dart @@ -117,7 +117,7 @@ class DocumentReference { /// Notifies of documents at this location // TODO(jackson): Reduce code duplication with [Query] Stream snapshots({bool includeMetadataChanges = false}) { - assert(metadataChanges != null); + assert(includeMetadataChanges != null); Future _handle; // It's fine to let the StreamController be garbage collected once all the // subscribers have cancelled; this analyzer warning is safe to ignore. From b0abf2f237b3a4f558e2abaa4613759dbffe8f9e Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sat, 27 Jul 2019 14:51:58 -0700 Subject: [PATCH 08/19] Update tests --- .../lib/src/document_reference.dart | 2 +- .../test/cloud_firestore_test.dart | 21 +++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/lib/src/document_reference.dart index 9b332d12699f..413cf41be0be 100644 --- a/packages/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/lib/src/document_reference.dart @@ -125,7 +125,7 @@ class DocumentReference { controller = StreamController.broadcast( onListen: () { _handle = Firestore.channel.invokeMethod( - 'DocumentReference#addDocumentListener', + 'DocumentReference#addSnapshotListener', { 'app': firestore.app.name, 'path': path, diff --git a/packages/cloud_firestore/test/cloud_firestore_test.dart b/packages/cloud_firestore/test/cloud_firestore_test.dart index 1bedec5d2839..59b7454262b7 100755 --- a/packages/cloud_firestore/test/cloud_firestore_test.dart +++ b/packages/cloud_firestore/test/cloud_firestore_test.dart @@ -328,8 +328,9 @@ void main() { expect(collectionReference.path, equals('foo')); }); test('listen', () async { - final QuerySnapshot snapshot = - await collectionReference.snapshots().first; + final QuerySnapshot snapshot = await collectionReference + .snapshots(includeMetadataChanges: true) + .first; final DocumentSnapshot document = snapshot.documents[0]; expect(document.documentID, equals('0')); expect(document.reference.path, equals('foo/0')); @@ -347,7 +348,7 @@ void main() { 'where': >[], 'orderBy': >[], }, - 'metadataChanges': 'exclude', + 'includeMetadataChanges': true, }, ), isMethodCall( @@ -379,7 +380,7 @@ void main() { ], 'orderBy': >[], }, - 'metadataChanges': 'exclude', + 'includeMetadataChanges': false, }, ), isMethodCall( @@ -412,7 +413,7 @@ void main() { ], 'orderBy': >[], }, - 'metadataChanges': 'exclude', + 'includeMetadataChanges': false, }, ), isMethodCall( @@ -445,7 +446,7 @@ void main() { ['createdAt', false] ], }, - 'metadataChanges': 'exclude', + 'includeMetadataChanges': false, }, ), isMethodCall( @@ -459,8 +460,10 @@ void main() { group('DocumentReference', () { test('listen', () async { - final DocumentSnapshot snapshot = - await firestore.document('path/to/foo').snapshots().first; + final DocumentSnapshot snapshot = await firestore + .document('path/to/foo') + .snapshots(includeMetadataChanges: true) + .first; expect(snapshot.documentID, equals('foo')); expect(snapshot.reference.path, equals('path/to/foo')); expect(snapshot.data, equals(kMockDocumentSnapshotData)); @@ -474,7 +477,7 @@ void main() { arguments: { 'app': app.name, 'path': 'path/to/foo', - 'metadataChanges': 'exclude', + 'includeMetadataChanges': true, }, ), isMethodCall( From 77ea54f7cbe5291b0fd43d7c2d9f9533ac957e9a Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sat, 27 Jul 2019 15:09:39 -0700 Subject: [PATCH 09/19] Fix Java --- .../cloudfirestore/CloudFirestorePlugin.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 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 23ea350fbdf1..cc058944b3eb 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 @@ -616,26 +616,31 @@ public void run() { case "Query#addSnapshotListener": { Map arguments = call.arguments(); - Boolean includeMetadataChanges = (Boolean) arguments.get("includeMetadataChanges"); int handle = nextListenerHandle++; EventObserver observer = new EventObserver(handle); observers.put(handle, observer); + MetadataChanges metadataChanges = + (Boolean) arguments.get("includeMetadataChanges") + ? MetadataChanges.include + : MetadataChanges.exclude; listenerRegistrations.put( - handle, getQuery(arguments).addSnapshotListener(includeMetadataChanges, observer)); + handle, getQuery(arguments).addSnapshotListener(metadataChanges, observer)); result.success(handle); break; } case "DocumentReference#addSnapshotListener": { Map arguments = call.arguments(); - Boolean includeMetadataChanges = (Boolean) arguments.get("includeMetadataChanges"); int handle = nextListenerHandle++; DocumentObserver observer = new DocumentObserver(handle); documentObservers.put(handle, observer); + MetadataChanges metadataChanges = + (Boolean) arguments.get("includeMetadataChanges") + ? MetadataChanges.include + : MetadataChanges.exclude; listenerRegistrations.put( handle, - getDocumentReference(arguments) - .addSnapshotListener(includeMetadataChanges, observer)); + getDocumentReference(arguments).addSnapshotListener(metadataChanges, observer)); result.success(handle); break; } From 37388cb632b24f00dd97b81662258286a04efd8c Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sat, 27 Jul 2019 15:13:43 -0700 Subject: [PATCH 10/19] Fix compile error --- .../firebase/cloudfirestore/CloudFirestorePlugin.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 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 cc058944b3eb..a13bcbe84d63 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 @@ -31,6 +31,7 @@ import com.google.firebase.firestore.FirebaseFirestoreSettings; import com.google.firebase.firestore.GeoPoint; import com.google.firebase.firestore.ListenerRegistration; +import com.google.firebase.firestore.MetadataChanges; import com.google.firebase.firestore.Query; import com.google.firebase.firestore.QuerySnapshot; import com.google.firebase.firestore.SetOptions; @@ -621,8 +622,8 @@ public void run() { observers.put(handle, observer); MetadataChanges metadataChanges = (Boolean) arguments.get("includeMetadataChanges") - ? MetadataChanges.include - : MetadataChanges.exclude; + ? MetadataChanges.INCLUDE + : MetadataChanges.EXCLUDE; listenerRegistrations.put( handle, getQuery(arguments).addSnapshotListener(metadataChanges, observer)); result.success(handle); @@ -636,8 +637,8 @@ public void run() { documentObservers.put(handle, observer); MetadataChanges metadataChanges = (Boolean) arguments.get("includeMetadataChanges") - ? MetadataChanges.include - : MetadataChanges.exclude; + ? MetadataChanges.INCLUDE + : MetadataChanges.EXCLUDE; listenerRegistrations.put( handle, getDocumentReference(arguments).addSnapshotListener(metadataChanges, observer)); From 5caddd52abc4367b6737c288c1e2ddc96694433e Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sat, 27 Jul 2019 20:04:38 -0700 Subject: [PATCH 11/19] Fix iOS compile --- 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 5ee2149e48c0..dcedfbae064e 100644 --- a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m +++ b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m @@ -522,9 +522,9 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result message:[exception name] details:[exception reason]]); } - BOOL includeMetadataChanges = call.arguments["includeMetadataChanges"].boolValue; + NSNumber *includeMetadataChanges = call.arguments[@"includeMetadataChanges"]; id listener = [query - addSnapshotListenerWithIncludeMetadataChanges:includeMetadataChanges + addSnapshotListenerWithIncludeMetadataChanges:includeMetadataChanges.boolValue listener:^(FIRQuerySnapshot *_Nullable snapshot, NSError *_Nullable error) { if (snapshot == nil) { From 0967909dbd5fa80f2e0e883bc086cef6fdf4a8f7 Mon Sep 17 00:00:00 2001 From: Razvan Cristian Lung Date: Sun, 28 Jul 2019 07:44:05 +0300 Subject: [PATCH 12/19] fix: use the string values of the message when it's not null --- packages/cloud_firestore/example/lib/main.dart | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/cloud_firestore/example/lib/main.dart b/packages/cloud_firestore/example/lib/main.dart index 9c2157dc901a..30c1e2ce3036 100755 --- a/packages/cloud_firestore/example/lib/main.dart +++ b/packages/cloud_firestore/example/lib/main.dart @@ -41,8 +41,11 @@ class MessageList extends StatelessWidget { itemCount: messageCount, itemBuilder: (_, int index) { final DocumentSnapshot document = snapshot.data.documents[index]; + final dynamic message = document['message']; return ListTile( - title: Text('${document['message']}' ?? ''), + title: Text( + message != null ? message.toString() : '', + ), subtitle: Text('Message ${index + 1} of $messageCount'), ); }, @@ -54,7 +57,9 @@ class MessageList extends StatelessWidget { class MyHomePage extends StatelessWidget { MyHomePage({this.firestore}); + final Firestore firestore; + CollectionReference get messages => firestore.collection('messages'); Future _addMessage() async { From 532ab99bf1a1cda4b73f73a08b510d3dceb1123d Mon Sep 17 00:00:00 2001 From: Razvan Cristian Lung Date: Sun, 28 Jul 2019 09:06:03 +0300 Subject: [PATCH 13/19] test: add integration test for metadata changes --- .../example/test_driver/cloud_firestore.dart | 6 ++++-- packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m | 4 ++-- 2 files changed, 6 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 d7d85db5b000..de3f0385e682 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -1,8 +1,10 @@ import 'dart:async'; -import 'package:flutter_driver/driver_extension.dart'; -import 'package:flutter_test/flutter_test.dart'; + import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter_driver/driver_extension.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:test/test.dart' as prefix0; void main() { final Completer completer = Completer(); diff --git a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m index dcedfbae064e..489c318fb3f1 100644 --- a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m +++ b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m @@ -542,9 +542,9 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result } else if ([@"DocumentReference#addSnapshotListener" isEqualToString:call.method]) { __block NSNumber *handle = [NSNumber numberWithInt:_nextListenerHandle++]; FIRDocumentReference *document = getDocumentReference(call.arguments); - BOOL includeMetadataChanges = call.arguments["includeMetadataChanges"].boolValue; + NSNumber *includeMetadataChanges = call.arguments[@"includeMetadataChanges"]; id listener = [document - addSnapshotListenerWithIncludeMetadataChanges:includeMetadataChanges + addSnapshotListenerWithIncludeMetadataChanges:includeMetadataChanges.boolValue listener:^(FIRDocumentSnapshot *snapshot, NSError *_Nullable error) { if (snapshot == nil) { From 2221d75d03650335f861cd0b393e9d77395117b6 Mon Sep 17 00:00:00 2001 From: Razvan Cristian Lung Date: Sun, 28 Jul 2019 09:10:18 +0300 Subject: [PATCH 14/19] fix: remove unused import --- .../ios/Runner.xcodeproj/project.pbxproj | 24 ++++++++++++------- .../example/test_driver/cloud_firestore.dart | 1 - 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/packages/cloud_firestore/example/ios/Runner.xcodeproj/project.pbxproj b/packages/cloud_firestore/example/ios/Runner.xcodeproj/project.pbxproj index 80980c30cd85..8768d268c089 100644 --- a/packages/cloud_firestore/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/cloud_firestore/example/ios/Runner.xcodeproj/project.pbxproj @@ -13,7 +13,6 @@ 5C6F5A711EC3CCCC008D64B5 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C6F5A701EC3CCCC008D64B5 /* GeneratedPluginRegistrant.m */; }; 7A1ECC911E8EDB6900309407 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7A1ECC901E8EDB6900309407 /* GoogleService-Info.plist */; }; 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; @@ -32,7 +31,6 @@ dstSubfolderSpec = 10; files = ( 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -42,8 +40,10 @@ /* Begin PBXFileReference section */ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 5242063BF2F3A395B1EE213B /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 5C6F5A6F1EC3CCCC008D64B5 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 5C6F5A701EC3CCCC008D64B5 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 6D4ADF07FEA795BA476E640D /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 7A1ECC901E8EDB6900309407 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; @@ -77,6 +77,8 @@ 840012C8B5EDBCF56B0E4AC1 /* Pods */ = { isa = PBXGroup; children = ( + 6D4ADF07FEA795BA476E640D /* Pods-Runner.debug.xcconfig */, + 5242063BF2F3A395B1EE213B /* Pods-Runner.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -183,6 +185,7 @@ TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; + DevelopmentTeam = DKY2FBVP6L; }; }; }; @@ -191,6 +194,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); @@ -242,16 +246,16 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-C++/gRPCCertificates-Cpp.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates-Cpp.bundle", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; showEnvVarsInLog = 0; }; 95BB15E9E1769C0D146AA592 /* [CP] Embed Pods Frameworks */ = { @@ -260,8 +264,8 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${PODS_ROOT}/../.symlinks/flutter/ios-release/Flutter.framework", + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( @@ -269,7 +273,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; 9740EEB61CF901F6004384FC /* Run Script */ = { @@ -435,6 +439,7 @@ buildSettings = { ARCHS = arm64; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = DKY2FBVP6L; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -457,6 +462,7 @@ buildSettings = { ARCHS = arm64; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = DKY2FBVP6L; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", diff --git a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart index de3f0385e682..b775cd232999 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -4,7 +4,6 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter_driver/driver_extension.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:test/test.dart' as prefix0; void main() { final Completer completer = Completer(); From 245e2f449b9912af553fa30df6c1f84b890c99bc Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sun, 28 Jul 2019 13:08:23 -0700 Subject: [PATCH 15/19] Revert project.pbxproj --- .../ios/Runner.xcodeproj/project.pbxproj | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/packages/cloud_firestore/example/ios/Runner.xcodeproj/project.pbxproj b/packages/cloud_firestore/example/ios/Runner.xcodeproj/project.pbxproj index 8768d268c089..80980c30cd85 100644 --- a/packages/cloud_firestore/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/cloud_firestore/example/ios/Runner.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 5C6F5A711EC3CCCC008D64B5 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C6F5A701EC3CCCC008D64B5 /* GeneratedPluginRegistrant.m */; }; 7A1ECC911E8EDB6900309407 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7A1ECC901E8EDB6900309407 /* GoogleService-Info.plist */; }; 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; @@ -31,6 +32,7 @@ dstSubfolderSpec = 10; files = ( 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -40,10 +42,8 @@ /* Begin PBXFileReference section */ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; - 5242063BF2F3A395B1EE213B /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 5C6F5A6F1EC3CCCC008D64B5 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 5C6F5A701EC3CCCC008D64B5 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 6D4ADF07FEA795BA476E640D /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 7A1ECC901E8EDB6900309407 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; @@ -77,8 +77,6 @@ 840012C8B5EDBCF56B0E4AC1 /* Pods */ = { isa = PBXGroup; children = ( - 6D4ADF07FEA795BA476E640D /* Pods-Runner.debug.xcconfig */, - 5242063BF2F3A395B1EE213B /* Pods-Runner.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -185,7 +183,6 @@ TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; - DevelopmentTeam = DKY2FBVP6L; }; }; }; @@ -194,7 +191,6 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( - English, en, Base, ); @@ -246,16 +242,16 @@ files = ( ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-C++/gRPCCertificates-Cpp.bundle", + "${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates-Cpp.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; showEnvVarsInLog = 0; }; 95BB15E9E1769C0D146AA592 /* [CP] Embed Pods Frameworks */ = { @@ -264,8 +260,8 @@ files = ( ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework", + "${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${PODS_ROOT}/../.symlinks/flutter/ios-release/Flutter.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( @@ -273,7 +269,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; 9740EEB61CF901F6004384FC /* Run Script */ = { @@ -439,7 +435,6 @@ buildSettings = { ARCHS = arm64; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = DKY2FBVP6L; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -462,7 +457,6 @@ buildSettings = { ARCHS = arm64; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = DKY2FBVP6L; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", From 29a20eb0e9cf48ef97fb651b75a8cf287ea84014 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sun, 28 Jul 2019 13:32:17 -0700 Subject: [PATCH 16/19] Added integration test --- .../example/test_driver/cloud_firestore.dart | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart index be037e367e17..94395d075ec1 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -106,6 +106,32 @@ void main() { await ref.delete(); }); + test('includeMetadataChanges', () async { + final DocumentReference ref = firestore.collection('messages').document(); + Future streamWithoutMetadataChanges = + ref.snapshots(includeMetadataChanges: false).first; + Stream streamWithMetadataChanges = + ref.snapshots(includeMetadataChanges: true).take(2); + + ref.setData({'hello': 'world'}); + + DocumentSnapshot snapshot = await streamWithoutMetadataChanges; + expect(snapshot.metadata.hasPendingWrites, true); + expect(snapshot.metadata.isFromCache, true); + expect(snapshot.data['hello'], 'world'); + + List snapshots = + await streamWithMetadataChanges.toList(); + expect(snapshots[0].metadata.isFromCache, true); + expect(snapshots[0].metadata.hasPendingWrites, true); + expect(snapshots[0].data['hello'], 'world'); + expect(snapshots[1].metadata.hasPendingWrites, false); + expect(snapshots[1].metadata.isFromCache, false); + expect(snapshots[1].data['hello'], 'world'); + + await ref.delete(); + }); + test('runTransaction', () async { final DocumentReference ref = firestore.collection('messages').document(); await ref.setData({ From b35d86e2a17335e9e35387160162105f91ce2db3 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sun, 28 Jul 2019 13:53:17 -0700 Subject: [PATCH 17/19] Fix metadata test and lints --- .../example/test_driver/cloud_firestore.dart | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart index 94395d075ec1..0e2b8433b86b 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -108,26 +108,29 @@ void main() { test('includeMetadataChanges', () async { final DocumentReference ref = firestore.collection('messages').document(); - Future streamWithoutMetadataChanges = + final Future streamWithoutMetadataChanges = ref.snapshots(includeMetadataChanges: false).first; - Stream streamWithMetadataChanges = - ref.snapshots(includeMetadataChanges: true).take(2); + final Stream streamWithMetadataChanges = + ref.snapshots(includeMetadataChanges: true).take(3); ref.setData({'hello': 'world'}); - DocumentSnapshot snapshot = await streamWithoutMetadataChanges; + final DocumentSnapshot snapshot = await streamWithoutMetadataChanges; expect(snapshot.metadata.hasPendingWrites, true); expect(snapshot.metadata.isFromCache, true); expect(snapshot.data['hello'], 'world'); - List snapshots = + final List snapshots = await streamWithMetadataChanges.toList(); - expect(snapshots[0].metadata.isFromCache, true); expect(snapshots[0].metadata.hasPendingWrites, true); + expect(snapshots[0].metadata.isFromCache, true); expect(snapshots[0].data['hello'], 'world'); - expect(snapshots[1].metadata.hasPendingWrites, false); + expect(snapshots[1].metadata.hasPendingWrites, true); expect(snapshots[1].metadata.isFromCache, false); expect(snapshots[1].data['hello'], 'world'); + expect(snapshots[2].metadata.hasPendingWrites, false); + expect(snapshots[2].metadata.isFromCache, false); + expect(snapshots[2].data['hello'], 'world'); await ref.delete(); }); From 90fdbcef0d42ba66db53ca6d2c5c95875aed6f90 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sun, 28 Jul 2019 14:19:51 -0700 Subject: [PATCH 18/19] Update cloud_firestore.dart --- .../example/test_driver/cloud_firestore.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart index 0e2b8433b86b..7bb40063b3d0 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -108,20 +108,20 @@ void main() { test('includeMetadataChanges', () async { final DocumentReference ref = firestore.collection('messages').document(); - final Future streamWithoutMetadataChanges = - ref.snapshots(includeMetadataChanges: false).first; - final Stream streamWithMetadataChanges = + final Future snapshotsWithoutMetadataChanges = + ref.snapshots(includeMetadataChanges: false).take(1); + final Stream snapshotsWithMetadataChanges = ref.snapshots(includeMetadataChanges: true).take(3); ref.setData({'hello': 'world'}); - final DocumentSnapshot snapshot = await streamWithoutMetadataChanges; + final DocumentSnapshot snapshot = await snapshotsWithoutMetadataChanges.first; expect(snapshot.metadata.hasPendingWrites, true); expect(snapshot.metadata.isFromCache, true); expect(snapshot.data['hello'], 'world'); final List snapshots = - await streamWithMetadataChanges.toList(); + await snapshotsWithMetadataChanges.toList(); expect(snapshots[0].metadata.hasPendingWrites, true); expect(snapshots[0].metadata.isFromCache, true); expect(snapshots[0].data['hello'], 'world'); From 4c942a26a35f41a218ecd0ae2ad5f5d9f843f00e Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Sun, 28 Jul 2019 22:50:33 -0700 Subject: [PATCH 19/19] Fix test + reformat --- .../cloud_firestore/example/test_driver/cloud_firestore.dart | 5 +++-- 1 file changed, 3 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 7bb40063b3d0..2c984f7d6985 100644 --- a/packages/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -108,14 +108,15 @@ void main() { test('includeMetadataChanges', () async { final DocumentReference ref = firestore.collection('messages').document(); - final Future snapshotsWithoutMetadataChanges = + final Stream snapshotWithoutMetadataChanges = ref.snapshots(includeMetadataChanges: false).take(1); final Stream snapshotsWithMetadataChanges = ref.snapshots(includeMetadataChanges: true).take(3); ref.setData({'hello': 'world'}); - final DocumentSnapshot snapshot = await snapshotsWithoutMetadataChanges.first; + final DocumentSnapshot snapshot = + await snapshotWithoutMetadataChanges.first; expect(snapshot.metadata.hasPendingWrites, true); expect(snapshot.metadata.isFromCache, true); expect(snapshot.data['hello'], 'world');