diff --git a/packages/_flutterfire_internals/lib/_flutterfire_internals.dart b/packages/_flutterfire_internals/lib/_flutterfire_internals.dart index b4c6b6c905fd..1c6add47c8a8 100644 --- a/packages/_flutterfire_internals/lib/_flutterfire_internals.dart +++ b/packages/_flutterfire_internals/lib/_flutterfire_internals.dart @@ -17,7 +17,8 @@ import 'src/interop_shimmer.dart' if (dart.library.js_interop) 'package:firebase_core_web/firebase_core_web_interop.dart' as core_interop; import 'src/interop_shimmer.dart' - if (dart.library.js_interop) 'src/js_interop.dart' as js_interop; + if (dart.library.js_interop) 'src/js_interop.dart' + as js_interop; export 'src/exception.dart'; @@ -70,17 +71,14 @@ FirebaseException _firebaseExceptionFromCoreFirebaseError( final convertCode = _safeConvertFromPossibleJSObject(firebaseError.code); final code = codeParser(convertCode); - final String convertMessage = - _safeConvertFromPossibleJSObject(firebaseError.message); + final String convertMessage = _safeConvertFromPossibleJSObject( + firebaseError.message, + ); final message = messageParser != null ? messageParser(code, convertMessage) : convertMessage.replaceFirst('(${firebaseError.code})', ''); - return FirebaseException( - plugin: plugin, - message: message, - code: code, - ); + return FirebaseException(plugin: plugin, message: message, code: code); } /// Checks whether a thrown object needs to be mapped using [_mapException] or @@ -135,30 +133,32 @@ R guardWebExceptions( if (value is Future) { return value.catchError( - (err, stack) => Error.throwWithStackTrace( - _mapException( - err, - plugin: plugin, - codeParser: codeParser, - messageParser: messageParser, - ), - stack, - ), - test: _testException, - ) as R; + (err, stack) => Error.throwWithStackTrace( + _mapException( + err, + plugin: plugin, + codeParser: codeParser, + messageParser: messageParser, + ), + stack, + ), + test: _testException, + ) + as R; } else if (value is Stream) { return value.handleError( - (err, stack) => Error.throwWithStackTrace( - _mapException( - err, - plugin: plugin, - codeParser: codeParser, - messageParser: messageParser, - ), - stack, - ), - test: _testException, - ) as R; + (err, stack) => Error.throwWithStackTrace( + _mapException( + err, + plugin: plugin, + codeParser: codeParser, + messageParser: messageParser, + ), + stack, + ), + test: _testException, + ) + as R; } return value; diff --git a/packages/_flutterfire_internals/pubspec.yaml b/packages/_flutterfire_internals/pubspec.yaml index 4fe0ada562d2..3c6321c51d5b 100755 --- a/packages/_flutterfire_internals/pubspec.yaml +++ b/packages/_flutterfire_internals/pubspec.yaml @@ -6,8 +6,8 @@ version: 1.3.77 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: collection: ^1.0.0 diff --git a/packages/_flutterfire_internals/test/exception_test.dart b/packages/_flutterfire_internals/test/exception_test.dart index 4cd37d650bc2..6cdc5b480803 100644 --- a/packages/_flutterfire_internals/test/exception_test.dart +++ b/packages/_flutterfire_internals/test/exception_test.dart @@ -16,7 +16,8 @@ void main() { message: 'a channel level message', details: { 'code': 'permission-denied', - 'message': "Client doesn't have permission to access the desired " + 'message': + "Client doesn't have permission to access the desired " 'data.', }, ), diff --git a/packages/_flutterfire_internals/test/guard_test.dart b/packages/_flutterfire_internals/test/guard_test.dart index 7e8332d6e74f..a4bb9bc1cf33 100644 --- a/packages/_flutterfire_internals/test/guard_test.dart +++ b/packages/_flutterfire_internals/test/guard_test.dart @@ -8,63 +8,70 @@ import 'package:flutter_test/flutter_test.dart'; void main() { group('guardWebException', () { - test('preserves stacktrace on futures that fail with FirebaseError', - () async { - final current = StackTrace.current; - try { - await guardWebExceptions( - () => Future.error(_FirebaseError(), current), - plugin: 'test', - codeParser: (c) => c, - ); - fail('dead code'); - } catch (err, stack) { - expect(stack, current); - } - }); + test( + 'preserves stacktrace on futures that fail with FirebaseError', + () async { + final current = StackTrace.current; + try { + await guardWebExceptions( + () => Future.error(_FirebaseError(), current), + plugin: 'test', + codeParser: (c) => c, + ); + fail('dead code'); + } catch (err, stack) { + expect(stack, current); + } + }, + ); - test('preserves stacktrace on streams that fail with FirebaseError', - () async { - final current = StackTrace.current; - try { - await guardWebExceptions( - () => Stream.error(_FirebaseError(), current), - plugin: 'test', - codeParser: (c) => c, - ).first; - fail('dead code'); - } catch (err, stack) { - expect(stack, current); - } - }); + test( + 'preserves stacktrace on streams that fail with FirebaseError', + () async { + final current = StackTrace.current; + try { + await guardWebExceptions( + () => Stream.error(_FirebaseError(), current), + plugin: 'test', + codeParser: (c) => c, + ).first; + fail('dead code'); + } catch (err, stack) { + expect(stack, current); + } + }, + ); - test('preserves stacktrace on functions that throw a FirebaseError', - () async { - final current = StackTrace.current; - try { - guardWebExceptions( - () => Error.throwWithStackTrace(_FirebaseError(), current), - plugin: 'test', - codeParser: (c) => c, - ); - fail('dead code'); - } catch (err, stack) { - expect(stack, current); - } - }); + test( + 'preserves stacktrace on functions that throw a FirebaseError', + () async { + final current = StackTrace.current; + try { + guardWebExceptions( + () => Error.throwWithStackTrace(_FirebaseError(), current), + plugin: 'test', + codeParser: (c) => c, + ); + fail('dead code'); + } catch (err, stack) { + expect(stack, current); + } + }, + ); test( - 'propagates plain Dart errors from Futures (e.g. ArgumentError on web)', - () async { - await expectLater( - guardWebExceptions( - () => Future.error(ArgumentError('test')), - plugin: 'test', - codeParser: (c) => c, - ), - throwsA(isA()), - ); - }); + 'propagates plain Dart errors from Futures (e.g. ArgumentError on web)', + () async { + await expectLater( + guardWebExceptions( + () => Future.error(ArgumentError('test')), + plugin: 'test', + codeParser: (c) => c, + ), + throwsA(isA()), + ); + }, + ); }); } diff --git a/packages/cloud_firestore/cloud_firestore/dartpad/lib/main.dart b/packages/cloud_firestore/cloud_firestore/dartpad/lib/main.dart index 82bcf0299d02..a18b9c6b83c3 100644 --- a/packages/cloud_firestore/cloud_firestore/dartpad/lib/main.dart +++ b/packages/cloud_firestore/cloud_firestore/dartpad/lib/main.dart @@ -24,14 +24,7 @@ final moviesRef = FirebaseFirestore.instance ); /// The different ways that we can filter/sort movies. -enum MovieQuery { - year, - likesAsc, - likesDesc, - score, - sciFi, - fantasy, -} +enum MovieQuery { year, likesAsc, likesDesc, score, sciFi, fantasy } extension on Query { /// Create a firebase query from a [MovieQuery] @@ -39,11 +32,12 @@ extension on Query { return switch (query) { MovieQuery.fantasy => where('genre', arrayContainsAny: ['Fantasy']), MovieQuery.sciFi => where('genre', arrayContainsAny: ['Sci-Fi']), - MovieQuery.likesAsc || - MovieQuery.likesDesc => - orderBy('likes', descending: query == MovieQuery.likesDesc), + MovieQuery.likesAsc || MovieQuery.likesDesc => orderBy( + 'likes', + descending: query == MovieQuery.likesDesc, + ), MovieQuery.year => orderBy('year', descending: true), - MovieQuery.score => orderBy('score', descending: true) + MovieQuery.score => orderBy('score', descending: true), }; } } @@ -57,9 +51,7 @@ class FirestoreExampleApp extends StatelessWidget { return MaterialApp( title: 'Firestore Example App', theme: ThemeData.dark(), - home: const Scaffold( - body: Center(child: FilmList()), - ), + home: const Scaffold(body: Center(child: FilmList())), ); } } @@ -148,9 +140,7 @@ class _FilmListState extends State { stream: moviesRef.queryBy(query).snapshots(), builder: (context, snapshot) { if (snapshot.hasError) { - return Center( - child: Text(snapshot.error.toString()), - ); + return Center(child: Text(snapshot.error.toString())); } if (!snapshot.hasData) { @@ -193,10 +183,7 @@ class _MovieItem extends StatelessWidget { /// Returns the movie poster. Widget get poster { - return SizedBox( - width: 100, - child: Image.network(movie.poster), - ); + return SizedBox(width: 100, child: Image.network(movie.poster)); } /// Returns movie details. @@ -209,10 +196,7 @@ class _MovieItem extends StatelessWidget { title, metadata, genres, - Likes( - reference: reference, - currentLikes: movie.likes, - ), + Likes(reference: reference, currentLikes: movie.likes), ], ), ); @@ -251,10 +235,7 @@ class _MovieItem extends StatelessWidget { padding: const EdgeInsets.only(right: 2), child: Chip( backgroundColor: Colors.lightBlue, - label: Text( - genre, - style: const TextStyle(color: Colors.white), - ), + label: Text(genre, style: const TextStyle(color: Colors.white)), ), ), ]; @@ -264,9 +245,7 @@ class _MovieItem extends StatelessWidget { Widget get genres { return Padding( padding: const EdgeInsets.only(top: 8), - child: Wrap( - children: genreItems, - ), + child: Wrap(children: genreItems), ); } @@ -289,11 +268,8 @@ class _MovieItem extends StatelessWidget { class Likes extends StatefulWidget { /// Constructs a new [Likes] instance with a given [DocumentReference] and /// current like count. - Likes({ - Key? key, - required this.reference, - required this.currentLikes, - }) : super(key: key); + Likes({Key? key, required this.reference, required this.currentLikes}) + : super(key: key); /// The reference relating to the counter. final DocumentReference reference; @@ -323,10 +299,12 @@ class _LikesState extends State { // We use a transaction because multiple users could update the likes count // simultaneously. As such, our likes count may be different from the likes // count on the server. - int newLikes = await FirebaseFirestore.instance - .runTransaction((transaction) async { - DocumentSnapshot movie = - await transaction.get(widget.reference); + int newLikes = await FirebaseFirestore.instance.runTransaction(( + transaction, + ) async { + DocumentSnapshot movie = await transaction.get( + widget.reference, + ); if (!movie.exists) { throw Exception('Document does not exist!'); @@ -387,15 +365,15 @@ class Movie { }); Movie.fromJson(Map json) - : this( - genre: (json['genre']! as List).cast(), - likes: json['likes']! as int, - poster: json['poster']! as String, - rated: json['rated']! as String, - runtime: json['runtime']! as String, - title: json['title']! as String, - year: json['year']! as int, - ); + : this( + genre: (json['genre']! as List).cast(), + likes: json['likes']! as int, + poster: json['poster']! as String, + rated: json['rated']! as String, + runtime: json['runtime']! as String, + title: json['title']! as String, + year: json['year']! as int, + ); final String poster; final int likes; diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/collection_reference_e2e.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/collection_reference_e2e.dart index 73038acec97b..e62c63826704 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/collection_reference_e2e.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/collection_reference_e2e.dart @@ -19,12 +19,13 @@ void runCollectionReferenceTests() { Future>> initializeTest( String id, ) async { - CollectionReference> collection = - firestore.collection('flutter-tests/$id/query-tests'); + CollectionReference> collection = firestore + .collection('flutter-tests/$id/query-tests'); QuerySnapshot> snapshot = await collection.get(); - await Future.forEach(snapshot.docs, - (DocumentSnapshot> documentSnapshot) { + await Future.forEach(snapshot.docs, ( + DocumentSnapshot> documentSnapshot, + ) { return documentSnapshot.reference.delete(); }); return collection; @@ -42,170 +43,192 @@ void runCollectionReferenceTests() { expect(randNum, equals(snapshot.data()!['value'])); }); - test( - 'snapshots() can be reused', - () async { + test('snapshots() can be reused', () async { + final foo = await initializeTest('foo'); + + final snapshot = foo.snapshots(); + final snapshot2 = foo.snapshots(); + + expect( + await snapshot.first, + isA>>().having( + (e) => e.docs, + 'docs', + [], + ), + ); + expect( + await snapshot2.first, + isA>>().having( + (e) => e.docs, + 'docs', + [], + ), + ); + + await foo.add({'value': 42}); + + expect( + await snapshot.first, + isA>>().having( + (e) => e.docs, + 'docs', + [ + isA().having((e) => e.data(), 'data', { + 'value': 42, + }), + ], + ), + ); + expect( + await snapshot2.first, + isA>>().having( + (e) => e.docs, + 'docs', + [ + isA>>().having( + (e) => e.data(), + 'data', + {'value': 42}, + ), + ], + ), + ); + }, skip: defaultTargetPlatform == TargetPlatform.windows); + + group('withConverter', () { + test('add/snapshot', () async { final foo = await initializeTest('foo'); + final fooConverter = foo.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - final snapshot = foo.snapshots(); - final snapshot2 = foo.snapshots(); - - expect( - await snapshot.first, - isA>>() - .having((e) => e.docs, 'docs', []), + final fooSnapshot = foo.snapshots(); + final fooConverterSnapshot = fooConverter.snapshots(); + + await expectLater( + fooSnapshot, + emits( + isA>>().having( + (e) => e.docs, + 'docs', + [], + ), + ), ); - expect( - await snapshot2.first, - isA>>() - .having((e) => e.docs, 'docs', []), + await expectLater( + fooConverterSnapshot, + emits(isA>().having((e) => e.docs, 'docs', [])), ); - await foo.add({'value': 42}); + final newDocument = await fooConverter.add(42); - expect( - await snapshot.first, - isA>>() - .having((e) => e.docs, 'docs', [ - isA() - .having((e) => e.data(), 'data', {'value': 42}), - ]), + await expectLater( + newDocument.get(), + completion( + isA>().having((e) => e.data(), 'data', 42), + ), ); - expect( - await snapshot2.first, - isA>>() - .having((e) => e.docs, 'docs', [ - isA>>() - .having((e) => e.data(), 'data', {'value': 42}), - ]), + + await expectLater( + fooSnapshot, + emits( + isA().having((e) => e.docs, 'docs', [ + isA().having((e) => e.data(), 'data', { + 'value': 42, + }), + ]), + ), ); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); - - group( - 'withConverter', - () { - test( - 'add/snapshot', - () async { - final foo = await initializeTest('foo'); - final fooConverter = foo.withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); - - final fooSnapshot = foo.snapshots(); - final fooConverterSnapshot = fooConverter.snapshots(); - - await expectLater( - fooSnapshot, - emits( - isA>>() - .having((e) => e.docs, 'docs', []), - ), - ); - await expectLater( - fooConverterSnapshot, - emits( - isA>().having((e) => e.docs, 'docs', []), + await expectLater( + fooConverterSnapshot, + emits( + isA>().having((e) => e.docs, 'docs', [ + isA>().having( + (e) => e.data(), + 'data', + 42, ), - ); - - final newDocument = await fooConverter.add(42); + ]), + ), + ); - await expectLater( - newDocument.get(), - completion( - isA>() - .having((e) => e.data(), 'data', 42), - ), - ); - - await expectLater( - fooSnapshot, - emits( - isA().having((e) => e.docs, 'docs', [ - isA() - .having((e) => e.data(), 'data', {'value': 42}), - ]), - ), - ); - await expectLater( - fooConverterSnapshot, - emits( - isA>().having((e) => e.docs, 'docs', [ - isA>() - .having((e) => e.data(), 'data', 42), - ]), - ), - ); - - await foo.add({'value': 21}); - - await expectLater( - fooSnapshot, - emits( - isA().having( - (e) => e.docs, - 'docs', - unorderedEquals([ - isA>>() - .having((e) => e.data(), 'data', {'value': 42}), - isA>>() - .having((e) => e.data(), 'data', {'value': 21}), - ]), + await foo.add({'value': 21}); + + await expectLater( + fooSnapshot, + emits( + isA().having( + (e) => e.docs, + 'docs', + unorderedEquals([ + isA>>().having( + (e) => e.data(), + 'data', + {'value': 42}, ), - ), - ); - - await expectLater( - fooConverterSnapshot, - emits( - isA>().having( - (e) => e.docs, - 'docs', - unorderedEquals([ - isA>() - .having((e) => e.data(), 'data', 42), - isA>() - .having((e) => e.data(), 'data', 21), - ]), + isA>>().having( + (e) => e.data(), + 'data', + {'value': 21}, ), - ), - ); - }, - timeout: const Timeout.factor(3), + ]), + ), + ), ); - test( - 'returning null from `fromFirestore` should not throw a null check error', - () async { - final foo = await initializeTest('foo'); - await foo.add({'value': 42}); - final fooConverter = foo.withConverter( - fromFirestore: (_, __) => null, - toFirestore: (_, __) => {}, // unused - ); - - final fooConverterSnapshot = fooConverter.snapshots(); - - await expectLater( - fooConverterSnapshot, - emits( - // ignore: prefer_void_to_null - isA>().having((e) => e.docs, 'docs', [ - // ignore: prefer_void_to_null - isA>() - .having((e) => e.data(), 'data', null), - ]), - ), - ); - }, + await expectLater( + fooConverterSnapshot, + emits( + isA>().having( + (e) => e.docs, + 'docs', + unorderedEquals([ + isA>().having( + (e) => e.data(), + 'data', + 42, + ), + isA>().having( + (e) => e.data(), + 'data', + 21, + ), + ]), + ), + ), ); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + }, timeout: const Timeout.factor(3)); + + test( + 'returning null from `fromFirestore` should not throw a null check error', + () async { + final foo = await initializeTest('foo'); + await foo.add({'value': 42}); + final fooConverter = foo.withConverter( + fromFirestore: (_, __) => null, + toFirestore: (_, __) => {}, // unused + ); + + final fooConverterSnapshot = fooConverter.snapshots(); + + await expectLater( + fooConverterSnapshot, + emits( + // ignore: prefer_void_to_null + isA>().having((e) => e.docs, 'docs', [ + // ignore: prefer_void_to_null + isA>().having( + (e) => e.data(), + 'data', + null, + ), + ]), + ), + ); + }, + ); + }, skip: defaultTargetPlatform == TargetPlatform.windows); }); } diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/document_change_e2e.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/document_change_e2e.dart index 74e5f9f37ab5..337f97cf1885 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/document_change_e2e.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/document_change_e2e.dart @@ -19,13 +19,14 @@ void runDocumentChangeTests() { Future>> initializeTest( String id, ) async { - CollectionReference> collection = - firestore.collection('flutter-tests/$id/query-tests'); + CollectionReference> collection = firestore + .collection('flutter-tests/$id/query-tests'); QuerySnapshot> snapshot = await collection.get(); - await Future.forEach(snapshot.docs, - (DocumentSnapshot> documentSnapshot) { + await Future.forEach(snapshot.docs, ( + DocumentSnapshot> documentSnapshot, + ) { return documentSnapshot.reference.delete(); }); return collection; @@ -41,15 +42,15 @@ void runDocumentChangeTests() { await expectLater( doc1.snapshots(), emits( - isA>>() - .having((q) => q.exists, 'exists', false), + isA>>().having( + (q) => q.exists, + 'exists', + false, + ), ), ); - await doc1.set({ - 'key': null, - 'key2': 42, - }); + await doc1.set({'key': null, 'key2': 42}); await expectLater( doc1.snapshots(), @@ -57,16 +58,13 @@ void runDocumentChangeTests() { isA>>() .having((q) => q.exists, 'exists', true) .having((q) => q.data(), 'data()', { - 'key': null, - 'key2': 42, - }), + 'key': null, + 'key2': 42, + }), ), ); - await doc1.set({ - 'key': null, - 'key2': null, - }); + await doc1.set({'key': null, 'key2': null}); await expectLater( doc1.snapshots(), @@ -74,9 +72,9 @@ void runDocumentChangeTests() { isA>>() .having((q) => q.exists, 'exists', true) .having((q) => q.data(), 'data()', { - 'key': null, - 'key2': null, - }), + 'key': null, + 'key2': null, + }), ), ); }, @@ -97,8 +95,9 @@ void runDocumentChangeTests() { final snapshots = >>[]; final receivedAll = Completer(); - StreamSubscription subscription = - collection.snapshots().listen((snapshot) { + StreamSubscription subscription = collection.snapshots().listen(( + snapshot, + ) { snapshots.add(snapshot); if (snapshots.length >= 2 && !receivedAll.isCompleted) { receivedAll.complete(); @@ -132,65 +131,63 @@ void runDocumentChangeTests() { expect(removeChange.type, equals(DocumentChangeType.removed)); expect(removeChange.doc.data()!['name'], equals('doc1')); }, - skip: defaultTargetPlatform == TargetPlatform.windows || + skip: + defaultTargetPlatform == TargetPlatform.windows || defaultTargetPlatform == TargetPlatform.android, ); - test( - 'returns the correct metadata when modifying', - () async { - CollectionReference> collection = - await initializeTest('add-modify-document'); - DocumentReference> doc1 = collection.doc('doc1'); - DocumentReference> doc2 = collection.doc('doc2'); - DocumentReference> doc3 = collection.doc('doc3'); - - await doc1.set({'value': 1}); - await doc2.set({'value': 2}); - await doc3.set({'value': 3}); - - final snapshots = >>[]; - final receivedAll = Completer(); - - StreamSubscription subscription = - collection.orderBy('value').snapshots().listen((snapshot) { - snapshots.add(snapshot); - if (snapshots.length >= 2 && !receivedAll.isCompleted) { - receivedAll.complete(); - } - }); - - // Wait for the initial snapshot before modifying - await Future.delayed(const Duration(milliseconds: 500)); - await doc1.update({'value': 4}); - - await receivedAll.future.timeout(const Duration(seconds: 30)); - await subscription.cancel(); - - // Verify first snapshot (all 3 docs added) - expect(snapshots[0].docs.length, equals(3)); - expect(snapshots[0].docChanges.length, equals(3)); - snapshots[0] - .docChanges - .asMap() - .forEach((int index, DocumentChange> change) { - expect(change.oldIndex, equals(-1)); - expect(change.newIndex, equals(index)); - expect(change.type, equals(DocumentChangeType.added)); - expect(change.doc.data()!['value'], equals(index + 1)); - }); + test('returns the correct metadata when modifying', () async { + CollectionReference> collection = + await initializeTest('add-modify-document'); + DocumentReference> doc1 = collection.doc('doc1'); + DocumentReference> doc2 = collection.doc('doc2'); + DocumentReference> doc3 = collection.doc('doc3'); + + await doc1.set({'value': 1}); + await doc2.set({'value': 2}); + await doc3.set({'value': 3}); + + final snapshots = >>[]; + final receivedAll = Completer(); + + StreamSubscription subscription = collection + .orderBy('value') + .snapshots() + .listen((snapshot) { + snapshots.add(snapshot); + if (snapshots.length >= 2 && !receivedAll.isCompleted) { + receivedAll.complete(); + } + }); + + // Wait for the initial snapshot before modifying + await Future.delayed(const Duration(milliseconds: 500)); + await doc1.update({'value': 4}); + + await receivedAll.future.timeout(const Duration(seconds: 30)); + await subscription.cancel(); + + // Verify first snapshot (all 3 docs added) + expect(snapshots[0].docs.length, equals(3)); + expect(snapshots[0].docChanges.length, equals(3)); + snapshots[0].docChanges.asMap().forEach(( + int index, + DocumentChange> change, + ) { + expect(change.oldIndex, equals(-1)); + expect(change.newIndex, equals(index)); + expect(change.type, equals(DocumentChangeType.added)); + expect(change.doc.data()!['value'], equals(index + 1)); + }); - // Verify second snapshot (doc1 modified, moved to end) - expect(snapshots[1].docs.length, equals(3)); - expect(snapshots[1].docChanges.length, equals(1)); - DocumentChange> change = - snapshots[1].docChanges[0]; - expect(change.oldIndex, equals(0)); - expect(change.newIndex, equals(2)); - expect(change.type, equals(DocumentChangeType.modified)); - expect(change.doc.id, equals('doc1')); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + // Verify second snapshot (doc1 modified, moved to end) + expect(snapshots[1].docs.length, equals(3)); + expect(snapshots[1].docChanges.length, equals(1)); + DocumentChange> change = snapshots[1].docChanges[0]; + expect(change.oldIndex, equals(0)); + expect(change.newIndex, equals(2)); + expect(change.type, equals(DocumentChangeType.modified)); + expect(change.doc.id, equals('doc1')); + }, skip: defaultTargetPlatform == TargetPlatform.windows); }); } diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/document_reference_e2e.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/document_reference_e2e.dart index 0b218013ef11..1526990ac4b2 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/document_reference_e2e.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/document_reference_e2e.dart @@ -24,219 +24,222 @@ void runDocumentReferenceTests() { return firestore.doc(prefixedPath); } - group( - 'DocumentReference.snapshots()', - () { - test('returns a [Stream]', () async { - DocumentReference> document = - await initializeTest('document-snapshot'); - Stream>> stream = - document.snapshots(); - expect(stream, isA>>>()); - }); + group('DocumentReference.snapshots()', () { + test('returns a [Stream]', () async { + DocumentReference> document = await initializeTest( + 'document-snapshot', + ); + Stream>> stream = document + .snapshots(); + expect(stream, isA>>>()); + }); - test('can be reused', () async { - final foo = await initializeTest('foo'); + test('can be reused', () async { + final foo = await initializeTest('foo'); - final snapshot = foo.snapshots(); - final snapshot2 = foo.snapshots(); + final snapshot = foo.snapshots(); + final snapshot2 = foo.snapshots(); - expect( - await snapshot.first, - isA>>() - .having((e) => e.exists, 'exists', false), - ); - expect( - await snapshot2.first, - isA>>() - .having((e) => e.exists, 'exists', false), - ); + expect( + await snapshot.first, + isA>>().having( + (e) => e.exists, + 'exists', + false, + ), + ); + expect( + await snapshot2.first, + isA>>().having( + (e) => e.exists, + 'exists', + false, + ), + ); - await foo.set({'value': 42}); + await foo.set({'value': 42}); - expect( - await snapshot.first, - isA>>() - .having((e) => e.data(), 'data', {'value': 42}), - ); - expect( - await snapshot2.first, - isA>>() - .having((e) => e.data(), 'data', {'value': 42}), - ); + expect( + await snapshot.first, + isA>>().having( + (e) => e.data(), + 'data', + {'value': 42}, + ), + ); + expect( + await snapshot2.first, + isA>>().having( + (e) => e.data(), + 'data', + {'value': 42}, + ), + ); + }); + + test('listens to a single response', () async { + DocumentReference> document = await initializeTest( + 'document-snapshot', + ); + Stream>> stream = document + .snapshots(); + StreamSubscription>>? + subscription; + + subscription = stream.listen( + expectAsync1((DocumentSnapshot> snapshot) { + expect(snapshot.exists, isFalse); + }, reason: 'Stream should only have been called once.'), + ); + + addTearDown(() async { + await subscription?.cancel(); }); + }); - test('listens to a single response', () async { + test( + 'listens to a single response from cache', + () async { DocumentReference> document = await initializeTest('document-snapshot'); - Stream>> stream = - document.snapshots(); + Stream>> stream = document + .snapshots(source: ListenSource.cache); StreamSubscription>>? - subscription; + subscription; subscription = stream.listen( - expectAsync1( - (DocumentSnapshot> snapshot) { - expect(snapshot.exists, isFalse); - }, - reason: 'Stream should only have been called once.', - ), + expectAsync1((DocumentSnapshot> snapshot) { + expect(snapshot.exists, isFalse); + }, reason: 'Stream should only have been called once.'), ); addTearDown(() async { await subscription?.cancel(); }); - }); + }, + // Listening from cache is not supported on Windows (see + // DocumentReference.snapshots in cloud_firestore). + skip: defaultTargetPlatform == TargetPlatform.windows, + ); - test( - 'listens to a single response from cache', - () async { - DocumentReference> document = - await initializeTest('document-snapshot'); - Stream>> stream = - document.snapshots(source: ListenSource.cache); - StreamSubscription>>? - subscription; - - subscription = stream.listen( - expectAsync1( - (DocumentSnapshot> snapshot) { - expect(snapshot.exists, isFalse); - }, - reason: 'Stream should only have been called once.', - ), - ); + test( + 'listens to a document from cache', + () async { + DocumentReference> document = + await initializeTest('document-snapshot-cache'); + await document.set({'foo': 'bar'}); + Stream>> stream = document + .snapshots(source: ListenSource.cache); + StreamSubscription>>? + subscription; - addTearDown(() async { - await subscription?.cancel(); - }); - }, - // Listening from cache is not supported on Windows (see - // DocumentReference.snapshots in cloud_firestore). - skip: defaultTargetPlatform == TargetPlatform.windows, - ); - - test( - 'listens to a document from cache', - () async { - DocumentReference> document = - await initializeTest('document-snapshot-cache'); - await document.set({'foo': 'bar'}); - Stream>> stream = - document.snapshots(source: ListenSource.cache); - StreamSubscription>>? - subscription; - - subscription = stream.listen( - expectAsync1( - (DocumentSnapshot> snapshot) { - expect(snapshot.exists, isTrue); - expect(snapshot.data(), equals({'foo': 'bar'})); - }, - reason: 'Stream should only have been called once.', - ), - ); + subscription = stream.listen( + expectAsync1((DocumentSnapshot> snapshot) { + expect(snapshot.exists, isTrue); + expect(snapshot.data(), equals({'foo': 'bar'})); + }, reason: 'Stream should only have been called once.'), + ); - addTearDown(() async { - await subscription?.cancel(); - }); - }, - // Listening from cache is not supported on Windows. - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + addTearDown(() async { + await subscription?.cancel(); + }); + }, + // Listening from cache is not supported on Windows. + skip: defaultTargetPlatform == TargetPlatform.windows, + ); - test('listens to multiple documents', () async { - DocumentReference> doc1 = - await initializeTest('document-snapshot-1'); - DocumentReference> doc2 = - await initializeTest('document-snapshot-2'); + test('listens to multiple documents', () async { + DocumentReference> doc1 = await initializeTest( + 'document-snapshot-1', + ); + DocumentReference> doc2 = await initializeTest( + 'document-snapshot-2', + ); - await doc1.set({'test': 'value1'}); - await doc2.set({'test': 'value2'}); + await doc1.set({'test': 'value1'}); + await doc2.set({'test': 'value2'}); - final value1 = doc1.snapshots().first.then((s) => s.data()!['test']); - final value2 = doc2.snapshots().first.then((s) => s.data()!['test']); + final value1 = doc1.snapshots().first.then((s) => s.data()!['test']); + final value2 = doc2.snapshots().first.then((s) => s.data()!['test']); - await expectLater(value1, completion('value1')); - await expectLater(value2, completion('value2')); - }); + await expectLater(value1, completion('value1')); + await expectLater(value2, completion('value2')); + }); - test('listens to a multiple changes response', () async { - DocumentReference> document = - await initializeTest('document-snapshot-multiple'); - Stream>> stream = - document.snapshots(); - int call = 0; - - StreamSubscription subscription = stream.listen( - expectAsync1( - (DocumentSnapshot> snapshot) { - call++; - if (call == 1) { - expect(snapshot.exists, isFalse); - } else if (call == 2) { - expect(snapshot.exists, isTrue); - expect(snapshot.data()!['bar'], equals('baz')); - } else if (call == 3) { - expect(snapshot.exists, isFalse); - } else if (call == 4) { - expect(snapshot.exists, isTrue); - expect(snapshot.data()!['foo'], equals('bar')); - } else if (call == 5) { - expect(snapshot.exists, isTrue); - expect(snapshot.data()!['foo'], equals('baz')); - } else { - fail('Should not have been called'); - } - }, - count: 5, - reason: 'Stream should only have been called five times.', - ), - ); + test('listens to a multiple changes response', () async { + DocumentReference> document = await initializeTest( + 'document-snapshot-multiple', + ); + Stream>> stream = document + .snapshots(); + int call = 0; + + StreamSubscription subscription = stream.listen( + expectAsync1( + (DocumentSnapshot> snapshot) { + call++; + if (call == 1) { + expect(snapshot.exists, isFalse); + } else if (call == 2) { + expect(snapshot.exists, isTrue); + expect(snapshot.data()!['bar'], equals('baz')); + } else if (call == 3) { + expect(snapshot.exists, isFalse); + } else if (call == 4) { + expect(snapshot.exists, isTrue); + expect(snapshot.data()!['foo'], equals('bar')); + } else if (call == 5) { + expect(snapshot.exists, isTrue); + expect(snapshot.data()!['foo'], equals('baz')); + } else { + fail('Should not have been called'); + } + }, + count: 5, + reason: 'Stream should only have been called five times.', + ), + ); - await Future.delayed( - const Duration(seconds: 1), - ); // allow stream to return a noop-doc - await document.set({'bar': 'baz'}); - await document.delete(); - await document.set({'foo': 'bar'}); - await document.update({'foo': 'baz'}); + await Future.delayed( + const Duration(seconds: 1), + ); // allow stream to return a noop-doc + await document.set({'bar': 'baz'}); + await document.delete(); + await document.set({'foo': 'bar'}); + await document.update({'foo': 'baz'}); - await subscription.cancel(); - await Future.delayed( - const Duration(seconds: 1), - ); - }); + await subscription.cancel(); + await Future.delayed(const Duration(seconds: 1)); + }); - test('listeners throws a [FirebaseException]', () async { - DocumentReference> document = - firestore.doc('not-allowed/document'); - Stream>> stream = - document.snapshots(); + test('listeners throws a [FirebaseException]', () async { + DocumentReference> document = firestore.doc( + 'not-allowed/document', + ); + Stream>> stream = document + .snapshots(); - try { - await stream.first; - } catch (error) { - expect(error, isA()); - expect( - (error as FirebaseException).code, - equals('permission-denied'), - ); - return; - } + try { + await stream.first; + } catch (error) { + expect(error, isA()); + expect( + (error as FirebaseException).code, + equals('permission-denied'), + ); + return; + } - fail('Should have thrown a [FirebaseException]'); - }); - }, - ); + fail('Should have thrown a [FirebaseException]'); + }); + }); group('DocumentReference.delete()', () { test('delete() deletes a document', () async { - DocumentReference> document = - await initializeTest('document-delete'); - await document.set({ - 'foo': 'bar', - }); + DocumentReference> document = await initializeTest( + 'document-delete', + ); + await document.set({'foo': 'bar'}); DocumentSnapshot> snapshot = await document.get(); expect(snapshot.exists, isTrue); await document.delete(); @@ -247,8 +250,9 @@ void runDocumentReferenceTests() { test( 'throws a [FirebaseException] on error', () async { - DocumentReference> document = - firestore.doc('not-allowed/document'); + DocumentReference> document = firestore.doc( + 'not-allowed/document', + ); try { await document.delete(); @@ -278,79 +282,75 @@ void runDocumentReferenceTests() { expect(snapshot.get('blob'), blob); }); - test( - 'preserves native error messages when offline', - () async { - final document = - await initializeTest('document-get-server-while-offline'); - await firestore.disableNetwork(); - addTearDown(firestore.enableNetwork); - - await expectLater( - document.get(const GetOptions(source: Source.server)), - throwsA( - isA() - .having((error) => error.code, 'code', 'unavailable') - .having( - (error) => error.message, - 'message', - contains('offline'), - ), - ), - ); - }, - skip: kIsWeb, - ); + test('preserves native error messages when offline', () async { + final document = await initializeTest( + 'document-get-server-while-offline', + ); + await firestore.disableNetwork(); + addTearDown(firestore.enableNetwork); + + await expectLater( + document.get(const GetOptions(source: Source.server)), + throwsA( + isA() + .having((error) => error.code, 'code', 'unavailable') + .having( + (error) => error.message, + 'message', + contains('offline'), + ), + ), + ); + }, skip: kIsWeb); test('gets a document from server', () async { - DocumentReference> document = - await initializeTest('document-get-server'); + DocumentReference> document = await initializeTest( + 'document-get-server', + ); await document.set({'foo': 'bar'}); - DocumentSnapshot> snapshot = - await document.get(const GetOptions(source: Source.server)); + DocumentSnapshot> snapshot = await document.get( + const GetOptions(source: Source.server), + ); expect(snapshot.data(), {'foo': 'bar'}); expect(snapshot.metadata.isFromCache, isFalse); }); - test( - 'gets a document from cache', - () async { - DocumentReference> document = - await initializeTest('document-get-cache'); - await document.set({'foo': 'bar'}); - DocumentSnapshot> snapshot = - await document.get(const GetOptions(source: Source.cache)); - expect(snapshot.data(), equals({'foo': 'bar'})); - expect(snapshot.metadata.isFromCache, isTrue); - }, - skip: kIsWeb, - ); + test('gets a document from cache', () async { + DocumentReference> document = await initializeTest( + 'document-get-cache', + ); + await document.set({'foo': 'bar'}); + DocumentSnapshot> snapshot = await document.get( + const GetOptions(source: Source.cache), + ); + expect(snapshot.data(), equals({'foo': 'bar'})); + expect(snapshot.metadata.isFromCache, isTrue); + }, skip: kIsWeb); - test( - 'throws a [FirebaseException] on error', - () async { - DocumentReference> document = - firestore.doc('not-allowed/document'); + test('throws a [FirebaseException] on error', () async { + DocumentReference> document = firestore.doc( + 'not-allowed/document', + ); - try { - await document.get(); - } catch (error) { - expect(error, isA()); - expect( - (error as FirebaseException).code, - equals('permission-denied'), - ); - return; - } - fail('Should have thrown a [FirebaseException]'); - }, - ); + try { + await document.get(); + } catch (error) { + expect(error, isA()); + expect( + (error as FirebaseException).code, + equals('permission-denied'), + ); + return; + } + fail('Should have thrown a [FirebaseException]'); + }); }); group('DocumentReference.set()', () { test('sets data', () async { - DocumentReference> document = - await initializeTest('document-set'); + DocumentReference> document = await initializeTest( + 'document-set', + ); await document.set({'foo': 'bar'}); DocumentSnapshot> snapshot = await document.get(); expect(snapshot.data(), equals({'foo': 'bar'})); @@ -360,77 +360,75 @@ void runDocumentReferenceTests() { }); test('set() merges data', () async { - DocumentReference> document = - await initializeTest('document-set-merge'); + DocumentReference> document = await initializeTest( + 'document-set-merge', + ); await document.set({'foo': 'bar'}); DocumentSnapshot> snapshot = await document.get(); expect(snapshot.data(), equals({'foo': 'bar'})); - await document - .set({'foo': 'ben', 'bar': 'baz'}, SetOptions(merge: true)); + await document.set({ + 'foo': 'ben', + 'bar': 'baz', + }, SetOptions(merge: true)); DocumentSnapshot> snapshot2 = await document.get(); expect(snapshot2.data(), equals({'foo': 'ben', 'bar': 'baz'})); }); - test( - 'set() merges fields', - () async { - DocumentReference> document = - await initializeTest('document-set-merge-fields'); - Map initialData = { - 'foo': 'bar', - 'bar': 123, - 'baz': '456', - }; - Map dataToSet = { - 'foo': 'should-not-merge', - 'bar': 456, - 'baz': 'foo', - }; - await document.set(initialData); - DocumentSnapshot> snapshot = - await document.get(); - expect(snapshot.data(), equals(initialData)); - await document.set( - dataToSet, - SetOptions( - mergeFields: [ - 'bar', - FieldPath(const ['baz']), - ], - ), - ); - DocumentSnapshot> snapshot2 = - await document.get(); - expect( - snapshot2.data(), - equals({'foo': 'bar', 'bar': 456, 'baz': 'foo'}), - ); - }, - ); + test('set() merges fields', () async { + DocumentReference> document = await initializeTest( + 'document-set-merge-fields', + ); + Map initialData = { + 'foo': 'bar', + 'bar': 123, + 'baz': '456', + }; + Map dataToSet = { + 'foo': 'should-not-merge', + 'bar': 456, + 'baz': 'foo', + }; + await document.set(initialData); + DocumentSnapshot> snapshot = await document.get(); + expect(snapshot.data(), equals(initialData)); + await document.set( + dataToSet, + SetOptions( + mergeFields: [ + 'bar', + FieldPath(const ['baz']), + ], + ), + ); + DocumentSnapshot> snapshot2 = await document.get(); + expect( + snapshot2.data(), + equals({'foo': 'bar', 'bar': 456, 'baz': 'foo'}), + ); + }); - test( - 'throws a [FirebaseException] on error', - () async { - DocumentReference> document = - firestore.doc('not-allowed/document'); + test('throws a [FirebaseException] on error', () async { + DocumentReference> document = firestore.doc( + 'not-allowed/document', + ); - try { - await document.set({'foo': 'bar'}); - } catch (error) { - expect(error, isA()); - expect( - (error as FirebaseException).code, - equals('permission-denied'), - ); - return; - } - fail('Should have thrown a [FirebaseException]'); - }, - ); + try { + await document.set({'foo': 'bar'}); + } catch (error) { + expect(error, isA()); + expect( + (error as FirebaseException).code, + equals('permission-denied'), + ); + return; + } + fail('Should have thrown a [FirebaseException]'); + }); test('set and return all possible datatypes', () async { - DocumentReference> document = - await initializeTest('document-types'); + DocumentReference> document = await initializeTest( + 'document-types', + ); await document.set({ 'string': 'foo bar', @@ -506,10 +504,12 @@ void runDocumentReferenceTests() { }); test('sets data with DocumentReference as map key', () async { - DocumentReference> document = - await initializeTest('document-set-ref-key'); - DocumentReference> refKey = - FirebaseFirestore.instance.doc('foo/bar'); + DocumentReference> document = await initializeTest( + 'document-set-ref-key', + ); + DocumentReference> refKey = FirebaseFirestore + .instance + .doc('foo/bar'); await document.set({ 'myMap': {refKey: 42.0}, }); @@ -521,8 +521,9 @@ void runDocumentReferenceTests() { group('DocumentReference.update()', () { test('updates data', () async { - DocumentReference> document = - await initializeTest('document-update'); + DocumentReference> document = await initializeTest( + 'document-update', + ); await document.set({'foo': 'bar'}); DocumentSnapshot> snapshot = await document.get(); expect(snapshot.data(), equals({'foo': 'bar'})); @@ -532,8 +533,9 @@ void runDocumentReferenceTests() { }); test('updates nested data using dots', () async { - DocumentReference> document = - await initializeTest('document-update-field-path'); + DocumentReference> document = await initializeTest( + 'document-update-field-path', + ); await document.set({ 'foo': {'bar': 'baz'}, }); @@ -556,8 +558,9 @@ void runDocumentReferenceTests() { }); test('updates nested data using FieldPath', () async { - DocumentReference> document = - await initializeTest('document-update-field-path'); + DocumentReference> document = await initializeTest( + 'document-update-field-path', + ); await document.set({ 'foo': {'bar': 'baz'}, }); @@ -582,113 +585,109 @@ void runDocumentReferenceTests() { }); test('updates nested data containing a dot using FieldPath', () async { - DocumentReference> document = - await initializeTest('document-update-field-path'); + DocumentReference> document = await initializeTest( + 'document-update-field-path', + ); await document.set({'foo.bar': 'baz'}); DocumentSnapshot> snapshot = await document.get(); - expect( - snapshot.data(), - equals({'foo.bar': 'baz'}), - ); + expect(snapshot.data(), equals({'foo.bar': 'baz'})); await document.update({ FieldPath(const ['foo.bar']): 'toto', }); DocumentSnapshot> snapshot2 = await document.get(); - expect( - snapshot2.data(), - equals({'foo.bar': 'toto'}), - ); + expect(snapshot2.data(), equals({'foo.bar': 'toto'})); }); - test( - 'throws if document does not exist', - () async { - DocumentReference> document = - await initializeTest('document-update-not-exists'); - try { - await document.update({'foo': 'bar'}); - fail('Should have thrown'); - } catch (e) { - expect( - e, - isA() - .having((e) => e.code, 'code', 'not-found'), - ); - } - }, - ); + test('throws if document does not exist', () async { + DocumentReference> document = await initializeTest( + 'document-update-not-exists', + ); + try { + await document.update({'foo': 'bar'}); + fail('Should have thrown'); + } catch (e) { + expect( + e, + isA().having((e) => e.code, 'code', 'not-found'), + ); + } + }); }); group('withConverter', () { - test( - 'set/snapshot/get', - () async { - final foo = await initializeTest('foo'); - final fooConverter = foo.withConverter( - fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + test('set/snapshot/get', () async { + final foo = await initializeTest('foo'); + final fooConverter = foo.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - final fooSnapshot = foo.snapshots(); - final fooConverterSnapshot = fooConverter.snapshots(); + final fooSnapshot = foo.snapshots(); + final fooConverterSnapshot = fooConverter.snapshots(); - await expectLater( - fooSnapshot, - emits( - isA>>() - .having((e) => e.data(), 'data', null), + await expectLater( + fooSnapshot, + emits( + isA>>().having( + (e) => e.data(), + 'data', + null, ), - ); - await expectLater( - fooConverterSnapshot, - emits( - isA>() - .having((e) => e.data(), 'data', null), - ), - ); + ), + ); + await expectLater( + fooConverterSnapshot, + emits( + isA>().having((e) => e.data(), 'data', null), + ), + ); - await fooConverter.set(42); + await fooConverter.set(42); - await expectLater( - fooSnapshot, - emits( - isA>>() - .having((e) => e.data(), 'data', {'value': 42}), - ), - ); - await expectLater( - fooConverterSnapshot, - emits( - isA>().having((e) => e.data(), 'data', 42), + await expectLater( + fooSnapshot, + emits( + isA>>().having( + (e) => e.data(), + 'data', + {'value': 42}, ), - ); - await expectLater( - fooConverter.get(const GetOptions(source: Source.server)), - completion( - isA>().having((e) => e.data(), 'data', 42), - ), - ); + ), + ); + await expectLater( + fooConverterSnapshot, + emits( + isA>().having((e) => e.data(), 'data', 42), + ), + ); + await expectLater( + fooConverter.get(const GetOptions(source: Source.server)), + completion( + isA>().having((e) => e.data(), 'data', 42), + ), + ); - await foo.set({'value': 21}); + await foo.set({'value': 21}); - await expectLater( - fooSnapshot, - emits( - isA>>() - .having((e) => e.data(), 'data', {'value': 21}), + await expectLater( + fooSnapshot, + emits( + isA>>().having( + (e) => e.data(), + 'data', + {'value': 21}, ), - ); + ), + ); - await expectLater( - fooConverter.get(const GetOptions(source: Source.server)), - completion( - isA>().having((e) => e.data(), 'data', 21), - ), - ); - }, - timeout: const Timeout.factor(3), - ); + await expectLater( + fooConverter.get(const GetOptions(source: Source.server)), + completion( + isA>().having((e) => e.data(), 'data', 21), + ), + ); + }, timeout: const Timeout.factor(3)); }); group('DocumentReference as field value', () { @@ -706,8 +705,9 @@ void runDocumentReferenceTests() { }); test('can query by DocumentReference value', () async { - final collection = - firestore.collection('flutter-tests/doc-ref-query/items'); + final collection = firestore.collection( + 'flutter-tests/doc-ref-query/items', + ); final targetDoc = firestore.doc('flutter-tests/target-doc'); // Clean up @@ -718,8 +718,9 @@ void runDocumentReferenceTests() { await collection.add({'ref': targetDoc, 'name': 'test'}); - final querySnapshot = - await collection.where('ref', isEqualTo: targetDoc).get(); + final querySnapshot = await collection + .where('ref', isEqualTo: targetDoc) + .get(); expect(querySnapshot.docs, hasLength(1)); expect(querySnapshot.docs.first.data()['name'], 'test'); }); diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/field_value_e2e.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/field_value_e2e.dart index 71de05f5c456..12bb01b6b256 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/field_value_e2e.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/field_value_e2e.dart @@ -23,8 +23,9 @@ void runFieldValueTests() { group('FieldValue.increment()', () { test('increments a number if it exists', () async { - DocumentReference> doc = - await initializeTest('field-value-increment-exists'); + DocumentReference> doc = await initializeTest( + 'field-value-increment-exists', + ); await doc.set({'foo': 2}); await doc.update({'foo': FieldValue.increment(1)}); DocumentSnapshot> snapshot = await doc.get(); @@ -34,8 +35,9 @@ void runFieldValueTests() { }); test('increments a big number if it exists', () async { - DocumentReference> doc = - await initializeTest('field-value-increment-exists'); + DocumentReference> doc = await initializeTest( + 'field-value-increment-exists', + ); await doc.set({'foo': 0}); await doc.update({'foo': FieldValue.increment(2148000000)}); DocumentSnapshot> snapshot = await doc.get(); @@ -43,8 +45,9 @@ void runFieldValueTests() { }); test('decrements a number', () async { - DocumentReference> doc = - await initializeTest('field-value-decrement-exists'); + DocumentReference> doc = await initializeTest( + 'field-value-decrement-exists', + ); await doc.set({'foo': 2}); await doc.update({'foo': FieldValue.increment(-1)}); DocumentSnapshot> snapshot = await doc.get(); @@ -52,8 +55,9 @@ void runFieldValueTests() { }); test('sets an increment if it does not exist', () async { - DocumentReference> doc = - await initializeTest('field-value-increment-not-exists'); + DocumentReference> doc = await initializeTest( + 'field-value-increment-not-exists', + ); DocumentSnapshot> snapshot = await doc.get(); expect(snapshot.exists, isFalse); await doc.set({'foo': FieldValue.increment(1)}); @@ -64,16 +68,18 @@ void runFieldValueTests() { group('FieldValue.serverTimestamp()', () { test('sets a new server time value', () async { - DocumentReference> doc = - await initializeTest('field-value-server-timestamp-new'); + DocumentReference> doc = await initializeTest( + 'field-value-server-timestamp-new', + ); await doc.set({'foo': FieldValue.serverTimestamp()}); DocumentSnapshot> snapshot = await doc.get(); expect(snapshot.data()!['foo'], isA()); }); test('updates a server time value', () async { - DocumentReference> doc = - await initializeTest('field-value-server-timestamp-update'); + DocumentReference> doc = await initializeTest( + 'field-value-server-timestamp-update', + ); await doc.set({'foo': FieldValue.serverTimestamp()}); DocumentSnapshot> snapshot = await doc.get(); Timestamp serverTime1 = snapshot.data()!['foo']; @@ -93,8 +99,9 @@ void runFieldValueTests() { group('FieldValue.delete()', () { test('removes a value', () async { - DocumentReference> doc = - await initializeTest('field-value-delete'); + DocumentReference> doc = await initializeTest( + 'field-value-delete', + ); await doc.set({'foo': 'bar', 'bar': 'baz'}); await doc.update({'bar': FieldValue.delete()}); DocumentSnapshot> snapshot = await doc.get(); @@ -104,8 +111,9 @@ void runFieldValueTests() { group('FieldValue.arrayUnion()', () { test('updates an existing array', () async { - DocumentReference> doc = - await initializeTest('field-value-array-union-update-array'); + DocumentReference> doc = await initializeTest( + 'field-value-array-union-update-array', + ); await doc.set({ 'foo': [1, 2], }); @@ -117,8 +125,9 @@ void runFieldValueTests() { }); test('updates an array if current value is not an array', () async { - DocumentReference> doc = - await initializeTest('field-value-array-union-replace'); + DocumentReference> doc = await initializeTest( + 'field-value-array-union-replace', + ); await doc.set({'foo': 'bar'}); await doc.update({ 'foo': FieldValue.arrayUnion([3, 4]), @@ -128,8 +137,9 @@ void runFieldValueTests() { }); test('sets an array if current value is not an array', () async { - DocumentReference> doc = - await initializeTest('field-value-array-union-replace'); + DocumentReference> doc = await initializeTest( + 'field-value-array-union-replace', + ); await doc.set({'foo': 'bar'}); await doc.set({ 'foo': FieldValue.arrayUnion([3, 4]), @@ -141,8 +151,9 @@ void runFieldValueTests() { group('FieldValue.arrayRemove()', () { test('removes items in an array', () async { - DocumentReference> doc = - await initializeTest('field-value-array-remove-existing'); + DocumentReference> doc = await initializeTest( + 'field-value-array-remove-existing', + ); await doc.set({ 'foo': [1, 2, 3, 4], }); @@ -153,38 +164,43 @@ void runFieldValueTests() { expect(snapshot.data()!['foo'], equals([1, 2])); }); - test('removes & updates an array if existing item is not an array', - () async { - DocumentReference> doc = - await initializeTest('field-value-array-remove-replace'); - await doc.set({'foo': 'bar'}); - await doc.update({ - 'foo': FieldValue.arrayUnion([3, 4]), - }); - DocumentSnapshot> snapshot = await doc.get(); - expect(snapshot.data()!['foo'], equals([3, 4])); - }); - - test('removes & sets an array if existing item is not an array', - () async { - DocumentReference> doc = - await initializeTest('field-value-array-remove-replace'); - await doc.set({'foo': 'bar'}); - await doc.set({ - 'foo': FieldValue.arrayUnion([3, 4]), - }); - DocumentSnapshot> snapshot = await doc.get(); - expect(snapshot.data()!['foo'], equals([3, 4])); - }); + test( + 'removes & updates an array if existing item is not an array', + () async { + DocumentReference> doc = await initializeTest( + 'field-value-array-remove-replace', + ); + await doc.set({'foo': 'bar'}); + await doc.update({ + 'foo': FieldValue.arrayUnion([3, 4]), + }); + DocumentSnapshot> snapshot = await doc.get(); + expect(snapshot.data()!['foo'], equals([3, 4])); + }, + ); + + test( + 'removes & sets an array if existing item is not an array', + () async { + DocumentReference> doc = await initializeTest( + 'field-value-array-remove-replace', + ); + await doc.set({'foo': 'bar'}); + await doc.set({ + 'foo': FieldValue.arrayUnion([3, 4]), + }); + DocumentSnapshot> snapshot = await doc.get(); + expect(snapshot.data()!['foo'], equals([3, 4])); + }, + ); test('query should restore nested Timestamp', () async { - DocumentReference> doc = - await initializeTest('nested-timestamp'); + DocumentReference> doc = await initializeTest( + 'nested-timestamp', + ); await Future.wait([ doc.set({ - 'nested': { - 'timestamp': Timestamp.fromDate(DateTime(2020)), - }, + 'nested': {'timestamp': Timestamp.fromDate(DateTime(2020))}, 'timestamp': Timestamp.fromDate(DateTime(2020)), }), ]); @@ -196,14 +212,13 @@ void runFieldValueTests() { }); test('query should restore nested Timestamp in List', () async { - DocumentReference> doc = - await initializeTest('nested-timestamp'); + DocumentReference> doc = await initializeTest( + 'nested-timestamp', + ); await doc.set({ 'timestamp': Timestamp.fromDate(DateTime.now()), 'logs': [ - { - 'createdAt': Timestamp.fromDate(DateTime.now()), - }, + {'createdAt': Timestamp.fromDate(DateTime.now())}, ], }); diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/firebase_options.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/firebase_options.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/geo_point_e2e.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/geo_point_e2e.dart index b9ee4b27b0c6..4b7f00809671 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/geo_point_e2e.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/geo_point_e2e.dart @@ -22,8 +22,9 @@ void runGeoPointTests() { } test('sets a $GeoPoint & returns one', () async { - DocumentReference> doc = - await initializeTest('geo-point'); + DocumentReference> doc = await initializeTest( + 'geo-point', + ); await doc.set({'foo': const GeoPoint(10, -10)}); @@ -36,8 +37,9 @@ void runGeoPointTests() { }); test('updates a $GeoPoint & returns', () async { - DocumentReference> doc = - await initializeTest('geo-point-update'); + DocumentReference> doc = await initializeTest( + 'geo-point-update', + ); await doc.set({'foo': const GeoPoint(10, -10)}); diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/instance_e2e.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/instance_e2e.dart index 108cd2565cfe..a9c684656279 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/instance_e2e.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/instance_e2e.dart @@ -11,233 +11,204 @@ import 'package:flutter/foundation.dart'; import 'package:flutter_test/flutter_test.dart'; void runInstanceTests() { - group( - '$FirebaseFirestore.instance', - () { - late FirebaseFirestore firestore; + group('$FirebaseFirestore.instance', () { + late FirebaseFirestore firestore; - setUpAll(() async { - firestore = FirebaseFirestore.instance; - }); - - test( - 'snapshotsInSync()', - () async { - DocumentReference> documentReference = - firestore.doc('flutter-tests/insync'); + setUpAll(() async { + firestore = FirebaseFirestore.instance; + }); - // Ensure deleted - await documentReference.delete(); + test('snapshotsInSync()', () async { + DocumentReference> documentReference = firestore.doc( + 'flutter-tests/insync', + ); - StreamController controller = StreamController(); - StreamSubscription insync; - StreamSubscription snapshots; + // Ensure deleted + await documentReference.delete(); - int inSyncCount = 0; + StreamController controller = StreamController(); + StreamSubscription insync; + StreamSubscription snapshots; - insync = firestore.snapshotsInSync().listen((_) { - controller.add('insync=$inSyncCount'); - inSyncCount++; - }); + int inSyncCount = 0; - snapshots = documentReference.snapshots().listen((ds) { - controller.add('snapshot-exists=${ds.exists}'); - }); + insync = firestore.snapshotsInSync().listen((_) { + controller.add('insync=$inSyncCount'); + inSyncCount++; + }); - // Allow the snapshots to trigger... - await Future.delayed(const Duration(seconds: 1)); + snapshots = documentReference.snapshots().listen((ds) { + controller.add('snapshot-exists=${ds.exists}'); + }); - await documentReference.set({'foo': 'bar'}); + // Allow the snapshots to trigger... + await Future.delayed(const Duration(seconds: 1)); - await expectLater( - controller.stream, - emitsInOrder([ - 'insync=0', // No other snapshots - 'snapshot-exists=false', - 'insync=1', - 'snapshot-exists=true', - 'insync=2', - ]), - ); + await documentReference.set({'foo': 'bar'}); - await controller.close(); - await insync.cancel(); - await snapshots.cancel(); - }, - skip: kIsWeb, + await expectLater( + controller.stream, + emitsInOrder([ + 'insync=0', // No other snapshots + 'snapshot-exists=false', + 'insync=1', + 'snapshot-exists=true', + 'insync=2', + ]), ); - test( - 'enableNetwork()', - () async { - // Write some data while online - await firestore.enableNetwork(); - DocumentReference> documentReference = - firestore.doc('flutter-tests/enable-network'); - await documentReference.set({'foo': 'bar'}); - - // Disable the network - await firestore.disableNetwork(); - - StreamController controller = StreamController(); - - // Set some data while offline - // ignore: unawaited_futures - documentReference.set({'foo': 'baz'}).then((_) async { - // Only when back online will this trigger - controller.add(true); - }); - - // Go back online - await firestore.enableNetwork(); - - await expectLater(controller.stream, emits(true)); - await controller.close(); - }, - skip: kIsWeb, - ); + await controller.close(); + await insync.cancel(); + await snapshots.cancel(); + }, skip: kIsWeb); - test( - 'disableNetwork()', - () async { - // Write some data while online - await firestore.enableNetwork(); - DocumentReference> documentReference = - firestore.doc('flutter-tests/disable-network'); - await documentReference.set({'foo': 'bar'}); - - // Disable the network - await firestore.disableNetwork(); - - // Get data from cache - DocumentSnapshot> documentSnapshot = - await documentReference.get(); - expect(documentSnapshot.metadata.isFromCache, isTrue); - expect(documentSnapshot.data()!['foo'], equals('bar')); - - // Go back online once test complete - await firestore.enableNetwork(); - }, - skip: kIsWeb, + test('enableNetwork()', () async { + // Write some data while online + await firestore.enableNetwork(); + DocumentReference> documentReference = firestore.doc( + 'flutter-tests/enable-network', ); + await documentReference.set({'foo': 'bar'}); - test( - 'waitForPendingWrites()', - () async { - await firestore.waitForPendingWrites(); - }, - skip: kIsWeb, - ); + // Disable the network + await firestore.disableNetwork(); - test( - 'terminate() / clearPersistence()', - () async { - // Since the firestore instance has already been used, - // calling `clearPersistence` will throw a native error. - // We first check it does throw as expected, then terminate - // the instance, and then check whether clearing succeeds. - try { - await firestore.clearPersistence(); - fail('Should have thrown'); - } on FirebaseException catch (e) { - expect(e.code, equals('failed-precondition')); - } catch (e) { - fail('$e'); - } + StreamController controller = StreamController(); - await firestore.terminate(); - await firestore.clearPersistence(); - }, - skip: kIsWeb, - ); - - test( - 'terminate() then use Firestore again', - () async { - // Regression test for https://github.com/firebase/flutterfire/issues/17781 - // On Windows, terminate() did not remove the instance from the native - // cache, so subsequent usage would crash with "The client has already - // been terminated". - final instance = FirebaseFirestore.instanceFor( - app: Firebase.app(), - databaseId: 'flutterfire-2', - ); + // Set some data while offline + // ignore: unawaited_futures + documentReference.set({'foo': 'baz'}).then((_) async { + // Only when back online will this trigger + controller.add(true); + }); - instance.useFirestoreEmulator('localhost', 8080); + // Go back online + await firestore.enableNetwork(); - // Use Firestore so it is fully initialized - await instance.collection('flutterfire-2').doc('terminate-test').set( - {'foo': 'bar'}, - ); + await expectLater(controller.stream, emits(true)); + await controller.close(); + }, skip: kIsWeb); - await instance.terminate(); - await instance.clearPersistence(); - - // After terminate + clearPersistence, we should be able to use - // Firestore again without crashing. - await instance - .collection('flutterfire-2') - .doc('terminate-test') - .get(); - - // Clean up: terminate so the native instance cache is cleared - // for subsequent tests that may use the same databaseId. - await instance.terminate(); - }, - skip: kIsWeb, + test('disableNetwork()', () async { + // Write some data while online + await firestore.enableNetwork(); + DocumentReference> documentReference = firestore.doc( + 'flutter-tests/disable-network', + ); + await documentReference.set({'foo': 'bar'}); + + // Disable the network + await firestore.disableNetwork(); + + // Get data from cache + DocumentSnapshot> documentSnapshot = + await documentReference.get(); + expect(documentSnapshot.metadata.isFromCache, isTrue); + expect(documentSnapshot.data()!['foo'], equals('bar')); + + // Go back online once test complete + await firestore.enableNetwork(); + }, skip: kIsWeb); + + test('waitForPendingWrites()', () async { + await firestore.waitForPendingWrites(); + }, skip: kIsWeb); + + test('terminate() / clearPersistence()', () async { + // Since the firestore instance has already been used, + // calling `clearPersistence` will throw a native error. + // We first check it does throw as expected, then terminate + // the instance, and then check whether clearing succeeds. + try { + await firestore.clearPersistence(); + fail('Should have thrown'); + } on FirebaseException catch (e) { + expect(e.code, equals('failed-precondition')); + } catch (e) { + fail('$e'); + } + + await firestore.terminate(); + await firestore.clearPersistence(); + }, skip: kIsWeb); + + test('terminate() then use Firestore again', () async { + // Regression test for https://github.com/firebase/flutterfire/issues/17781 + // On Windows, terminate() did not remove the instance from the native + // cache, so subsequent usage would crash with "The client has already + // been terminated". + final instance = FirebaseFirestore.instanceFor( + app: Firebase.app(), + databaseId: 'flutterfire-2', ); - test( - 'setIndexConfigurationFromJSON()', - () async { - final json = jsonEncode({ - 'indexes': [ - { - 'collectionGroup': 'posts', - 'queryScope': 'COLLECTION', - 'fields': [ - {'fieldPath': 'author', 'arrayConfig': 'CONTAINS'}, - {'fieldPath': 'timestamp', 'order': 'DESCENDING'}, - ], - } - ], - 'fieldOverrides': [ - { - 'collectionGroup': 'posts', - 'fieldPath': 'myBigMapField', - 'indexes': [], - } - ], - }); + instance.useFirestoreEmulator('localhost', 8080); - // ignore: experimental_member_use - await firestore.setIndexConfigurationFromJSON(json); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + // Use Firestore so it is fully initialized + await instance.collection('flutterfire-2').doc('terminate-test').set({ + 'foo': 'bar', + }); - test('setLoggingEnabled should resolve without issue', () async { - await FirebaseFirestore.setLoggingEnabled(true); - await FirebaseFirestore.setLoggingEnabled(false); + await instance.terminate(); + await instance.clearPersistence(); + + // After terminate + clearPersistence, we should be able to use + // Firestore again without crashing. + await instance.collection('flutterfire-2').doc('terminate-test').get(); + + // Clean up: terminate so the native instance cache is cleared + // for subsequent tests that may use the same databaseId. + await instance.terminate(); + }, skip: kIsWeb); + + test('setIndexConfigurationFromJSON()', () async { + final json = jsonEncode({ + 'indexes': [ + { + 'collectionGroup': 'posts', + 'queryScope': 'COLLECTION', + 'fields': [ + {'fieldPath': 'author', 'arrayConfig': 'CONTAINS'}, + {'fieldPath': 'timestamp', 'order': 'DESCENDING'}, + ], + }, + ], + 'fieldOverrides': [ + { + 'collectionGroup': 'posts', + 'fieldPath': 'myBigMapField', + 'indexes': [], + }, + ], }); - test( - 'Settings() - `persistenceEnabled` & `cacheSizeBytes` with acceptable number', - () async { - FirebaseFirestore.instance.settings = - const Settings(persistenceEnabled: true, cacheSizeBytes: 10000000); + // ignore: experimental_member_use + await firestore.setIndexConfigurationFromJSON(json); + }, skip: defaultTargetPlatform == TargetPlatform.windows); + + test('setLoggingEnabled should resolve without issue', () async { + await FirebaseFirestore.setLoggingEnabled(true); + await FirebaseFirestore.setLoggingEnabled(false); + }); + + test( + 'Settings() - `persistenceEnabled` & `cacheSizeBytes` with acceptable number', + () async { + FirebaseFirestore.instance.settings = const Settings( + persistenceEnabled: true, + cacheSizeBytes: 10000000, + ); // Used to trigger settings await FirebaseFirestore.instance .collection('flutter-tests') .doc('new-doc') - .set( - {'some': 'data'}, - ); - }); + .set({'some': 'data'}); + }, + ); - test( - 'Settings() - `persistenceEnabled` & `cacheSizeBytes` with `Settings.CACHE_SIZE_UNLIMITED`', - () async { + test( + 'Settings() - `persistenceEnabled` & `cacheSizeBytes` with `Settings.CACHE_SIZE_UNLIMITED`', + () async { FirebaseFirestore.instance.settings = const Settings( persistenceEnabled: true, cacheSizeBytes: Settings.CACHE_SIZE_UNLIMITED, @@ -246,138 +217,137 @@ void runInstanceTests() { await FirebaseFirestore.instance .collection('flutter-tests') .doc('new-doc') - .set( - {'some': 'data'}, - ); - }); + .set({'some': 'data'}); + }, + ); - test('Settings() - `persistenceEnabled` & without `cacheSizeBytes`', - () async { - FirebaseFirestore.instance.settings = - const Settings(persistenceEnabled: true); + test( + 'Settings() - `persistenceEnabled` & without `cacheSizeBytes`', + () async { + FirebaseFirestore.instance.settings = const Settings( + persistenceEnabled: true, + ); // Used to trigger settings await FirebaseFirestore.instance .collection('flutter-tests') .doc('new-doc') - .set( - {'some': 'data'}, - ); - }); - test( - '`PersistenceCacheIndexManager` with default persistence settings for each platform', - () async { - if (defaultTargetPlatform == TargetPlatform.windows) { - try { - // Windows does not have `PersistenceCacheIndexManager` support - FirebaseFirestore.instance.persistentCacheIndexManager(); - } catch (e) { - expect(e, isInstanceOf()); - } - } else { - if (kIsWeb) { - // persistence is disabled by default on web - final firestore = FirebaseFirestore.instanceFor( - app: Firebase.app(), - // Use different firestore instance to test behavior - databaseId: 'default-web', - ); - PersistentCacheIndexManager? indexManager = - firestore.persistentCacheIndexManager(); - expect(indexManager, isNull); - } else { - final firestore = FirebaseFirestore.instanceFor( - app: Firebase.app(), - // Use different firestore instance to test behavior - databaseId: 'default-other-platform-test', - ); - // macOS, android, iOS have persistence enabled by default - PersistentCacheIndexManager? indexManager = - firestore.persistentCacheIndexManager(); - await indexManager!.enableIndexAutoCreation(); - await indexManager.disableIndexAutoCreation(); - await indexManager.deleteAllIndexes(); - } + .set({'some': 'data'}); + }, + ); + test( + '`PersistenceCacheIndexManager` with default persistence settings for each platform', + () async { + if (defaultTargetPlatform == TargetPlatform.windows) { + try { + // Windows does not have `PersistenceCacheIndexManager` support + FirebaseFirestore.instance.persistentCacheIndexManager(); + } catch (e) { + expect(e, isInstanceOf()); } - }, - ); - - test( - '`PersistenceCacheIndexManager` with persistence enabled for each platform', - () async { + } else { if (kIsWeb) { + // persistence is disabled by default on web final firestore = FirebaseFirestore.instanceFor( app: Firebase.app(), - databaseId: 'web-enabled', + // Use different firestore instance to test behavior + databaseId: 'default-web', ); - // persistence is disabled by default so we enable it - firestore.settings = const Settings(persistenceEnabled: true); - - PersistentCacheIndexManager? indexManager = - firestore.persistentCacheIndexManager(); - - await indexManager!.enableIndexAutoCreation(); - await indexManager.disableIndexAutoCreation(); - await indexManager.deleteAllIndexes(); - - final firestore2 = FirebaseFirestore.instanceFor( - app: Firebase.app(), - databaseId: 'web-disabled-2', - ); - - // Enable persistence using settings instead of deprecated enablePersistence() - firestore2.settings = const Settings(persistenceEnabled: true); - - PersistentCacheIndexManager? indexManager2 = - firestore2.persistentCacheIndexManager(); - - await indexManager2!.enableIndexAutoCreation(); - await indexManager2.disableIndexAutoCreation(); - await indexManager2.deleteAllIndexes(); + PersistentCacheIndexManager? indexManager = firestore + .persistentCacheIndexManager(); + expect(indexManager, isNull); } else { final firestore = FirebaseFirestore.instanceFor( app: Firebase.app(), - databaseId: 'other-platform-enabled', + // Use different firestore instance to test behavior + databaseId: 'default-other-platform-test', ); - firestore.settings = const Settings(persistenceEnabled: true); - PersistentCacheIndexManager? indexManager = - firestore.persistentCacheIndexManager(); + // macOS, android, iOS have persistence enabled by default + PersistentCacheIndexManager? indexManager = firestore + .persistentCacheIndexManager(); await indexManager!.enableIndexAutoCreation(); await indexManager.disableIndexAutoCreation(); await indexManager.deleteAllIndexes(); } - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + } + }, + ); + + test( + '`PersistenceCacheIndexManager` with persistence enabled for each platform', + () async { + if (kIsWeb) { + final firestore = FirebaseFirestore.instanceFor( + app: Firebase.app(), + databaseId: 'web-enabled', + ); + // persistence is disabled by default so we enable it + firestore.settings = const Settings(persistenceEnabled: true); - test( - '`PersistenceCacheIndexManager` with persistence disabled for each platform', - () async { - if (kIsWeb) { - final firestore = FirebaseFirestore.instanceFor( - app: Firebase.app(), - databaseId: 'web-disabled-1', - ); - // persistence is disabled by default so we enable it - firestore.settings = const Settings(persistenceEnabled: false); + PersistentCacheIndexManager? indexManager = firestore + .persistentCacheIndexManager(); - PersistentCacheIndexManager? indexManager = - firestore.persistentCacheIndexManager(); + await indexManager!.enableIndexAutoCreation(); + await indexManager.disableIndexAutoCreation(); + await indexManager.deleteAllIndexes(); - expect(indexManager, isNull); - } else { - final firestore = FirebaseFirestore.instanceFor( - app: Firebase.app(), - databaseId: 'other-platform-disabled', - ); - // macOS, android, iOS have persistence enabled by default so we disable it - firestore.settings = const Settings(persistenceEnabled: false); - PersistentCacheIndexManager? indexManager = - firestore.persistentCacheIndexManager(); - expect(indexManager, isNull); - } - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); - }, - ); + final firestore2 = FirebaseFirestore.instanceFor( + app: Firebase.app(), + databaseId: 'web-disabled-2', + ); + + // Enable persistence using settings instead of deprecated enablePersistence() + firestore2.settings = const Settings(persistenceEnabled: true); + + PersistentCacheIndexManager? indexManager2 = firestore2 + .persistentCacheIndexManager(); + + await indexManager2!.enableIndexAutoCreation(); + await indexManager2.disableIndexAutoCreation(); + await indexManager2.deleteAllIndexes(); + } else { + final firestore = FirebaseFirestore.instanceFor( + app: Firebase.app(), + databaseId: 'other-platform-enabled', + ); + firestore.settings = const Settings(persistenceEnabled: true); + PersistentCacheIndexManager? indexManager = firestore + .persistentCacheIndexManager(); + await indexManager!.enableIndexAutoCreation(); + await indexManager.disableIndexAutoCreation(); + await indexManager.deleteAllIndexes(); + } + }, + skip: defaultTargetPlatform == TargetPlatform.windows, + ); + + test( + '`PersistenceCacheIndexManager` with persistence disabled for each platform', + () async { + if (kIsWeb) { + final firestore = FirebaseFirestore.instanceFor( + app: Firebase.app(), + databaseId: 'web-disabled-1', + ); + // persistence is disabled by default so we enable it + firestore.settings = const Settings(persistenceEnabled: false); + + PersistentCacheIndexManager? indexManager = firestore + .persistentCacheIndexManager(); + + expect(indexManager, isNull); + } else { + final firestore = FirebaseFirestore.instanceFor( + app: Firebase.app(), + databaseId: 'other-platform-disabled', + ); + // macOS, android, iOS have persistence enabled by default so we disable it + firestore.settings = const Settings(persistenceEnabled: false); + PersistentCacheIndexManager? indexManager = firestore + .persistentCacheIndexManager(); + expect(indexManager, isNull); + } + }, + skip: defaultTargetPlatform == TargetPlatform.windows, + ); + }); } diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/load_bundle_e2e.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/load_bundle_e2e.dart index 9d1b4d1737d8..2cbb0dc68e04 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/load_bundle_e2e.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/load_bundle_e2e.dart @@ -103,115 +103,106 @@ void runLoadBundleTests() { skip: kIsWeb, ); - test( - 'loadBundle(): error handling for malformed bundle', - () async { - final Uint8List buffer = await _fetchFixture( - Uri.https( - 'api.rnfirebase.io', - '/firestore/e2e-tests/malformed-bundle', - ), - ); + test('loadBundle(): error handling for malformed bundle', () async { + final Uint8List buffer = await _fetchFixture( + Uri.https( + 'api.rnfirebase.io', + '/firestore/e2e-tests/malformed-bundle', + ), + ); - LoadBundleTask task = firestore.loadBundle(buffer); + LoadBundleTask task = firestore.loadBundle(buffer); - await expectLater( - task.stream.last, - throwsA( - isA() - .having((e) => e.code, 'code', 'load-bundle-error'), + await expectLater( + task.stream.last, + throwsA( + isA().having( + (e) => e.code, + 'code', + 'load-bundle-error', ), - ); - }, - ); + ), + ); + }); - test( - 'loadBundle(): pause and resume stream', - () async { - Uint8List buffer = await loadBundleSetup(3); - LoadBundleTask task = firestore.loadBundle(buffer); - // Illustrates the pause() & resume() function. - // A single stream will stop sending events once the listener is unsubscribed - - // Will listen & pause after first event received - await expectLater( - task.stream, - emits( - isA().having( - (ts) => ts.taskState, - 'taskState', - LoadBundleTaskState.running, - ), + test('loadBundle(): pause and resume stream', () async { + Uint8List buffer = await loadBundleSetup(3); + LoadBundleTask task = firestore.loadBundle(buffer); + // Illustrates the pause() & resume() function. + // A single stream will stop sending events once the listener is unsubscribed + + // Will listen & pause after first event received + await expectLater( + task.stream, + emits( + isA().having( + (ts) => ts.taskState, + 'taskState', + LoadBundleTaskState.running, ), - ); + ), + ); - await Future.delayed(const Duration(milliseconds: 1)); - - // Will resume & pause after second event received - await expectLater( - task.stream, - emits( - isA().having( - (ts) => ts.taskState, - 'taskState', - anyOf(LoadBundleTaskState.running, LoadBundleTaskState.success), - ), + await Future.delayed(const Duration(milliseconds: 1)); + + // Will resume & pause after second event received + await expectLater( + task.stream, + emits( + isA().having( + (ts) => ts.taskState, + 'taskState', + anyOf(LoadBundleTaskState.running, LoadBundleTaskState.success), ), - ); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + ), + ); + }, skip: defaultTargetPlatform == TargetPlatform.windows); }); group('FirebaseFirestore.namedQueryGet()', () { - test( - 'namedQueryGet() successful', - () async { - const int number = 4; - Uint8List buffer = await loadBundleSetup(number); - LoadBundleTask task = firestore.loadBundle(buffer); + test('namedQueryGet() successful', () async { + const int number = 4; + Uint8List buffer = await loadBundleSetup(number); + LoadBundleTask task = firestore.loadBundle(buffer); - // ensure the bundle has been completely cached - await task.stream.last; + // ensure the bundle has been completely cached + await task.stream.last; - // namedQuery 'named-bundle-test' which returns a QuerySnaphot of the same 3 documents - // with 'number' property - QuerySnapshot> snapshot = - await firestore.namedQueryGet( - 'named-bundle-test-$number', - options: const GetOptions(source: Source.cache), - ); + // namedQuery 'named-bundle-test' which returns a QuerySnaphot of the same 3 documents + // with 'number' property + QuerySnapshot> snapshot = await firestore + .namedQueryGet( + 'named-bundle-test-$number', + options: const GetOptions(source: Source.cache), + ); - expect( - snapshot.docs.map((document) => document['number']), - everyElement(anyOf(1, 2, 3)), - ); - }, - skip: kIsWeb, - ); + expect( + snapshot.docs.map((document) => document['number']), + everyElement(anyOf(1, 2, 3)), + ); + }, skip: kIsWeb); - test( - 'namedQueryGet() error', - () async { - Uint8List buffer = await loadBundleSetup(4); - LoadBundleTask task = firestore.loadBundle(buffer); + test('namedQueryGet() error', () async { + Uint8List buffer = await loadBundleSetup(4); + LoadBundleTask task = firestore.loadBundle(buffer); - // ensure the bundle has been completely cached - await task.stream.last; + // ensure the bundle has been completely cached + await task.stream.last; - await expectLater( - firestore.namedQueryGet( - 'wrong-name', - options: const GetOptions(source: Source.cache), - ), - throwsA( - isA() - .having((e) => e.code, 'code', 'non-existent-named-query'), + await expectLater( + firestore.namedQueryGet( + 'wrong-name', + options: const GetOptions(source: Source.cache), + ), + throwsA( + isA().having( + (e) => e.code, + 'code', + 'non-existent-named-query', ), - ); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + ), + ); + }, skip: defaultTargetPlatform == TargetPlatform.windows); }); group('FirebaeFirestore.namedQueryWithConverterGet()', () { @@ -225,13 +216,13 @@ void runLoadBundleTests() { // namedQuery 'named-bundle-test' which returns a QuerySnaphot of the same 3 documents // with 'number' property - QuerySnapshot snapshot = - await firestore.namedQueryWithConverterGet( - 'named-bundle-test-$number', - options: const GetOptions(source: Source.cache), - fromFirestore: ConverterPlaceholder.new, - toFirestore: (value, options) => value.toFirestore(), - ); + QuerySnapshot snapshot = await firestore + .namedQueryWithConverterGet( + 'named-bundle-test-$number', + options: const GetOptions(source: Source.cache), + fromFirestore: ConverterPlaceholder.new, + toFirestore: (value, options) => value.toFirestore(), + ); expect( snapshot.docs.map((document) => document['number']), @@ -239,30 +230,29 @@ void runLoadBundleTests() { ); }); - test( - 'namedQueryWithConverterGet() error', - () async { - Uint8List buffer = await loadBundleSetup(4); - LoadBundleTask task = firestore.loadBundle(buffer); + test('namedQueryWithConverterGet() error', () async { + Uint8List buffer = await loadBundleSetup(4); + LoadBundleTask task = firestore.loadBundle(buffer); - // ensure the bundle has been completely cached - await task.stream.last; + // ensure the bundle has been completely cached + await task.stream.last; - await expectLater( - firestore.namedQueryWithConverterGet( - 'wrong-name', - options: const GetOptions(source: Source.cache), - fromFirestore: ConverterPlaceholder.new, - toFirestore: (value, options) => value.toFirestore(), - ), - throwsA( - isA() - .having((e) => e.code, 'code', 'non-existent-named-query'), + await expectLater( + firestore.namedQueryWithConverterGet( + 'wrong-name', + options: const GetOptions(source: Source.cache), + fromFirestore: ConverterPlaceholder.new, + toFirestore: (value, options) => value.toFirestore(), + ), + throwsA( + isA().having( + (e) => e.code, + 'code', + 'non-existent-named-query', ), - ); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + ), + ); + }, skip: defaultTargetPlatform == TargetPlatform.windows); }); }); } 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 05d13abe3651..f9a0d6a7859a 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 @@ -23,12 +23,13 @@ void runQueryTests() { Future>> initializeTest( String id, ) async { - CollectionReference> collection = - firestore.collection('flutter-tests/$id/query-tests'); + CollectionReference> collection = firestore + .collection('flutter-tests/$id/query-tests'); QuerySnapshot> snapshot = await collection.get(); - await Future.forEach(snapshot.docs, - (QueryDocumentSnapshot> documentSnapshot) { + await Future.forEach(snapshot.docs, ( + QueryDocumentSnapshot> documentSnapshot, + ) { return documentSnapshot.reference.delete(); }); return collection; @@ -38,8 +39,9 @@ void runQueryTests() { // testing == override using e2e tests as it is dependent on the platform test('handles deeply compares query parameters', () async { final movies = firestore.collection('/movies'); - final starWarsComments = - firestore.collection('/movies/star-wars/comments'); + final starWarsComments = firestore.collection( + '/movies/star-wars/comments', + ); expect( movies.where('genre', arrayContains: ['Flutter']), @@ -62,20 +64,20 @@ void runQueryTests() { ); expect( - FirebaseFirestore.instanceFor(app: fooApp) - .collection('movies') - .limit(42), - FirebaseFirestore.instanceFor(app: fooApp) - .collection('movies') - .limit(42), + FirebaseFirestore.instanceFor( + app: fooApp, + ).collection('movies').limit(42), + FirebaseFirestore.instanceFor( + app: fooApp, + ).collection('movies').limit(42), ); expect( FirebaseFirestore.instance.collection('movies').limit(42), isNot( - FirebaseFirestore.instanceFor(app: fooApp) - .collection('movies') - .limit(42), + FirebaseFirestore.instanceFor( + app: fooApp, + ).collection('movies').limit(42), ), ); }); @@ -97,12 +99,13 @@ void runQueryTests() { */ group('collectionGroup()', () { test('returns a data via a sub-collection', () async { - CollectionReference> collection = - firestore.collection('flutter-tests/collection-group/group-test'); + CollectionReference> collection = firestore + .collection('flutter-tests/collection-group/group-test'); QuerySnapshot> snapshot = await collection.get(); - await Future.forEach(snapshot.docs, - (DocumentSnapshot documentSnapshot) { + await Future.forEach(snapshot.docs, ( + DocumentSnapshot documentSnapshot, + ) { return documentSnapshot.reference.delete(); }); @@ -119,25 +122,23 @@ void runQueryTests() { }); test( - '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', - ); - } - }); + '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'); + } + }, + ); }); /** @@ -154,8 +155,9 @@ void runQueryTests() { test('uses [GetOptions] cache', () async { CollectionReference> collection = await initializeTest('get'); - QuerySnapshot> qs = - await collection.get(const GetOptions(source: Source.cache)); + QuerySnapshot> qs = await collection.get( + const GetOptions(source: Source.cache), + ); expect(qs, isA>>()); expect(qs.metadata.isFromCache, isTrue); }); @@ -163,8 +165,9 @@ void runQueryTests() { test('uses [GetOptions] server', () async { CollectionReference> collection = await initializeTest('get'); - QuerySnapshot> qs = - await collection.get(const GetOptions(source: Source.server)); + QuerySnapshot> qs = await collection.get( + const GetOptions(source: Source.server), + ); expect(qs, isA>>()); expect(qs.metadata.isFromCache, isFalse); }); @@ -191,25 +194,22 @@ void runQueryTests() { expect(qs, isA>>()); }); - test( - 'throws a [FirebaseException]', - () async { - CollectionReference> collection = - firestore.collection('not-allowed'); + test('throws a [FirebaseException]', () async { + CollectionReference> collection = firestore + .collection('not-allowed'); - try { - await collection.get(); - } catch (error) { - expect(error, isA()); - expect( - (error as FirebaseException).code, - equals('permission-denied'), - ); - return; - } - fail('Should have thrown a [FirebaseException]'); - }, - ); + try { + await collection.get(); + } catch (error) { + expect(error, isA()); + expect( + (error as FirebaseException).code, + equals('permission-denied'), + ); + return; + } + fail('Should have thrown a [FirebaseException]'); + }); test( 'should respond with a FirebaseException, the query requires an index', @@ -225,10 +225,7 @@ void runQueryTests() { (error as FirebaseException).code, equals('failed-precondition'), ); - expect( - error.message, - 'The query requires an index', - ); + expect(error.message, 'The query requires an index'); } }, ); @@ -241,8 +238,8 @@ void runQueryTests() { test('returns a [Stream]', () async { CollectionReference> collection = await initializeTest('get'); - Stream>> stream = - collection.snapshots(); + Stream>> stream = collection + .snapshots(); expect(stream, isA>>>()); }); @@ -250,21 +247,18 @@ void runQueryTests() { CollectionReference> collection = await initializeTest('get-single'); await collection.add({'foo': 'bar'}); - Stream>> stream = - collection.snapshots(); + Stream>> stream = collection + .snapshots(); StreamSubscription>>? subscription; subscription = stream.listen( - expectAsync1( - (QuerySnapshot> snapshot) { - expect(snapshot.docs.length, equals(1)); - expect(snapshot.docs[0], isA()); - QueryDocumentSnapshot> documentSnapshot = - snapshot.docs[0]; - expect(documentSnapshot.data()['foo'], equals('bar')); - }, - reason: 'Stream should only have been called once.', - ), + expectAsync1((QuerySnapshot> snapshot) { + expect(snapshot.docs.length, equals(1)); + expect(snapshot.docs[0], isA()); + QueryDocumentSnapshot> documentSnapshot = + snapshot.docs[0]; + expect(documentSnapshot.data()['foo'], equals('bar')); + }, reason: 'Stream should only have been called once.'), ); addTearDown(() async { await subscription?.cancel(); @@ -277,21 +271,18 @@ void runQueryTests() { CollectionReference> collection = await initializeTest('get-single-cache'); await collection.add({'foo': 'bar'}); - Stream>> stream = - collection.snapshots(source: ListenSource.cache); + Stream>> stream = collection + .snapshots(source: ListenSource.cache); StreamSubscription>>? subscription; subscription = stream.listen( - expectAsync1( - (QuerySnapshot> snapshot) { - expect(snapshot.docs.length, equals(1)); - expect(snapshot.docs[0], isA()); - QueryDocumentSnapshot> documentSnapshot = - snapshot.docs[0]; - expect(documentSnapshot.data()['foo'], equals('bar')); - }, - reason: 'Stream should only have been called once.', - ), + expectAsync1((QuerySnapshot> snapshot) { + expect(snapshot.docs.length, equals(1)); + expect(snapshot.docs[0], isA()); + QueryDocumentSnapshot> documentSnapshot = + snapshot.docs[0]; + expect(documentSnapshot.data()['foo'], equals('bar')); + }, reason: 'Stream should only have been called once.'), ); addTearDown(() async { await subscription?.cancel(); @@ -311,14 +302,12 @@ void runQueryTests() { await collection1.add({'test': 'value1'}); await collection2.add({'test': 'value2'}); - final value1 = collection1 - .snapshots() - .first - .then((s) => s.docs.first.data()['test']); - final value2 = collection2 - .snapshots() - .first - .then((s) => s.docs.first.data()['test']); + final value1 = collection1.snapshots().first.then( + (s) => s.docs.first.data()['test'], + ); + final value2 = collection2.snapshots().first.then( + (s) => s.docs.first.data()['test'], + ); await expectLater(value1, completion('value1')); await expectLater(value2, completion('value2')); @@ -329,8 +318,8 @@ void runQueryTests() { await initializeTest('get-multiple'); await collection.add({'foo': 'bar'}); - Stream>> stream = - collection.snapshots(); + Stream>> stream = collection + .snapshots(); final initialSnapshot = Completer>>(); final doc1Set = Completer>>(); @@ -339,10 +328,12 @@ void runQueryTests() { final doc2Updated = Completer>>(); StreamSubscription subscription = stream.listen((snapshot) { - final doc1 = - snapshot.docs.where((doc) => doc.id == 'doc1').firstOrNull; - final doc2 = - snapshot.docs.where((doc) => doc.id == 'doc2').firstOrNull; + final doc1 = snapshot.docs + .where((doc) => doc.id == 'doc1') + .firstOrNull; + final doc2 = snapshot.docs + .where((doc) => doc.id == 'doc2') + .firstOrNull; if (!initialSnapshot.isCompleted && snapshot.docs.length == 1 && @@ -435,7 +426,7 @@ void runQueryTests() { var updateSnapshots = 0; final StreamSubscription>> - subscription = collection.snapshots().listen((snapshot) { + subscription = collection.snapshots().listen((snapshot) { if (!initialSnapshotReceived && snapshot.size == documentCount) { initialSnapshotReceived = true; initialSnapshot.complete(); @@ -460,17 +451,20 @@ void runQueryTests() { ); var updatesDone = false; - final updateFuture = Future(() async { - for (int index = 0; index < 3; index++) { - await collection.doc('doc-0').update({ - 'counter': index, - 'payload': payload, + final updateFuture = + Future(() async { + for (int index = 0; index < 3; index++) { + await collection.doc('doc-0').update({ + 'counter': index, + 'payload': payload, + }); + } + await receivedUpdates.future.timeout( + const Duration(seconds: 30), + ); + }).whenComplete(() { + updatesDone = true; }); - } - await receivedUpdates.future.timeout(const Duration(seconds: 30)); - }).whenComplete(() { - updatesDone = true; - }); final pumpDurations = []; while (!updatesDone) { @@ -491,30 +485,25 @@ void runQueryTests() { skip: kIsWeb || defaultTargetPlatform == TargetPlatform.windows, ); - test( - 'listeners throws a [FirebaseException] with Query', - () async { - CollectionReference> collection = - firestore.collection('not-allowed'); - Stream>> stream = - collection.snapshots(); + test('listeners throws a [FirebaseException] with Query', () async { + CollectionReference> collection = firestore + .collection('not-allowed'); + Stream>> stream = collection + .snapshots(); - try { - await stream.first; - } catch (error) { - expect(error, isA()); - expect( - (error as FirebaseException).code, - equals( - 'permission-denied', - ), - ); - return; - } + try { + await stream.first; + } catch (error) { + expect(error, isA()); + expect( + (error as FirebaseException).code, + equals('permission-denied'), + ); + return; + } - fail('Should have thrown a [FirebaseException]'); - }, - ); + fail('Should have thrown a [FirebaseException]'); + }); }); /** @@ -542,14 +531,17 @@ void runQueryTests() { QuerySnapshot> snapshot = await collection .orderBy('bar.value', descending: true) - .endAt([2]).get(); + .endAt([2]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc3')); expect(snapshot.docs[1].id, equals('doc2')); - QuerySnapshot> snapshot2 = - await collection.orderBy('foo').endAt([2]).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy('foo') + .endAt([2]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc1')); @@ -576,14 +568,17 @@ void runQueryTests() { QuerySnapshot> snapshot = await collection .orderBy('bar.value', descending: true) - .endAt({2}).get(); + .endAt({2}) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc3')); expect(snapshot.docs[1].id, equals('doc2')); - QuerySnapshot> snapshot2 = - await collection.orderBy('foo').endAt([2]).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy('foo') + .endAt([2]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc1')); @@ -610,14 +605,17 @@ void runQueryTests() { QuerySnapshot> snapshot = await collection .orderBy(FieldPath(const ['bar', 'value']), descending: true) - .endAt([2]).get(); + .endAt([2]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc3')); expect(snapshot.docs[1].id, equals('doc2')); - QuerySnapshot> snapshot2 = - await collection.orderBy(FieldPath(const ['foo'])).endAt([2]).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy(FieldPath(const ['foo'])) + .endAt([2]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc1')); @@ -671,8 +669,9 @@ void runQueryTests() { DocumentSnapshot endAtSnapshot = await collection.doc('doc3').get(); - QuerySnapshot> snapshot = - await collection.endAtDocument(endAtSnapshot).get(); + QuerySnapshot> snapshot = await collection + .endAtDocument(endAtSnapshot) + .get(); expect(snapshot.docs.length, equals(3)); expect(snapshot.docs[0].id, equals('doc1')); @@ -706,14 +705,17 @@ void runQueryTests() { QuerySnapshot> snapshot = await collection .orderBy('bar.value', descending: true) - .startAt([2]).get(); + .startAt([2]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); expect(snapshot.docs[1].id, equals('doc1')); - QuerySnapshot> snapshot2 = - await collection.orderBy('foo').startAt([2]).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy('foo') + .startAt([2]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc2')); @@ -740,14 +742,17 @@ void runQueryTests() { QuerySnapshot> snapshot = await collection .orderBy('bar.value', descending: true) - .startAt([2]).get(); + .startAt([2]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); expect(snapshot.docs[1].id, equals('doc1')); - QuerySnapshot> snapshot2 = - await collection.orderBy('foo').startAt({2}).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy('foo') + .startAt({2}) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc2')); @@ -774,7 +779,8 @@ void runQueryTests() { QuerySnapshot> snapshot = await collection .orderBy(FieldPath(const ['bar', 'value']), descending: true) - .startAt([2]).get(); + .startAt([2]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); @@ -782,7 +788,8 @@ void runQueryTests() { QuerySnapshot> snapshot2 = await collection .orderBy(FieldPath(const ['foo'])) - .startAt([2]).get(); + .startAt([2]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc2')); @@ -836,8 +843,9 @@ void runQueryTests() { DocumentSnapshot startAtSnapshot = await collection.doc('doc3').get(); - QuerySnapshot> snapshot = - await collection.startAtDocument(startAtSnapshot).get(); + QuerySnapshot> snapshot = await collection + .startAtDocument(startAtSnapshot) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc3')); @@ -870,14 +878,17 @@ void runQueryTests() { QuerySnapshot> snapshot = await collection .orderBy('bar.value', descending: true) - .endBefore([1]).get(); + .endBefore([1]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc3')); expect(snapshot.docs[1].id, equals('doc2')); - QuerySnapshot> snapshot2 = - await collection.orderBy('foo').endBefore([3]).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy('foo') + .endBefore([3]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc1')); @@ -904,14 +915,17 @@ void runQueryTests() { QuerySnapshot> snapshot = await collection .orderBy('bar.value', descending: true) - .endBefore({1}).get(); + .endBefore({1}) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc3')); expect(snapshot.docs[1].id, equals('doc2')); - QuerySnapshot> snapshot2 = - await collection.orderBy('foo').endBefore([3]).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy('foo') + .endBefore([3]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc1')); @@ -938,7 +952,8 @@ void runQueryTests() { QuerySnapshot> snapshot = await collection .orderBy(FieldPath(const ['bar', 'value']), descending: true) - .endBefore([1]).get(); + .endBefore([1]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc3')); @@ -946,7 +961,8 @@ void runQueryTests() { QuerySnapshot> snapshot2 = await collection .orderBy(FieldPath(const ['foo'])) - .endBefore([3]).get(); + .endBefore([3]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc1')); @@ -1000,8 +1016,9 @@ void runQueryTests() { DocumentSnapshot endAtSnapshot = await collection.doc('doc4').get(); - QuerySnapshot> snapshot = - await collection.endBeforeDocument(endAtSnapshot).get(); + QuerySnapshot> snapshot = await collection + .endBeforeDocument(endAtSnapshot) + .get(); expect(snapshot.docs.length, equals(3)); expect(snapshot.docs[0].id, equals('doc1')); @@ -1034,14 +1051,17 @@ void runQueryTests() { QuerySnapshot> snapshot = await collection .orderBy('bar.value', descending: true) - .startAfter([3]).get(); + .startAfter([3]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); expect(snapshot.docs[1].id, equals('doc1')); - QuerySnapshot> snapshot2 = - await collection.orderBy('foo').startAfter([1]).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy('foo') + .startAfter([1]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc2')); @@ -1068,7 +1088,8 @@ void runQueryTests() { QuerySnapshot> snapshot = await collection .orderBy(FieldPath(const ['bar', 'value']), descending: true) - .startAfter([3]).get(); + .startAfter([3]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); @@ -1076,41 +1097,45 @@ void runQueryTests() { QuerySnapshot> snapshot2 = await collection .orderBy(FieldPath(const ['foo'])) - .startAfter([1]).get(); + .startAfter([1]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc2')); expect(snapshot2.docs[1].id, equals('doc3')); }); - test('startAfterDocument() starts after a document field value', - () async { - CollectionReference> collection = - await initializeTest('startAfter-document-field-value'); - await Future.wait([ - collection.doc('doc1').set({ - 'bar': {'value': 3}, - }), - collection.doc('doc2').set({ - 'bar': {'value': 2}, - }), - collection.doc('doc3').set({ - 'bar': {'value': 1}, - }), - ]); + test( + 'startAfterDocument() starts after a document field value', + () async { + CollectionReference> collection = + await initializeTest('startAfter-document-field-value'); + await Future.wait([ + collection.doc('doc1').set({ + 'bar': {'value': 3}, + }), + collection.doc('doc2').set({ + 'bar': {'value': 2}, + }), + collection.doc('doc3').set({ + 'bar': {'value': 1}, + }), + ]); - DocumentSnapshot startAfterSnapshot = - await collection.doc('doc3').get(); + DocumentSnapshot startAfterSnapshot = await collection + .doc('doc3') + .get(); - QuerySnapshot> snapshot = await collection - .orderBy('bar.value') - .startAfterDocument(startAfterSnapshot) - .get(); + QuerySnapshot> snapshot = await collection + .orderBy('bar.value') + .startAfterDocument(startAfterSnapshot) + .get(); - expect(snapshot.docs.length, equals(2)); - expect(snapshot.docs[0].id, equals('doc2')); - expect(snapshot.docs[1].id, equals('doc1')); - }); + expect(snapshot.docs.length, equals(2)); + expect(snapshot.docs[0].id, equals('doc2')); + expect(snapshot.docs[1].id, equals('doc1')); + }, + ); test('startAfterDocument() starts after a document', () async { CollectionReference> collection = @@ -1132,8 +1157,9 @@ void runQueryTests() { DocumentSnapshot startAtSnapshot = await collection.doc('doc2').get(); - QuerySnapshot> snapshot = - await collection.startAfterDocument(startAtSnapshot).get(); + QuerySnapshot> snapshot = await collection + .startAfterDocument(startAtSnapshot) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc3')); @@ -1149,10 +1175,12 @@ void runQueryTests() { 'createdAt': Timestamp(1, 123456789), }); - Query> baseQuery = - collection.orderBy('createdAt'); - QuerySnapshot> firstPage = - await baseQuery.limit(50).get(); + Query> baseQuery = collection.orderBy( + 'createdAt', + ); + QuerySnapshot> firstPage = await baseQuery + .limit(50) + .get(); expect(firstPage.docs.length, equals(1)); expect(firstPage.docs.first.id, equals('doc1')); @@ -1188,8 +1216,10 @@ void runQueryTests() { ]); DocumentSnapshot startAtSnapshot = await collection.doc('doc2').get(); - Query inequalityQuery = - collection.where('bar.value', isGreaterThan: 5); + Query inequalityQuery = collection.where( + 'bar.value', + isGreaterThan: 5, + ); await expectLater( inequalityQuery.startAfterDocument(startAtSnapshot).get(), @@ -1199,8 +1229,10 @@ void runQueryTests() { 'message', anyOf( contains('Client specified an invalid argument'), - contains('order by clause cannot contain more fields ' - 'after the key'), + contains( + 'order by clause cannot contain more fields ' + 'after the key', + ), ), ), ), @@ -1216,35 +1248,31 @@ void runQueryTests() { (_) async { CollectionReference> collection = await initializeTest( - 'startAfterDocument-wrong-inequality-field-throw', - ); + 'startAfterDocument-wrong-inequality-field-throw', + ); await Future.wait([ collection.doc('doc1').set({ 'bar': {'value': 2}, }), - collection.doc('doc2').set( - { - 'bar': {'value': 10}, - 'wrong-field': 2, - }, - ), - collection.doc('doc3').set( - { - 'bar': {'value': 10}, - 'wrong-field': 2, - }, - ), - collection.doc('doc4').set( - { - 'bar': {'value': 10}, - 'wrong-field': 2, - }, - ), + collection.doc('doc2').set({ + 'bar': {'value': 10}, + 'wrong-field': 2, + }), + collection.doc('doc3').set({ + 'bar': {'value': 10}, + 'wrong-field': 2, + }), + collection.doc('doc4').set({ + 'bar': {'value': 10}, + 'wrong-field': 2, + }), ]); DocumentSnapshot startAtSnapshot = await collection.doc('doc2').get(); - Query inequalityQuery = - collection.where('bar.value', isGreaterThan: 5); + Query inequalityQuery = collection.where( + 'bar.value', + isGreaterThan: 5, + ); await expectLater( inequalityQuery .orderBy('wrong-field') @@ -1256,8 +1284,10 @@ void runQueryTests() { 'message', anyOf( contains('Client specified an invalid argument'), - contains('order by clause cannot contain more fields ' - 'after the key'), + contains( + 'order by clause cannot contain more fields ' + 'after the key', + ), ), ), ), @@ -1268,37 +1298,32 @@ void runQueryTests() { ); testWidgets( - 'Successful request when using orderBy() with same field used on inequality query', - (_) async { - CollectionReference> collection = - await initializeTest('startAfterDocument-correct-inequality-field'); - await Future.wait([ - collection.doc('doc1').set({ - 'bar': 2, - }), - collection.doc('doc2').set({ - 'bar': 10, - }), - collection.doc('doc3').set({ - 'bar': 11, - }), - collection.doc('doc4').set({ - 'bar': 12, - }), - ]); + 'Successful request when using orderBy() with same field used on inequality query', + (_) async { + CollectionReference> collection = + await initializeTest( + 'startAfterDocument-correct-inequality-field', + ); + await Future.wait([ + collection.doc('doc1').set({'bar': 2}), + collection.doc('doc2').set({'bar': 10}), + collection.doc('doc3').set({'bar': 11}), + collection.doc('doc4').set({'bar': 12}), + ]); - DocumentSnapshot startAtSnapshot = await collection.doc('doc2').get(); - Query inequalityQuery = collection.where('bar', isGreaterThan: 5); + DocumentSnapshot startAtSnapshot = await collection.doc('doc2').get(); + Query inequalityQuery = collection.where('bar', isGreaterThan: 5); - final result = await inequalityQuery - .orderBy('bar') - .startAfterDocument(startAtSnapshot) - .get(); + final result = await inequalityQuery + .orderBy('bar') + .startAfterDocument(startAtSnapshot) + .get(); - expect(result.size, equals(2)); - expect(result.docs[0].id, equals('doc3')); - expect(result.docs[1].id, equals('doc4')); - }); + expect(result.size, equals(2)); + expect(result.docs[0].id, equals('doc3')); + expect(result.docs[1].id, equals('doc4')); + }, + ); }); /** @@ -1310,22 +1335,17 @@ void runQueryTests() { CollectionReference> collection = await initializeTest('start-end-string'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 1, - }), - collection.doc('doc2').set({ - 'foo': 2, - }), - collection.doc('doc3').set({ - 'foo': 3, - }), - collection.doc('doc4').set({ - 'foo': 4, - }), + collection.doc('doc1').set({'foo': 1}), + collection.doc('doc2').set({'foo': 2}), + collection.doc('doc3').set({'foo': 3}), + collection.doc('doc4').set({'foo': 4}), ]); - QuerySnapshot> snapshot = - await collection.orderBy('foo').startAt([2]).endAt([3]).get(); + QuerySnapshot> snapshot = await collection + .orderBy('foo') + .startAt([2]) + .endAt([3]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); @@ -1336,22 +1356,17 @@ void runQueryTests() { CollectionReference> collection = await initializeTest('start-end-string'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 1, - }), - collection.doc('doc2').set({ - 'foo': 2, - }), - collection.doc('doc3').set({ - 'foo': 3, - }), - collection.doc('doc4').set({ - 'foo': 4, - }), + collection.doc('doc1').set({'foo': 1}), + collection.doc('doc2').set({'foo': 2}), + collection.doc('doc3').set({'foo': 3}), + collection.doc('doc4').set({'foo': 4}), ]); - QuerySnapshot> snapshot = - await collection.orderBy('foo').startAt([2]).endBefore([4]).get(); + QuerySnapshot> snapshot = await collection + .orderBy('foo') + .startAt([2]) + .endBefore([4]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); @@ -1362,22 +1377,17 @@ void runQueryTests() { CollectionReference> collection = await initializeTest('start-end-field-path'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 1, - }), - collection.doc('doc2').set({ - 'foo': 2, - }), - collection.doc('doc3').set({ - 'foo': 3, - }), - collection.doc('doc4').set({ - 'foo': 4, - }), + collection.doc('doc1').set({'foo': 1}), + collection.doc('doc2').set({'foo': 2}), + collection.doc('doc3').set({'foo': 3}), + collection.doc('doc4').set({'foo': 4}), ]); - QuerySnapshot> snapshot = - await collection.orderBy('foo').startAfter([1]).endAt([3]).get(); + QuerySnapshot> snapshot = await collection + .orderBy('foo') + .startAfter([1]) + .endAt([3]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); @@ -1388,18 +1398,10 @@ void runQueryTests() { CollectionReference> collection = await initializeTest('start-end-document'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 1, - }), - collection.doc('doc2').set({ - 'foo': 2, - }), - collection.doc('doc3').set({ - 'foo': 3, - }), - collection.doc('doc4').set({ - 'foo': 4, - }), + collection.doc('doc1').set({'foo': 1}), + collection.doc('doc2').set({'foo': 2}), + collection.doc('doc3').set({'foo': 3}), + collection.doc('doc4').set({'foo': 4}), ]); DocumentSnapshot startAtSnapshot = await collection.doc('doc2').get(); @@ -1425,26 +1427,23 @@ void runQueryTests() { CollectionReference> collection = await initializeTest('limit'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 1, - }), - collection.doc('doc2').set({ - 'foo': 2, - }), - collection.doc('doc3').set({ - 'foo': 3, - }), + collection.doc('doc1').set({'foo': 1}), + collection.doc('doc2').set({'foo': 2}), + collection.doc('doc3').set({'foo': 3}), ]); - QuerySnapshot> snapshot = - await collection.limit(2).get(); + QuerySnapshot> snapshot = await collection + .limit(2) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc1')); expect(snapshot.docs[1].id, equals('doc2')); - QuerySnapshot> snapshot2 = - await collection.orderBy('foo', descending: true).limit(2).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy('foo', descending: true) + .limit(2) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc3')); @@ -1455,19 +1454,15 @@ void runQueryTests() { CollectionReference> collection = await initializeTest('limitToLast'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 1, - }), - collection.doc('doc2').set({ - 'foo': 2, - }), - collection.doc('doc3').set({ - 'foo': 3, - }), + collection.doc('doc1').set({'foo': 1}), + collection.doc('doc2').set({'foo': 2}), + collection.doc('doc3').set({'foo': 3}), ]); - QuerySnapshot> snapshot = - await collection.orderBy('foo').limitToLast(2).get(); + QuerySnapshot> snapshot = await collection + .orderBy('foo') + .limitToLast(2) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); @@ -1493,22 +1488,16 @@ void runQueryTests() { await initializeTest('order-document-id'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 1, - }), - collection.doc('doc2').set({ - 'foo': 1, - }), - collection.doc('doc3').set({ - 'foo': 1, - }), - collection.doc('doc4').set({ - 'bar': 1, - }), + collection.doc('doc1').set({'foo': 1}), + collection.doc('doc2').set({'foo': 1}), + collection.doc('doc3').set({'foo': 1}), + collection.doc('doc4').set({'bar': 1}), ]); - QuerySnapshot> snapshot = - await collection.orderBy('foo').orderBy(FieldPath.documentId).get(); + QuerySnapshot> snapshot = await collection + .orderBy('foo') + .orderBy(FieldPath.documentId) + .get(); expect(snapshot.docs.length, equals(3)); expect(snapshot.docs[0].id, equals('doc1')); @@ -1521,19 +1510,14 @@ void runQueryTests() { await initializeTest('order-asc'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 3, - }), - collection.doc('doc2').set({ - 'foo': 2, - }), - collection.doc('doc3').set({ - 'foo': 1, - }), + collection.doc('doc1').set({'foo': 3}), + collection.doc('doc2').set({'foo': 2}), + collection.doc('doc3').set({'foo': 1}), ]); - QuerySnapshot> snapshot = - await collection.orderBy('foo').get(); + QuerySnapshot> snapshot = await collection + .orderBy('foo') + .get(); expect(snapshot.docs.length, equals(3)); expect(snapshot.docs[0].id, equals('doc3')); @@ -1545,19 +1529,14 @@ void runQueryTests() { CollectionReference> collection = await initializeTest('order-desc'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 1, - }), - collection.doc('doc2').set({ - 'foo': 2, - }), - collection.doc('doc3').set({ - 'foo': 3, - }), + collection.doc('doc1').set({'foo': 1}), + collection.doc('doc2').set({'foo': 2}), + collection.doc('doc3').set({'foo': 3}), ]); - QuerySnapshot> snapshot = - await collection.orderBy('foo', descending: true).get(); + QuerySnapshot> snapshot = await collection + .orderBy('foo', descending: true) + .get(); expect(snapshot.docs.length, equals(3)); expect(snapshot.docs[0].id, equals('doc3')); @@ -1571,52 +1550,46 @@ void runQueryTests() { */ group('Query.where()', () { - test('returns documents when querying for properties that are not null', - () async { - CollectionReference> collection = - await initializeTest('not-null'); - await Future.wait([ - collection.doc('doc1').set({ - 'foo': 'bar', - }), - collection.doc('doc2').set({ - 'foo': 'bar', - }), - collection.doc('doc3').set({ - 'foo': null, - }), - ]); + test( + 'returns documents when querying for properties that are not null', + () async { + CollectionReference> collection = + await initializeTest('not-null'); + await Future.wait([ + collection.doc('doc1').set({'foo': 'bar'}), + collection.doc('doc2').set({'foo': 'bar'}), + collection.doc('doc3').set({'foo': null}), + ]); - QuerySnapshot> snapshot = - await collection.where('foo', isNull: false).get(); + QuerySnapshot> snapshot = await collection + .where('foo', isNull: false) + .get(); - expect(snapshot.docs.length, equals(2)); - expect(snapshot.docs[0].id, equals('doc1')); - expect(snapshot.docs[1].id, equals('doc2')); - }); + expect(snapshot.docs.length, equals(2)); + expect(snapshot.docs[0].id, equals('doc1')); + expect(snapshot.docs[1].id, equals('doc2')); + }, + ); - test('returns documents when querying properties that are equal to null', - () async { - CollectionReference> collection = - await initializeTest('not-null'); - await Future.wait([ - collection.doc('doc1').set({ - 'foo': 'bar', - }), - collection.doc('doc2').set({ - 'foo': 'bar', - }), - collection.doc('doc3').set({ - 'foo': null, - }), - ]); + test( + 'returns documents when querying properties that are equal to null', + () async { + CollectionReference> collection = + await initializeTest('not-null'); + await Future.wait([ + collection.doc('doc1').set({'foo': 'bar'}), + collection.doc('doc2').set({'foo': 'bar'}), + collection.doc('doc3').set({'foo': null}), + ]); - QuerySnapshot> snapshot = - await collection.where('foo', isNull: true).get(); + QuerySnapshot> snapshot = await collection + .where('foo', isNull: true) + .get(); - expect(snapshot.docs.length, equals(1)); - expect(snapshot.docs[0].id, equals('doc3')); - }); + expect(snapshot.docs.length, equals(1)); + expect(snapshot.docs[0].id, equals('doc3')); + }, + ); test('returns with equal checks', () async { CollectionReference> collection = @@ -1624,19 +1597,14 @@ void runQueryTests() { int rand = Random().nextInt(9999); await Future.wait([ - collection.doc('doc1').set({ - 'foo': rand, - }), - collection.doc('doc2').set({ - 'foo': rand, - }), - collection.doc('doc3').set({ - 'foo': rand + 1, - }), + collection.doc('doc1').set({'foo': rand}), + collection.doc('doc2').set({'foo': rand}), + collection.doc('doc3').set({'foo': rand + 1}), ]); - QuerySnapshot> snapshot = - await collection.where('foo', isEqualTo: rand).get(); + QuerySnapshot> snapshot = await collection + .where('foo', isEqualTo: rand) + .get(); expect(snapshot.docs.length, equals(2)); snapshot.docs.forEach((doc) { @@ -1650,19 +1618,14 @@ void runQueryTests() { int rand = Random().nextInt(9999); await Future.wait([ - collection.doc('doc1').set({ - 'foo': rand, - }), - collection.doc('doc2').set({ - 'foo': rand, - }), - collection.doc('doc3').set({ - 'foo': rand + 1, - }), + collection.doc('doc1').set({'foo': rand}), + collection.doc('doc2').set({'foo': rand}), + collection.doc('doc3').set({'foo': rand + 1}), ]); - QuerySnapshot> snapshot = - await collection.where('foo', isNotEqualTo: rand).get(); + QuerySnapshot> snapshot = await collection + .where('foo', isNotEqualTo: rand) + .get(); expect(snapshot.docs.length, equals(1)); snapshot.docs.forEach((doc) { @@ -1676,22 +1639,15 @@ void runQueryTests() { int rand = Random().nextInt(9999); await Future.wait([ - collection.doc('doc1').set({ - 'foo': rand - 1, - }), - collection.doc('doc2').set({ - 'foo': rand, - }), - collection.doc('doc3').set({ - 'foo': rand + 1, - }), - collection.doc('doc4').set({ - 'foo': rand + 2, - }), + collection.doc('doc1').set({'foo': rand - 1}), + collection.doc('doc2').set({'foo': rand}), + collection.doc('doc3').set({'foo': rand + 1}), + collection.doc('doc4').set({'foo': rand + 2}), ]); - QuerySnapshot> snapshot = - await collection.where('foo', isGreaterThan: rand).get(); + QuerySnapshot> snapshot = await collection + .where('foo', isGreaterThan: rand) + .get(); expect(snapshot.docs.length, equals(2)); snapshot.docs.forEach((doc) { @@ -1705,22 +1661,15 @@ void runQueryTests() { int rand = Random().nextInt(9999); await Future.wait([ - collection.doc('doc1').set({ - 'foo': rand - 1, - }), - collection.doc('doc2').set({ - 'foo': rand, - }), - collection.doc('doc3').set({ - 'foo': rand + 1, - }), - collection.doc('doc4').set({ - 'foo': rand + 2, - }), + collection.doc('doc1').set({'foo': rand - 1}), + collection.doc('doc2').set({'foo': rand}), + collection.doc('doc3').set({'foo': rand + 1}), + collection.doc('doc4').set({'foo': rand + 2}), ]); - QuerySnapshot> snapshot = - await collection.where('foo', isGreaterThanOrEqualTo: rand).get(); + QuerySnapshot> snapshot = await collection + .where('foo', isGreaterThanOrEqualTo: rand) + .get(); expect(snapshot.docs.length, equals(3)); snapshot.docs.forEach((doc) { @@ -1734,19 +1683,14 @@ void runQueryTests() { int rand = Random().nextInt(9999); await Future.wait([ - collection.doc('doc1').set({ - 'foo': -rand + 1, - }), - collection.doc('doc2').set({ - 'foo': -rand + 2, - }), - collection.doc('doc3').set({ - 'foo': rand, - }), + collection.doc('doc1').set({'foo': -rand + 1}), + collection.doc('doc2').set({'foo': -rand + 2}), + collection.doc('doc3').set({'foo': rand}), ]); - QuerySnapshot> snapshot = - await collection.where('foo', isLessThan: rand).get(); + QuerySnapshot> snapshot = await collection + .where('foo', isLessThan: rand) + .get(); expect(snapshot.docs.length, equals(2)); snapshot.docs.forEach((doc) { @@ -1760,22 +1704,15 @@ void runQueryTests() { int rand = Random().nextInt(9999); await Future.wait([ - collection.doc('doc1').set({ - 'foo': -rand + 1, - }), - collection.doc('doc2').set({ - 'foo': -rand + 2, - }), - collection.doc('doc3').set({ - 'foo': rand, - }), - collection.doc('doc4').set({ - 'foo': rand + 1, - }), + collection.doc('doc1').set({'foo': -rand + 1}), + collection.doc('doc2').set({'foo': -rand + 2}), + collection.doc('doc3').set({'foo': rand}), + collection.doc('doc4').set({'foo': rand + 1}), ]); - QuerySnapshot> snapshot = - await collection.where('foo', isLessThanOrEqualTo: rand).get(); + QuerySnapshot> snapshot = await collection + .where('foo', isLessThanOrEqualTo: rand) + .get(); expect(snapshot.docs.length, equals(3)); snapshot.docs.forEach((doc) { @@ -1800,8 +1737,9 @@ void runQueryTests() { }), ]); - QuerySnapshot> snapshot = - await collection.where('foo', arrayContains: '$rand').get(); + QuerySnapshot> snapshot = await collection + .where('foo', arrayContains: '$rand') + .get(); expect(snapshot.docs.length, equals(2)); snapshot.docs.forEach((doc) { @@ -1814,22 +1752,15 @@ void runQueryTests() { await initializeTest('where-in'); await Future.wait([ - collection.doc('doc1').set({ - 'status': 'Ordered', - }), - collection.doc('doc2').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc3').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc4').set({ - 'status': 'Incomplete', - }), + collection.doc('doc1').set({'status': 'Ordered'}), + collection.doc('doc2').set({'status': 'Ready to Ship'}), + collection.doc('doc3').set({'status': 'Ready to Ship'}), + collection.doc('doc4').set({'status': 'Incomplete'}), ]); QuerySnapshot> snapshot = await collection - .where('status', whereIn: ['Ready to Ship', 'Ordered']).get(); + .where('status', whereIn: ['Ready to Ship', 'Ordered']) + .get(); expect(snapshot.docs.length, equals(3)); snapshot.docs.forEach((doc) { @@ -1843,18 +1774,10 @@ void runQueryTests() { await initializeTest('where-in-iterable'); await Future.wait([ - collection.doc('doc1').set({ - 'status': 'Ordered', - }), - collection.doc('doc2').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc3').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc4').set({ - 'status': 'Incomplete', - }), + collection.doc('doc1').set({'status': 'Ordered'}), + collection.doc('doc2').set({'status': 'Ready to Ship'}), + collection.doc('doc3').set({'status': 'Ready to Ship'}), + collection.doc('doc4').set({'status': 'Incomplete'}), ]); QuerySnapshot> snapshot = await collection @@ -1877,22 +1800,15 @@ void runQueryTests() { await initializeTest('where-in'); await Future.wait([ - collection.doc('doc1').set({ - 'status': 'Ordered', - }), - collection.doc('doc2').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc3').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc4').set({ - 'status': 'Incomplete', - }), + collection.doc('doc1').set({'status': 'Ordered'}), + collection.doc('doc2').set({'status': 'Ready to Ship'}), + collection.doc('doc3').set({'status': 'Ready to Ship'}), + collection.doc('doc4').set({'status': 'Incomplete'}), ]); QuerySnapshot> snapshot = await collection - .where('status', whereIn: {'Ready to Ship', 'Ordered'}).get(); + .where('status', whereIn: {'Ready to Ship', 'Ordered'}) + .get(); expect(snapshot.docs.length, equals(3)); snapshot.docs.forEach((doc) { @@ -1906,22 +1822,15 @@ void runQueryTests() { await initializeTest('where-not-in'); await Future.wait([ - collection.doc('doc1').set({ - 'status': 'Ordered', - }), - collection.doc('doc2').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc3').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc4').set({ - 'status': 'Incomplete', - }), + collection.doc('doc1').set({'status': 'Ordered'}), + collection.doc('doc2').set({'status': 'Ready to Ship'}), + collection.doc('doc3').set({'status': 'Ready to Ship'}), + collection.doc('doc4').set({'status': 'Incomplete'}), ]); QuerySnapshot> snapshot = await collection - .where('status', whereNotIn: ['Ready to Ship', 'Ordered']).get(); + .where('status', whereNotIn: ['Ready to Ship', 'Ordered']) + .get(); expect(snapshot.docs.length, equals(1)); snapshot.docs.forEach((doc) { @@ -1935,22 +1844,15 @@ void runQueryTests() { await initializeTest('where-not-in'); await Future.wait([ - collection.doc('doc1').set({ - 'status': 'Ordered', - }), - collection.doc('doc2').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc3').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc4').set({ - 'status': 'Incomplete', - }), + collection.doc('doc1').set({'status': 'Ordered'}), + collection.doc('doc2').set({'status': 'Ready to Ship'}), + collection.doc('doc3').set({'status': 'Ready to Ship'}), + collection.doc('doc4').set({'status': 'Incomplete'}), ]); QuerySnapshot> snapshot = await collection - .where('status', whereNotIn: {'Ready to Ship', 'Ordered'}).get(); + .where('status', whereNotIn: {'Ready to Ship', 'Ordered'}) + .get(); expect(snapshot.docs.length, equals(1)); snapshot.docs.forEach((doc) { @@ -1978,10 +1880,9 @@ void runQueryTests() { }), ]); - QuerySnapshot> snapshot = await collection.where( - 'category', - arrayContainsAny: ['Appliances', 'Electronics'], - ).get(); + QuerySnapshot> snapshot = await collection + .where('category', arrayContainsAny: ['Appliances', 'Electronics']) + .get(); // 2nd record should only be returned once expect(snapshot.docs.length, equals(3)); @@ -2006,10 +1907,9 @@ void runQueryTests() { }), ]); - QuerySnapshot> snapshot = await collection.where( - 'category', - arrayContainsAny: {'Appliances', 'Electronics'}, - ).get(); + QuerySnapshot> snapshot = await collection + .where('category', arrayContainsAny: {'Appliances', 'Electronics'}) + .get(); // 2nd record should only be returned once expect(snapshot.docs.length, equals(3)); @@ -2025,25 +1925,20 @@ void runQueryTests() { await Future.wait([ collection.doc('doc1').set({ - 'nested': { - 'foo.bar@gmail.com': true, - }, + 'nested': {'foo.bar@gmail.com': true}, }), collection.doc('doc2').set({ - 'nested': { - 'foo.bar@gmail.com': true, - }, + 'nested': {'foo.bar@gmail.com': true}, 'foo': 'bar', }), collection.doc('doc3').set({ - 'nested': { - 'foo.bar@gmail.com': false, - }, + 'nested': {'foo.bar@gmail.com': false}, }), ]); - QuerySnapshot> snapshot = - await collection.where(fieldPath, isEqualTo: true).get(); + QuerySnapshot> snapshot = await collection + .where(fieldPath, isEqualTo: true) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].get(fieldPath), isTrue); @@ -2060,9 +1955,7 @@ void runQueryTests() { }); // Add secondary document for sanity check - await collection.add({ - 'bar': 'baz', - }); + await collection.add({'bar': 'baz'}); QuerySnapshot> snapshot = await collection .where(FieldPath.documentId, isEqualTo: docRef.id) @@ -2076,19 +1969,13 @@ void runQueryTests() { CollectionReference> collection = await initializeTest('where-document-reference'); - DocumentReference> ref = - FirebaseFirestore.instance.doc('foo/bar'); + DocumentReference> ref = FirebaseFirestore.instance + .doc('foo/bar'); await Future.wait([ - collection.add({ - 'foo': ref, - }), - collection.add({ - 'foo': FirebaseFirestore.instance.doc('bar/baz'), - }), - collection.add({ - 'foo': 'foo/bar', - }), + collection.add({'foo': ref}), + collection.add({'foo': FirebaseFirestore.instance.doc('bar/baz')}), + collection.add({'foo': 'foo/bar'}), ]); QuerySnapshot> snapshot = await collection @@ -2102,104 +1989,100 @@ void runQueryTests() { group('Query.where() with Filter class', () { test( - 'returns documents with `DocumentReference` as an argument in `isEqualTo`', - () async { - CollectionReference> collection = - await initializeTest('doc-ref-arg-isequal-to'); - final ref = FirebaseFirestore.instance.doc('foo/bar'); - final ref2 = FirebaseFirestore.instance.doc('foo/foo'); - await Future.wait([ - collection.doc('doc1').set({ - 'genre': 'fantasy', - 'title': 'Book A', - 'ref': FirebaseFirestore.instance.doc('foo/bar'), - }), - collection.doc('doc2').set({ - 'genre': 'fantasy', - 'title': 'Book B', - 'ref': FirebaseFirestore.instance.doc('foo/bar'), - }), - collection.doc('doc3').set({ - 'genre': 'fantasy', - 'title': 'Book C', - 'ref': ref2, - }), - ]); + 'returns documents with `DocumentReference` as an argument in `isEqualTo`', + () async { + CollectionReference> collection = + await initializeTest('doc-ref-arg-isequal-to'); + final ref = FirebaseFirestore.instance.doc('foo/bar'); + final ref2 = FirebaseFirestore.instance.doc('foo/foo'); + await Future.wait([ + collection.doc('doc1').set({ + 'genre': 'fantasy', + 'title': 'Book A', + 'ref': FirebaseFirestore.instance.doc('foo/bar'), + }), + collection.doc('doc2').set({ + 'genre': 'fantasy', + 'title': 'Book B', + 'ref': FirebaseFirestore.instance.doc('foo/bar'), + }), + collection.doc('doc3').set({ + 'genre': 'fantasy', + 'title': 'Book C', + 'ref': ref2, + }), + ]); - final results = await collection - .where( - Filter.or( - Filter.and( - Filter('genre', isEqualTo: 'fantasy'), - Filter('ref', isEqualTo: ref), - ), - Filter.and( - Filter('genre', isEqualTo: 'fantasy'), - Filter( - 'ref', - isEqualTo: ref2, + final results = await collection + .where( + Filter.or( + Filter.and( + Filter('genre', isEqualTo: 'fantasy'), + Filter('ref', isEqualTo: ref), + ), + Filter.and( + Filter('genre', isEqualTo: 'fantasy'), + Filter('ref', isEqualTo: ref2), ), ), - ), - ) - .orderBy('title', descending: true) - .get(); + ) + .orderBy('title', descending: true) + .get(); - expect(results.docs.length, equals(3)); - expect(results.docs[0].data()['title'], equals('Book C')); - expect(results.docs[1].data()['title'], equals('Book B')); - expect(results.docs[2].data()['title'], equals('Book A')); - }); + expect(results.docs.length, equals(3)); + expect(results.docs[0].data()['title'], equals('Book C')); + expect(results.docs[1].data()['title'], equals('Book B')); + expect(results.docs[2].data()['title'], equals('Book A')); + }, + ); test( - 'returns documents with `DocumentReference` as an argument in `arrayContains`', - () async { - CollectionReference> collection = - await initializeTest('doc-ref-arg-array-contains'); - final ref = FirebaseFirestore.instance.doc('foo/bar'); - final ref2 = FirebaseFirestore.instance.doc('foo/foo'); - await Future.wait([ - collection.doc('doc1').set({ - 'genre': 'fantasy', - 'title': 'Book A', - 'ref': [ref], - }), - collection.doc('doc2').set({ - 'genre': 'fantasy', - 'title': 'Book B', - 'ref': [ref], - }), - collection.doc('doc3').set({ - 'genre': 'adventure', - 'title': 'Book C', - 'ref': [ref2], - }), - ]); + 'returns documents with `DocumentReference` as an argument in `arrayContains`', + () async { + CollectionReference> collection = + await initializeTest('doc-ref-arg-array-contains'); + final ref = FirebaseFirestore.instance.doc('foo/bar'); + final ref2 = FirebaseFirestore.instance.doc('foo/foo'); + await Future.wait([ + collection.doc('doc1').set({ + 'genre': 'fantasy', + 'title': 'Book A', + 'ref': [ref], + }), + collection.doc('doc2').set({ + 'genre': 'fantasy', + 'title': 'Book B', + 'ref': [ref], + }), + collection.doc('doc3').set({ + 'genre': 'adventure', + 'title': 'Book C', + 'ref': [ref2], + }), + ]); - final results = await collection - .where( - Filter.or( - Filter.and( - Filter('genre', isEqualTo: 'fantasy'), - Filter('ref', arrayContains: ref), - ), - Filter.and( - Filter('genre', isEqualTo: 'adventure'), - Filter( - 'ref', - arrayContains: ref2, + final results = await collection + .where( + Filter.or( + Filter.and( + Filter('genre', isEqualTo: 'fantasy'), + Filter('ref', arrayContains: ref), + ), + Filter.and( + Filter('genre', isEqualTo: 'adventure'), + Filter('ref', arrayContains: ref2), ), ), - ), - ) - .orderBy('title', descending: true) - .get(); + ) + .orderBy('title', descending: true) + .get(); - expect(results.docs.length, equals(3)); - expect(results.docs[0].data()['title'], equals('Book C')); - expect(results.docs[1].data()['title'], equals('Book B')); - expect(results.docs[2].data()['title'], equals('Book A')); - }); + expect(results.docs.length, equals(3)); + expect(results.docs[0].data()['title'], equals('Book C')); + expect(results.docs[1].data()['title'], equals('Book B')); + expect(results.docs[2].data()['title'], equals('Book A')); + }, + ); test('returns documents with OR filter for arrayContainsAny', () async { CollectionReference> collection = @@ -2268,45 +2151,47 @@ void runQueryTests() { expect(results.docs[0].data()['genre'], equals(['sci-fi', 'action'])); }); - test('returns documents with OR filter and a previous condition', - () async { - CollectionReference> collection = - await initializeTest('where-filter-and'); - await Future.wait([ - collection.doc('doc1').set({ - 'genre': 'fantasy', - 'rating': 4.5, - 'year': 1970, - }), - collection.doc('doc2').set({ - 'genre': 'fantasy', - 'rating': 3.8, - 'year': 1980, - }), - collection.doc('doc3').set({ - 'genre': 'sci-fi', - 'rating': 4.2, - 'year': 1980, - }), - ]); + test( + 'returns documents with OR filter and a previous condition', + () async { + CollectionReference> collection = + await initializeTest('where-filter-and'); + await Future.wait([ + collection.doc('doc1').set({ + 'genre': 'fantasy', + 'rating': 4.5, + 'year': 1970, + }), + collection.doc('doc2').set({ + 'genre': 'fantasy', + 'rating': 3.8, + 'year': 1980, + }), + collection.doc('doc3').set({ + 'genre': 'sci-fi', + 'rating': 4.2, + 'year': 1980, + }), + ]); - final results = await collection - .where('genre', isEqualTo: 'fantasy') - .where( - Filter.or( - Filter('year', isEqualTo: 1980), - Filter('rating', isGreaterThanOrEqualTo: 4.0), - ), - ) - .orderBy('rating') - .get(); + final results = await collection + .where('genre', isEqualTo: 'fantasy') + .where( + Filter.or( + Filter('year', isEqualTo: 1980), + Filter('rating', isGreaterThanOrEqualTo: 4.0), + ), + ) + .orderBy('rating') + .get(); - expect(results.docs.length, equals(2)); - expect(results.docs[0].id, equals('doc2')); - expect(results.docs[0].data()['rating'], equals(3.8)); - expect(results.docs[1].id, equals('doc1')); - expect(results.docs[1].data()['rating'], equals(4.5)); - }); + expect(results.docs.length, equals(2)); + expect(results.docs[0].id, equals('doc2')); + expect(results.docs[0].data()['rating'], equals(3.8)); + expect(results.docs[1].id, equals('doc1')); + expect(results.docs[1].data()['rating'], equals(4.5)); + }, + ); test('returns documents with nested OR and AND filters', () async { CollectionReference> collection = @@ -2349,10 +2234,7 @@ void runQueryTests() { expect(results.docs.length, equals(2)); expect(results.docs[0].id, equals('doc4')); expect(results.docs[0].data()['rating'], equals(4.7)); - expect( - results.docs[0].data()['genre'], - equals(['mystery', 'action']), - ); + expect(results.docs[0].data()['genre'], equals(['mystery', 'action'])); expect(results.docs[1].id, equals('doc3')); expect(results.docs[1].data()['rating'], equals(4.2)); expect(results.docs[1].data()['genre'], equals(['sci-fi', 'action'])); @@ -2506,8 +2388,8 @@ void runQueryTests() { () async { CollectionReference> collection = await initializeTest( - 'array-contain-not-equal-conjunctive-queries', - ); + 'array-contain-not-equal-conjunctive-queries', + ); await Future.wait([ collection.doc('doc1').set({ @@ -2643,10 +2525,7 @@ void runQueryTests() { expect(results.docs.length, equals(3)); expect(results.docs[0].id, equals('doc4')); expect(results.docs[0].data()['rating'], equals(4.7)); - expect( - results.docs[0].data()['genre'], - equals(['sci-fi', 'thriller']), - ); + expect(results.docs[0].data()['genre'], equals(['sci-fi', 'thriller'])); expect(results.docs[1].id, equals('doc3')); expect(results.docs[1].data()['rating'], equals(4.2)); expect(results.docs[1].data()['genre'], equals(['sci-fi', 'thriller'])); @@ -2660,8 +2539,8 @@ void runQueryTests() { () async { CollectionReference> collection = await initializeTest( - 'array-contain-not-equal-disjunctive-queries', - ); + 'array-contain-not-equal-disjunctive-queries', + ); await Future.wait([ collection.doc('doc1').set({ @@ -2699,127 +2578,123 @@ void runQueryTests() { ); test( - 'allow multiple disjunctive queries for "arrayContainsAny" using ".where() API"', - () async { - CollectionReference> collection = - await initializeTest('multiple-disjunctive-where'); + 'allow multiple disjunctive queries for "arrayContainsAny" using ".where() API"', + () async { + CollectionReference> collection = + await initializeTest('multiple-disjunctive-where'); - await Future.wait([ - collection.doc('doc1').set({ - 'genre': ['Not', 'Here'], - 'number': 1, - }), - collection.doc('doc2').set({ - 'genre': ['Animation', 'Another'], - 'number': 2, - }), - collection.doc('doc3').set({ - 'genre': ['Adventure', 'Another'], - 'number': 3, - }), - ]); - final genres = [ - 'Action', - 'Adventure', - 'Animation', - 'Biography', - 'Comedy', - 'Crime', - 'Drama', - 'Documentary', - 'Family', - 'Fantasy', - 'Film-Noir', - 'History', - 'Horror', - 'Music', - 'Musical', - 'Mystery', - 'Romance', - 'Sci-Fi', - 'Sport', - 'Thriller', - 'War', - 'Western', - 'Epic', - 'Tragedy', - 'Satire', - 'Romantic Comedy', - 'Black Comedy', - 'Paranormal', - 'Non-fiction', - 'Realism', - ]; + await Future.wait([ + collection.doc('doc1').set({ + 'genre': ['Not', 'Here'], + 'number': 1, + }), + collection.doc('doc2').set({ + 'genre': ['Animation', 'Another'], + 'number': 2, + }), + collection.doc('doc3').set({ + 'genre': ['Adventure', 'Another'], + 'number': 3, + }), + ]); + final genres = [ + 'Action', + 'Adventure', + 'Animation', + 'Biography', + 'Comedy', + 'Crime', + 'Drama', + 'Documentary', + 'Family', + 'Fantasy', + 'Film-Noir', + 'History', + 'Horror', + 'Music', + 'Musical', + 'Mystery', + 'Romance', + 'Sci-Fi', + 'Sport', + 'Thriller', + 'War', + 'Western', + 'Epic', + 'Tragedy', + 'Satire', + 'Romantic Comedy', + 'Black Comedy', + 'Paranormal', + 'Non-fiction', + 'Realism', + ]; - final results = await collection - .where( - 'genre', - arrayContainsAny: genres, - ) - .orderBy('number') - .get(); + final results = await collection + .where('genre', arrayContainsAny: genres) + .orderBy('number') + .get(); - expect(results.docs.length, equals(2)); - expect(results.docs[0].id, equals('doc2')); - expect(results.docs[1].id, equals('doc3')); - }); + expect(results.docs.length, equals(2)); + expect(results.docs[0].id, equals('doc2')); + expect(results.docs[1].id, equals('doc3')); + }, + ); test( - 'allow multiple disjunctive queries for "whereIn" using ".where() API"', - () async { - CollectionReference> collection = - await initializeTest('multiple-disjunctive-where'); + 'allow multiple disjunctive queries for "whereIn" using ".where() API"', + () async { + CollectionReference> collection = + await initializeTest('multiple-disjunctive-where'); - await Future.wait([ - collection.doc('doc1').set({'genre': 'Not this', 'number': 1}), - collection.doc('doc2').set({'genre': 'Animation', 'number': 2}), - collection.doc('doc3').set({'genre': 'Adventure', 'number': 3}), - ]); - final genres = [ - 'Action', - 'Adventure', - 'Animation', - 'Biography', - 'Comedy', - 'Crime', - 'Drama', - 'Documentary', - 'Family', - 'Fantasy', - 'Film-Noir', - 'History', - 'Horror', - 'Music', - 'Musical', - 'Mystery', - 'Romance', - 'Sci-Fi', - 'Sport', - 'Thriller', - 'War', - 'Western', - 'Epic', - 'Tragedy', - 'Satire', - 'Romantic Comedy', - 'Black Comedy', - 'Paranormal', - 'Non-fiction', - 'Realism', - ]; + await Future.wait([ + collection.doc('doc1').set({'genre': 'Not this', 'number': 1}), + collection.doc('doc2').set({'genre': 'Animation', 'number': 2}), + collection.doc('doc3').set({'genre': 'Adventure', 'number': 3}), + ]); + final genres = [ + 'Action', + 'Adventure', + 'Animation', + 'Biography', + 'Comedy', + 'Crime', + 'Drama', + 'Documentary', + 'Family', + 'Fantasy', + 'Film-Noir', + 'History', + 'Horror', + 'Music', + 'Musical', + 'Mystery', + 'Romance', + 'Sci-Fi', + 'Sport', + 'Thriller', + 'War', + 'Western', + 'Epic', + 'Tragedy', + 'Satire', + 'Romantic Comedy', + 'Black Comedy', + 'Paranormal', + 'Non-fiction', + 'Realism', + ]; - final results = await collection - .where( - 'genre', - whereIn: genres, - ) - .orderBy('number') - .get(); + final results = await collection + .where('genre', whereIn: genres) + .orderBy('number') + .get(); - expect(results.docs.length, equals(2)); - expect(results.docs[0].id, equals('doc2')); - expect(results.docs[1].id, equals('doc3')); - }); + expect(results.docs.length, equals(2)); + expect(results.docs[0].id, equals('doc2')); + expect(results.docs[1].id, equals('doc3')); + }, + ); test('"whereIn" query combined with "arrayContainsAny"', () async { CollectionReference> collection = @@ -2840,14 +2715,8 @@ void runQueryTests() { ]); final results = await collection - .where( - 'value', - arrayContainsAny: [1, 7], - ) - .where( - 'prop', - whereIn: ['foo', 'basalt'], - ) + .where('value', arrayContainsAny: [1, 7]) + .where('prop', whereIn: ['foo', 'basalt']) .orderBy('prop') .get(); @@ -2866,9 +2735,7 @@ void runQueryTests() { ]); final results = await collection - .where( - Filter('value', isEqualTo: 5), - ) + .where(Filter('value', isEqualTo: 5)) .get(); expect(results.docs.length, equals(2)); @@ -2886,9 +2753,7 @@ void runQueryTests() { ]); final results = await collection - .where( - Filter('value', isNotEqualTo: 5), - ) + .where(Filter('value', isNotEqualTo: 5)) .get(); expect(results.docs.length, equals(1)); @@ -2905,9 +2770,7 @@ void runQueryTests() { ]); final results = await collection - .where( - Filter('value', isLessThan: 7), - ) + .where(Filter('value', isLessThan: 7)) .get(); expect(results.docs.length, equals(1)); @@ -2924,9 +2787,7 @@ void runQueryTests() { ]); final results = await collection - .where( - Filter('value', isLessThanOrEqualTo: 7), - ) + .where(Filter('value', isLessThanOrEqualTo: 7)) .get(); expect(results.docs.length, equals(2)); @@ -2944,9 +2805,7 @@ void runQueryTests() { ]); final results = await collection - .where( - Filter('value', isGreaterThan: 5), - ) + .where(Filter('value', isGreaterThan: 5)) .get(); expect(results.docs.length, equals(2)); @@ -2964,9 +2823,7 @@ void runQueryTests() { ]); final results = await collection - .where( - Filter('value', isGreaterThanOrEqualTo: 7), - ) + .where(Filter('value', isGreaterThanOrEqualTo: 7)) .get(); expect(results.docs.length, equals(2)); @@ -2990,9 +2847,7 @@ void runQueryTests() { ]); final results = await collection - .where( - Filter('value', arrayContains: 1), - ) + .where(Filter('value', arrayContains: 1)) .get(); expect(results.docs.length, equals(2)); @@ -3016,9 +2871,7 @@ void runQueryTests() { ]); final results = await collection - .where( - Filter('value', arrayContainsAny: [1, 7]), - ) + .where(Filter('value', arrayContainsAny: [1, 7])) .get(); expect(results.docs.length, equals(3)); @@ -3034,9 +2887,7 @@ void runQueryTests() { ]); final results = await collection - .where( - Filter('value', whereIn: ['A', 'C']), - ) + .where(Filter('value', whereIn: ['A', 'C'])) .get(); expect(results.docs.length, equals(2)); @@ -3054,9 +2905,7 @@ void runQueryTests() { ]); final results = await collection - .where( - Filter('value', whereNotIn: ['A', 'C']), - ) + .where(Filter('value', whereNotIn: ['A', 'C'])) .get(); expect(results.docs.length, equals(1)); @@ -3073,9 +2922,7 @@ void runQueryTests() { ]); final results = await collection - .where( - Filter('value', isNull: true), - ) + .where(Filter('value', isNull: true)) .get(); expect(results.docs.length, equals(1)); @@ -3098,7 +2945,8 @@ void runQueryTests() { results = await collection .where(Filter('value', isGreaterThan: 1)) .orderBy('value', descending: false) - .endAt([3]).get(); + .endAt([3]) + .get(); expect(results.docs.length, equals(2)); expect(results.docs[0].data()['title'], equals('B')); expect(results.docs[1].data()['title'], equals('C')); @@ -3121,7 +2969,8 @@ void runQueryTests() { results = await collection .where(Filter('value', isGreaterThan: 1)) .orderBy('value', descending: false) - .endBefore([4]).get(); + .endBefore([4]) + .get(); expect(results.docs.length, equals(2)); expect(results.docs[0].data()['title'], equals('B')); expect(results.docs[1].data()['title'], equals('C')); @@ -3243,7 +3092,8 @@ void runQueryTests() { results = await collection .where(Filter('value', isGreaterThan: 3)) .orderBy('value', descending: false) - .startAfter([2]).get(); + .startAfter([2]) + .get(); expect(results.docs.length, equals(2)); expect(results.docs[0].data()['title'], equals('D')); expect(results.docs[1].data()['title'], equals('E')); @@ -3264,7 +3114,7 @@ void runQueryTests() { final documentSnapshot = await collection.doc('doc2').get(); -// startAfterDocument + // startAfterDocument results = await collection .where(Filter('value', isGreaterThan: 1)) .orderBy('value', descending: false) @@ -3289,11 +3139,12 @@ void runQueryTests() { QuerySnapshot> results; -// startAt + // startAt results = await collection .where(Filter('value', isGreaterThan: 1)) .orderBy('value', descending: false) - .startAt([2]).get(); + .startAt([2]) + .get(); expect(results.docs.length, equals(4)); expect(results.docs[0].data()['title'], equals('B')); expect(results.docs[1].data()['title'], equals('C')); @@ -3316,7 +3167,7 @@ void runQueryTests() { final documentSnapshot = await collection.doc('doc2').get(); -// startAtDocument + // startAtDocument results = await collection .where(Filter('value', isGreaterThan: 1)) .orderBy('value', descending: false) @@ -3331,252 +3182,228 @@ void runQueryTests() { }); group('withConverter', () { - test( - 'from a query instead of collection', - () async { - final collection = await initializeTest('foo'); - - final query = collection // - .where('value', isGreaterThan: 0) - .withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + test('from a query instead of collection', () async { + final collection = await initializeTest('foo'); - await collection.add({'value': 42}); - await collection.add({'value': -1}); + final query = + collection // + .where('value', isGreaterThan: 0) + .withConverter( + fromFirestore: (snapshots, _) => + snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - final snapshot = query.snapshots(); + await collection.add({'value': 42}); + await collection.add({'value': -1}); - await expectLater( - snapshot, - emits( - isA>().having((e) => e.docs, 'docs', [ - isA>() - .having((e) => e.data(), 'data', 42), - ]), - ), - ); + final snapshot = query.snapshots(); - await collection.add({'value': 21}); + await expectLater( + snapshot, + emits( + isA>().having((e) => e.docs, 'docs', [ + isA>().having((e) => e.data(), 'data', 42), + ]), + ), + ); - await expectLater( - snapshot, - emits( - isA>().having( - (e) => e.docs, - 'docs', - unorderedEquals( - [ - isA>() - .having((e) => e.data(), 'data', 42), - isA>() - .having((e) => e.data(), 'data', 21), - ], + await collection.add({'value': 21}); + + await expectLater( + snapshot, + emits( + isA>().having( + (e) => e.docs, + 'docs', + unorderedEquals([ + isA>().having( + (e) => e.data(), + 'data', + 42, ), - ), + isA>().having( + (e) => e.data(), + 'data', + 21, + ), + ]), ), - ); - }, - timeout: const Timeout.factor(3), - ); + ), + ); + }, timeout: const Timeout.factor(3)); - test( - 'from a Filter query instead of collection', - () async { - final collection = await initializeTest('foo'); - - final query = collection - .where(Filter('value', isGreaterThan: 0)) - .withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + test('from a Filter query instead of collection', () async { + final collection = await initializeTest('foo'); - await collection.add({'value': 42}); - await collection.add({'value': -1}); + final query = collection + .where(Filter('value', isGreaterThan: 0)) + .withConverter( + fromFirestore: (snapshots, _) => + snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - final snapshot = query.snapshots(); + await collection.add({'value': 42}); + await collection.add({'value': -1}); - await expectLater( - snapshot, - emits( - isA>().having((e) => e.docs, 'docs', [ - isA>() - .having((e) => e.data(), 'data', 42), - ]), - ), - ); + final snapshot = query.snapshots(); - await collection.add({'value': 21}); + await expectLater( + snapshot, + emits( + isA>().having((e) => e.docs, 'docs', [ + isA>().having((e) => e.data(), 'data', 42), + ]), + ), + ); - await expectLater( - snapshot, - emits( - isA>().having( - (e) => e.docs, - 'docs', - unorderedEquals( - [ - isA>() - .having((e) => e.data(), 'data', 42), - isA>() - .having((e) => e.data(), 'data', 21), - ], + await collection.add({'value': 21}); + + await expectLater( + snapshot, + emits( + isA>().having( + (e) => e.docs, + 'docs', + unorderedEquals([ + isA>().having( + (e) => e.data(), + 'data', + 42, ), - ), + isA>().having( + (e) => e.data(), + 'data', + 21, + ), + ]), ), - ); - }, - timeout: const Timeout.factor(3), - ); - - test( - 'snapshots', - () async { - final collection = await initializeTest('foo'); - - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + ), + ); + }, timeout: const Timeout.factor(3)); - await converted.add(42); - await converted.add(-1); + test('snapshots', () async { + final collection = await initializeTest('foo'); - final snapshot = - converted.where('value', isGreaterThan: 0).snapshots(); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await expectLater( - snapshot, - emits( - isA>().having((e) => e.docs, 'docs', [ - isA>() - .having((e) => e.data(), 'data', 42), - ]), - ), - ); + await converted.add(42); + await converted.add(-1); - await converted.add(21); + final snapshot = converted.where('value', isGreaterThan: 0).snapshots(); - await expectLater( - snapshot, - emits( - isA>().having( - (e) => e.docs, - 'docs', - unorderedEquals([ - isA>() - .having((e) => e.data(), 'data', 42), - isA>() - .having((e) => e.data(), 'data', 21), - ]), - ), + await expectLater( + snapshot, + emits( + isA>().having((e) => e.docs, 'docs', [ + isA>().having((e) => e.data(), 'data', 42), + ]), + ), + ); + + await converted.add(21); + + await expectLater( + snapshot, + emits( + isA>().having( + (e) => e.docs, + 'docs', + unorderedEquals([ + isA>().having( + (e) => e.data(), + 'data', + 42, + ), + isA>().having( + (e) => e.data(), + 'data', + 21, + ), + ]), ), - ); - }, - timeout: const Timeout.factor(3), - ); + ), + ); + }, timeout: const Timeout.factor(3)); - test( - 'get', - () async { - final collection = await initializeTest('foo'); + test('get', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(42); - await converted.add(-1); + await converted.add(42); + await converted.add(-1); - expect( - await converted - .where('value', isGreaterThan: 0) - .get() - .then((d) => d.docs), - [isA>().having((e) => e.data(), 'data', 42)], - ); - }, - timeout: const Timeout.factor(3), - ); + expect( + await converted + .where('value', isGreaterThan: 0) + .get() + .then((d) => d.docs), + [isA>().having((e) => e.data(), 'data', 42)], + ); + }, timeout: const Timeout.factor(3)); - test( - 'orderBy', - () async { - final collection = await initializeTest('foo'); + test('orderBy', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(42); - await converted.add(21); + await converted.add(42); + await converted.add(21); - expect( - await converted.orderBy('value').get().then((d) => d.docs), - [ - isA>().having((e) => e.data(), 'data', 21), - isA>().having((e) => e.data(), 'data', 42), - ], - ); - }, - timeout: const Timeout.factor(3), - ); + expect(await converted.orderBy('value').get().then((d) => d.docs), [ + isA>().having((e) => e.data(), 'data', 21), + isA>().having((e) => e.data(), 'data', 42), + ]); + }, timeout: const Timeout.factor(3)); - test( - 'limit', - () async { - final collection = await initializeTest('foo'); + test('limit', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(42); - await converted.add(21); + await converted.add(42); + await converted.add(21); - expect( - await converted.orderBy('value').limit(1).get().then((d) => d.docs), - [ - isA>().having((e) => e.data(), 'data', 21), - ], - ); - }, - timeout: const Timeout.factor(3), - ); + expect( + await converted.orderBy('value').limit(1).get().then((d) => d.docs), + [isA>().having((e) => e.data(), 'data', 21)], + ); + }, timeout: const Timeout.factor(3)); - test( - 'limitToLast', - () async { - final collection = await initializeTest('foo'); + test('limitToLast', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(42); - await converted.add(21); + await converted.add(42); + await converted.add(21); - expect( - await converted - .orderBy('value') - .limitToLast(1) - .get() - .then((d) => d.docs), - [ - isA>().having((e) => e.data(), 'data', 42), - ], - ); - }, - timeout: const Timeout.factor(3), - ); + expect( + await converted + .orderBy('value') + .limitToLast(1) + .get() + .then((d) => d.docs), + [isA>().having((e) => e.data(), 'data', 42)], + ); + }, timeout: const Timeout.factor(3)); test('endAt', () async { final collection = await initializeTest('foo'); @@ -3620,34 +3447,30 @@ void runQueryTests() { ); }); - test( - 'endAtDocument', - () async { - final collection = await initializeTest('foo'); + test('endAtDocument', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(1); - final doc2 = await converted.add(2); - await converted.add(3); + await converted.add(1); + final doc2 = await converted.add(2); + await converted.add(3); - expect( - await converted - .orderBy('value') - .endAtDocument(await doc2.get()) - .get() - .then((d) => d.docs), - [ - isA>().having((e) => e.data(), 'data', 1), - isA>().having((e) => e.data(), 'data', 2), - ], - ); - }, - timeout: const Timeout.factor(3), - ); + expect( + await converted + .orderBy('value') + .endAtDocument(await doc2.get()) + .get() + .then((d) => d.docs), + [ + isA>().having((e) => e.data(), 'data', 1), + isA>().having((e) => e.data(), 'data', 2), + ], + ); + }, timeout: const Timeout.factor(3)); test('endBefore', () async { final collection = await initializeTest('foo'); @@ -3693,538 +3516,449 @@ void runQueryTests() { ); }); - test( - 'endBeforeDocument', - () async { - final collection = await initializeTest('foo'); + test('endBeforeDocument', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(1); - final doc2 = await converted.add(2); - await converted.add(3); + await converted.add(1); + final doc2 = await converted.add(2); + await converted.add(3); - expect( - await converted - .orderBy('value') - .endBeforeDocument(await doc2.get()) - .get() - .then((d) => d.docs), - [isA>().having((e) => e.data(), 'data', 1)], - ); - }, - timeout: const Timeout.factor(3), - ); + expect( + await converted + .orderBy('value') + .endBeforeDocument(await doc2.get()) + .get() + .then((d) => d.docs), + [isA>().having((e) => e.data(), 'data', 1)], + ); + }, timeout: const Timeout.factor(3)); - test( - 'startAt', - () async { - final collection = await initializeTest('foo'); + test('startAt', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(1); - await converted.add(2); - await converted.add(3); + await converted.add(1); + await converted.add(2); + await converted.add(3); - expect( - await converted - .orderBy('value') - .startAt([2]) - .get() - .then((d) => d.docs), - [ - isA>().having((e) => e.data(), 'data', 2), - isA>().having((e) => e.data(), 'data', 3), - ], - ); - }, - timeout: const Timeout.factor(3), - ); + expect( + await converted + .orderBy('value') + .startAt([2]) + .get() + .then((d) => d.docs), + [ + isA>().having((e) => e.data(), 'data', 2), + isA>().having((e) => e.data(), 'data', 3), + ], + ); + }, timeout: const Timeout.factor(3)); - test( - 'startAt with Iterable', - () async { - final collection = await initializeTest('foo'); + test('startAt with Iterable', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(1); - await converted.add(2); - await converted.add(3); + await converted.add(1); + await converted.add(2); + await converted.add(3); - expect( - await converted - .orderBy('value') - .startAt({2}) - .get() - .then((d) => d.docs), - [ - isA>().having((e) => e.data(), 'data', 2), - isA>().having((e) => e.data(), 'data', 3), - ], - ); - }, - timeout: const Timeout.factor(3), - ); + expect( + await converted + .orderBy('value') + .startAt({2}) + .get() + .then((d) => d.docs), + [ + isA>().having((e) => e.data(), 'data', 2), + isA>().having((e) => e.data(), 'data', 3), + ], + ); + }, timeout: const Timeout.factor(3)); - test( - 'startAtDocument', - () async { - final collection = await initializeTest('foo'); + test('startAtDocument', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(1); - final doc2 = await converted.add(2); - await converted.add(3); + await converted.add(1); + final doc2 = await converted.add(2); + await converted.add(3); - expect( - await converted - .orderBy('value') - .startAtDocument(await doc2.get()) - .get() - .then((d) => d.docs), - [ - isA>().having((e) => e.data(), 'data', 2), - isA>().having((e) => e.data(), 'data', 3), - ], - ); - }, - timeout: const Timeout.factor(3), - ); + expect( + await converted + .orderBy('value') + .startAtDocument(await doc2.get()) + .get() + .then((d) => d.docs), + [ + isA>().having((e) => e.data(), 'data', 2), + isA>().having((e) => e.data(), 'data', 3), + ], + ); + }, timeout: const Timeout.factor(3)); - test( - 'startAfter', - () async { - final collection = await initializeTest('foo'); + test('startAfter', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(1); - await converted.add(2); - await converted.add(3); + await converted.add(1); + await converted.add(2); + await converted.add(3); - expect( - await converted - .orderBy('value') - .startAfter([2]) - .get() - .then((d) => d.docs), - [isA>().having((e) => e.data(), 'data', 3)], - ); - }, - timeout: const Timeout.factor(3), - ); + expect( + await converted + .orderBy('value') + .startAfter([2]) + .get() + .then((d) => d.docs), + [isA>().having((e) => e.data(), 'data', 3)], + ); + }, timeout: const Timeout.factor(3)); - test( - 'startAfter with Iterable', - () async { - final collection = await initializeTest('foo'); + test('startAfter with Iterable', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(1); - await converted.add(2); - await converted.add(3); + await converted.add(1); + await converted.add(2); + await converted.add(3); - expect( - await converted - .orderBy('value') - .startAfter({2}) - .get() - .then((d) => d.docs), - [isA>().having((e) => e.data(), 'data', 3)], - ); - }, - timeout: const Timeout.factor(3), - ); + expect( + await converted + .orderBy('value') + .startAfter({2}) + .get() + .then((d) => d.docs), + [isA>().having((e) => e.data(), 'data', 3)], + ); + }, timeout: const Timeout.factor(3)); - test( - 'startAfterDocument', - () async { - final collection = await initializeTest('foo'); + test('startAfterDocument', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(1); - final doc2 = await converted.add(2); - await converted.add(3); + await converted.add(1); + final doc2 = await converted.add(2); + await converted.add(3); - expect( - await converted - .orderBy('value') - .startAfterDocument(await doc2.get()) - .get() - .then((d) => d.docs), - [isA>().having((e) => e.data(), 'data', 3)], - ); - }, - timeout: const Timeout.factor(3), - ); + expect( + await converted + .orderBy('value') + .startAfterDocument(await doc2.get()) + .get() + .then((d) => d.docs), + [isA>().having((e) => e.data(), 'data', 3)], + ); + }, timeout: const Timeout.factor(3)); }); group('Aggregate Queries', () { - test( - 'count()', - () async { - final collection = await initializeTest('count'); + test('count()', () async { + final collection = await initializeTest('count'); - await Future.wait([ - collection.add({'foo': 'bar'}), - collection.add({'bar': 'baz'}), - ]); + await Future.wait([ + collection.add({'foo': 'bar'}), + collection.add({'bar': 'baz'}), + ]); - AggregateQuery query = collection.count(); + AggregateQuery query = collection.count(); - AggregateQuerySnapshot snapshot = await query.get(); + AggregateQuerySnapshot snapshot = await query.get(); - expect( - snapshot.count, - 2, - ); - }, - ); + expect(snapshot.count, 2); + }); - test( - 'count() with query', - () async { - final collection = await initializeTest('count'); + test('count() with query', () async { + final collection = await initializeTest('count'); - await Future.wait([ - collection.add({'foo': 'bar'}), - collection.add({'foo': 'baz'}), - ]); + await Future.wait([ + collection.add({'foo': 'bar'}), + collection.add({'foo': 'baz'}), + ]); - AggregateQuery query = - collection.where('foo', isEqualTo: 'bar').count(); + AggregateQuery query = collection + .where('foo', isEqualTo: 'bar') + .count(); - AggregateQuerySnapshot snapshot = await query.get(); + AggregateQuerySnapshot snapshot = await query.get(); - expect( - snapshot.count, - 1, - ); - }, - ); + expect(snapshot.count, 1); + }); - test( - 'sum()', - () async { - final collection = await initializeTest('sum'); + test('sum()', () async { + final collection = await initializeTest('sum'); - await Future.wait([ - collection.add({'foo': 1}), - collection.add({'foo': 2}), - ]); + await Future.wait([ + collection.add({'foo': 1}), + collection.add({'foo': 2}), + ]); - AggregateQuery query = collection.aggregate(sum('foo')); + AggregateQuery query = collection.aggregate(sum('foo')); - AggregateQuerySnapshot snapshot = await query.get(); + AggregateQuerySnapshot snapshot = await query.get(); - expect( - snapshot.getSum('foo'), - 3, - ); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + expect(snapshot.getSum('foo'), 3); + }, skip: defaultTargetPlatform == TargetPlatform.windows); - test( - 'sum() with query', - () async { - final collection = await initializeTest('sum'); + test('sum() with query', () async { + final collection = await initializeTest('sum'); - await Future.wait([ - collection.add({'foo': 1}), - collection.add({'foo': 2}), - ]); + await Future.wait([ + collection.add({'foo': 1}), + collection.add({'foo': 2}), + ]); - AggregateQuery query = - collection.where('foo', isEqualTo: 1).aggregate(sum('foo')); + AggregateQuery query = collection + .where('foo', isEqualTo: 1) + .aggregate(sum('foo')); - AggregateQuerySnapshot snapshot = await query.get(); + AggregateQuerySnapshot snapshot = await query.get(); - expect( - snapshot.getSum('foo'), - 1, - ); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + expect(snapshot.getSum('foo'), 1); + }, skip: defaultTargetPlatform == TargetPlatform.windows); - test( - 'average()', - () async { - final collection = await initializeTest('avg'); + test('average()', () async { + final collection = await initializeTest('avg'); - await Future.wait([ - collection.add({'foo': 1}), - collection.add({'foo': 2}), - ]); + await Future.wait([ + collection.add({'foo': 1}), + collection.add({'foo': 2}), + ]); - AggregateQuery query = collection.aggregate(average('foo')); + AggregateQuery query = collection.aggregate(average('foo')); - AggregateQuerySnapshot snapshot = await query.get(); + AggregateQuerySnapshot snapshot = await query.get(); - expect( - snapshot.getAverage('foo'), - 1.5, - ); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + expect(snapshot.getAverage('foo'), 1.5); + }, skip: defaultTargetPlatform == TargetPlatform.windows); - test( - 'average() with query', - () async { - final collection = await initializeTest('avg'); + test('average() with query', () async { + final collection = await initializeTest('avg'); - await Future.wait([ - collection.add({'foo': 1}), - collection.add({'foo': 2}), - ]); + await Future.wait([ + collection.add({'foo': 1}), + collection.add({'foo': 2}), + ]); - AggregateQuery query = - collection.where('foo', isEqualTo: 1).aggregate(average('foo')); + AggregateQuery query = collection + .where('foo', isEqualTo: 1) + .aggregate(average('foo')); - AggregateQuerySnapshot snapshot = await query.get(); + AggregateQuerySnapshot snapshot = await query.get(); - expect( - snapshot.getAverage('foo'), - 1, - ); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + expect(snapshot.getAverage('foo'), 1); + }, skip: defaultTargetPlatform == TargetPlatform.windows); - test( - 'chaining aggregate queries', - () async { - final collection = await initializeTest('chaining'); + test('chaining aggregate queries', () async { + final collection = await initializeTest('chaining'); - await Future.wait([ - collection.add({'foo': 1}), - collection.add({'foo': 2}), - ]); + await Future.wait([ + collection.add({'foo': 1}), + collection.add({'foo': 2}), + ]); - AggregateQuery query = - collection.aggregate(count(), sum('foo'), average('foo')); - AggregateQuerySnapshot snapshot = await query.get(); + AggregateQuery query = collection.aggregate( + count(), + sum('foo'), + average('foo'), + ); + AggregateQuerySnapshot snapshot = await query.get(); - expect( - snapshot.count, - 2, - ); + expect(snapshot.count, 2); - expect( - snapshot.getSum('foo'), - 3, - ); + expect(snapshot.getSum('foo'), 3); - expect( - snapshot.getAverage('foo'), - 1.5, - ); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + expect(snapshot.getAverage('foo'), 1.5); + }, skip: defaultTargetPlatform == TargetPlatform.windows); - test( - 'chaining multiples aggregate queries', - () async { - final collection = await initializeTest('chaining'); + test('chaining multiples aggregate queries', () async { + final collection = await initializeTest('chaining'); - await Future.wait([ - collection.add({'foo': 1}), - collection.add({'foo': 2}), - ]); + await Future.wait([ + collection.add({'foo': 1}), + collection.add({'foo': 2}), + ]); - AggregateQuery query = collection - .where('foo', isEqualTo: 1) - .aggregate(count(), sum('foo'), average('foo')); + AggregateQuery query = collection + .where('foo', isEqualTo: 1) + .aggregate(count(), sum('foo'), average('foo')); - AggregateQuerySnapshot snapshot = await query.get(); + AggregateQuerySnapshot snapshot = await query.get(); - expect( - snapshot.count, - 1, - ); + expect(snapshot.count, 1); - expect( - snapshot.getSum('foo'), - 1, - ); + expect(snapshot.getSum('foo'), 1); - expect( - snapshot.getAverage('foo'), - 1, - ); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + expect(snapshot.getAverage('foo'), 1); + }, skip: defaultTargetPlatform == TargetPlatform.windows); - test( - 'count() with collectionGroup', - () async { - const subCollection = 'aggregate-group-count'; - final doc1 = FirebaseFirestore.instance - .collection('flutter-tests') - .doc('agg1'); - final doc2 = FirebaseFirestore.instance - .collection('flutter-tests') - .doc('agg2'); - await Future.wait([ - doc1.set({'foo': 'bar'}), - doc2.set({'foo': 'baz'}), - ]); + test('count() with collectionGroup', () async { + const subCollection = 'aggregate-group-count'; + final doc1 = FirebaseFirestore.instance + .collection('flutter-tests') + .doc('agg1'); + final doc2 = FirebaseFirestore.instance + .collection('flutter-tests') + .doc('agg2'); + await Future.wait([ + doc1.set({'foo': 'bar'}), + doc2.set({'foo': 'baz'}), + ]); - final collection = doc1.collection(subCollection); - final collection2 = doc2.collection(subCollection); + final collection = doc1.collection(subCollection); + final collection2 = doc2.collection(subCollection); - await Future.wait([ - // 6 sub-documents - collection.doc('agg1').set({'foo': 'bar'}), - collection.doc('agg2').set({'foo': 'bar'}), - collection.doc('agg3').set({'foo': 'bar'}), - collection2.doc('agg4').set({'foo': 'bar'}), - collection2.doc('agg5').set({'foo': 'bar'}), - collection2.doc('agg6').set({'foo': 'bar'}), - ]); + await Future.wait([ + // 6 sub-documents + collection.doc('agg1').set({'foo': 'bar'}), + collection.doc('agg2').set({'foo': 'bar'}), + collection.doc('agg3').set({'foo': 'bar'}), + collection2.doc('agg4').set({'foo': 'bar'}), + collection2.doc('agg5').set({'foo': 'bar'}), + collection2.doc('agg6').set({'foo': 'bar'}), + ]); - AggregateQuery query = - FirebaseFirestore.instance.collectionGroup(subCollection).count(); + AggregateQuery query = FirebaseFirestore.instance + .collectionGroup(subCollection) + .count(); - AggregateQuerySnapshot snapshot = await query.get(); + AggregateQuerySnapshot snapshot = await query.get(); - expect( - snapshot.count, - 6, - ); - }, - ); + expect(snapshot.count, 6); + }); - test( - 'count(), average() & sum() on empty collection', - () async { - final collection = await initializeTest('empty-collection'); + test('count(), average() & sum() on empty collection', () async { + final collection = await initializeTest('empty-collection'); - final snapshot = await collection - .aggregate(count(), sum('foo'), average('foo')) - .get(); - expect(snapshot.count, 0); - expect(snapshot.getSum('foo'), 0); - expect(snapshot.getAverage('foo'), null); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + final snapshot = await collection + .aggregate(count(), sum('foo'), average('foo')) + .get(); + expect(snapshot.count, 0); + expect(snapshot.getSum('foo'), 0); + expect(snapshot.getAverage('foo'), null); + }, skip: defaultTargetPlatform == TargetPlatform.windows); }); group('startAfterDocument', () { - test('startAfterDocument() accept DocumentReference in query parameters', - () async { - final collection = await initializeTest('start-after-document'); - - final doc1 = collection.doc('1'); - final doc2 = collection.doc('2'); - final doc3 = collection.doc('3'); - final doc4 = collection.doc('4'); - await doc1.set({'ref': doc1}); - await doc2.set({'ref': doc2}); - await doc3.set({'ref': doc3}); - await doc4.set({'ref': null}); - - final q = collection - .where('ref', isNull: false) - .orderBy('ref') - .startAfterDocument(await doc1.get()); - - final res = await q.get(); - expect(res.docs.map((e) => e.reference), [doc2, doc3]); - }); + test( + 'startAfterDocument() accept DocumentReference in query parameters', + () async { + final collection = await initializeTest('start-after-document'); + + final doc1 = collection.doc('1'); + final doc2 = collection.doc('2'); + final doc3 = collection.doc('3'); + final doc4 = collection.doc('4'); + await doc1.set({'ref': doc1}); + await doc2.set({'ref': doc2}); + await doc3.set({'ref': doc3}); + await doc4.set({'ref': null}); + + final q = collection + .where('ref', isNull: false) + .orderBy('ref') + .startAfterDocument(await doc1.get()); + + final res = await q.get(); + expect(res.docs.map((e) => e.reference), [doc2, doc3]); + }, + ); }); group('WhereIn Filter', () { - test('Multiple whereIn filters should not trigger an assertion', - () async { - try { - final collection = await initializeTest('multipe-whereIn-clause'); + test( + 'Multiple whereIn filters should not trigger an assertion', + () async { + try { + final collection = await initializeTest('multipe-whereIn-clause'); - Map data = {}; + Map data = {}; - for (int i = 1; i <= 10; i++) { - data['field$i'] = 'value$i'; - } + for (int i = 1; i <= 10; i++) { + data['field$i'] = 'value$i'; + } - await collection.doc().set(data); + await collection.doc().set(data); - Query> query = collection; - data.forEach((field, values) { - query = query.where(field, whereIn: [values]); - }); + Query> query = collection; + data.forEach((field, values) { + query = query.where(field, whereIn: [values]); + }); - await query.get(); - } on AssertionError catch (e) { - fail('Test failed due to AssertionError: $e'); - } - }); + await query.get(); + } on AssertionError catch (e) { + fail('Test failed due to AssertionError: $e'); + } + }, + ); test( - 'Multiple whereIn filters exceeding DNF 30 clause limit should trigger an assertion', - () async { - try { - final collection = await initializeTest('multipe-whereIn-clause'); - - await collection.doc().set({'genre': 'fiction'}); - await collection.doc().set({'author': 'Author A'}); - - // DNF for this query = 36 (6 genres * 6 authors) exceeding the 30 clause limit - await collection.where( - 'genre', - whereIn: [ - 'fiction', - 'non-fiction', - 'fantasy', - 'science-fiction', - 'mystery', - 'thriller', - ], - ).where( - 'author', - whereIn: [ - 'Author A', - 'Author B', - 'Author C', - 'Author D', - 'Author E', - 'Author F', - ], - ).get(); - } catch (error) { - expect(error, isA()); - } - }); + 'Multiple whereIn filters exceeding DNF 30 clause limit should trigger an assertion', + () async { + try { + final collection = await initializeTest('multipe-whereIn-clause'); + + await collection.doc().set({'genre': 'fiction'}); + await collection.doc().set({'author': 'Author A'}); + + // DNF for this query = 36 (6 genres * 6 authors) exceeding the 30 clause limit + await collection + .where( + 'genre', + whereIn: [ + 'fiction', + 'non-fiction', + 'fantasy', + 'science-fiction', + 'mystery', + 'thriller', + ], + ) + .where( + 'author', + whereIn: [ + 'Author A', + 'Author B', + 'Author C', + 'Author D', + 'Author E', + 'Author F', + ], + ) + .get(); + } catch (error) { + expect(error, isA()); + } + }, + ); }); }); } diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/report_test_results.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/report_test_results.dart index f08ddf1af020..0e4467aeb106 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/report_test_results.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/report_test_results.dart @@ -26,8 +26,9 @@ void reportTestResultsToDriver(IntegrationTestWidgetsFlutterBinding binding) { for (final entry in binding.results.entries) if (entry.value is Failure) entry.key, ]; - bool didFail(String name) => failures - .any((failure) => name == failure || name.endsWith(' $failure')); + bool didFail(String name) => failures.any( + (failure) => name == failure || name.endsWith(' $failure'), + ); binding.reportData ??= {}; binding.reportData!['testResults'] = { diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/second_database.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/second_database.dart index bc8e774c5347..c8b1b792fe98 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/second_database.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/second_database.dart @@ -49,10 +49,10 @@ void runSecondDatabaseTests() { ) async { // Pushed rules which only allow database "flutterfire-2" to have "flutterfire-2" collection writes - CollectionReference> collection = - firestore.collection( - '$collectionForSecondDatabase/${getCurrentPlatform()}/$id', - ); + CollectionReference> collection = firestore + .collection( + '$collectionForSecondDatabase/${getCurrentPlatform()}/$id', + ); QuerySnapshot> snapshot = await collection.get(); List deleteFutures = snapshot.docs.map((documentSnapshot) { @@ -64,28 +64,33 @@ void runSecondDatabaseTests() { } group( - 'queries for default database are banned for this collection: "$collectionForSecondDatabase"', - () { - test('barred query', () async { - final defaultFirestore = FirebaseFirestore.instance; - try { - await defaultFirestore - .collection(collectionForSecondDatabase) - .add({'foo': 'bar'}); - fail('Should have thrown a [FirebaseException]'); - } catch (e) { - expect(e, isA()); - expect((e as FirebaseException).code, equals('permission-denied')); - } - }); - }); + 'queries for default database are banned for this collection: "$collectionForSecondDatabase"', + () { + test('barred query', () async { + final defaultFirestore = FirebaseFirestore.instance; + try { + await defaultFirestore + .collection(collectionForSecondDatabase) + .add({'foo': 'bar'}); + fail('Should have thrown a [FirebaseException]'); + } catch (e) { + expect(e, isA()); + expect( + (e as FirebaseException).code, + equals('permission-denied'), + ); + } + }); + }, + ); group('equality', () { // testing == override using e2e tests as it is dependent on the platform test('handles deeply compares query parameters', () async { final movies = firestore.collection('/movies'); - final starWarsComments = - firestore.collection('/movies/star-wars/comments'); + final starWarsComments = firestore.collection( + '/movies/star-wars/comments', + ); expect( movies.where('genre', arrayContains: ['Flutter']), @@ -108,20 +113,20 @@ void runSecondDatabaseTests() { ); expect( - FirebaseFirestore.instanceFor(app: fooApp) - .collection('movies') - .limit(42), - FirebaseFirestore.instanceFor(app: fooApp) - .collection('movies') - .limit(42), + FirebaseFirestore.instanceFor( + app: fooApp, + ).collection('movies').limit(42), + FirebaseFirestore.instanceFor( + app: fooApp, + ).collection('movies').limit(42), ); expect( firestore.collection('movies').limit(42), isNot( - FirebaseFirestore.instanceFor(app: fooApp) - .collection('movies') - .limit(42), + FirebaseFirestore.instanceFor( + app: fooApp, + ).collection('movies').limit(42), ), ); }); @@ -151,8 +156,9 @@ void runSecondDatabaseTests() { test('uses [GetOptions] cache', () async { CollectionReference> collection = await initializeTest('get'); - QuerySnapshot> qs = - await collection.get(const GetOptions(source: Source.cache)); + QuerySnapshot> qs = await collection.get( + const GetOptions(source: Source.cache), + ); expect(qs, isA>>()); expect(qs.metadata.isFromCache, isTrue); }); @@ -160,8 +166,9 @@ void runSecondDatabaseTests() { test('uses [GetOptions] server', () async { CollectionReference> collection = await initializeTest('get'); - QuerySnapshot> qs = - await collection.get(const GetOptions(source: Source.server)); + QuerySnapshot> qs = await collection.get( + const GetOptions(source: Source.server), + ); expect(qs, isA>>()); expect(qs.metadata.isFromCache, isFalse); }); @@ -196,8 +203,8 @@ void runSecondDatabaseTests() { test('returns a [Stream]', () async { CollectionReference> collection = await initializeTest('get'); - Stream>> stream = - collection.snapshots(); + Stream>> stream = collection + .snapshots(); expect(stream, isA>>>()); }); @@ -205,23 +212,20 @@ void runSecondDatabaseTests() { CollectionReference> collection = await initializeTest('get-single'); await collection.add({'foo': 'bar'}); - Stream>> stream = - collection.snapshots(); + Stream>> stream = collection + .snapshots(); StreamSubscription>>? subscription; subscription = stream.listen( - expectAsync1( - (QuerySnapshot> snapshot) { - expect(snapshot.docs.length, equals(1)); - - expect(snapshot.docs[0], isA()); - QueryDocumentSnapshot> documentSnapshot = - snapshot.docs[0]; - expect(documentSnapshot.data()['foo'], equals('bar')); - }, - reason: 'Stream should only have been called once.', - ), + expectAsync1((QuerySnapshot> snapshot) { + expect(snapshot.docs.length, equals(1)); + + expect(snapshot.docs[0], isA()); + QueryDocumentSnapshot> documentSnapshot = + snapshot.docs[0]; + expect(documentSnapshot.data()['foo'], equals('bar')); + }, reason: 'Stream should only have been called once.'), ); addTearDown(() async { @@ -238,14 +242,12 @@ void runSecondDatabaseTests() { await collection1.add({'test': 'value1'}); await collection2.add({'test': 'value2'}); - final value1 = collection1 - .snapshots() - .first - .then((s) => s.docs.first.data()['test']); - final value2 = collection2 - .snapshots() - .first - .then((s) => s.docs.first.data()['test']); + final value1 = collection1.snapshots().first.then( + (s) => s.docs.first.data()['test'], + ); + final value2 = collection2.snapshots().first.then( + (s) => s.docs.first.data()['test'], + ); await expectLater(value1, completion('value1')); await expectLater(value2, completion('value2')); @@ -256,8 +258,8 @@ void runSecondDatabaseTests() { await initializeTest('get-multiple'); await collection.add({'foo': 'bar'}); - Stream>> stream = - collection.snapshots(); + Stream>> stream = collection + .snapshots(); int call = 0; StreamSubscription subscription = stream.listen( @@ -334,14 +336,17 @@ void runSecondDatabaseTests() { QuerySnapshot> snapshot = await collection .orderBy('bar.value', descending: true) - .endAt([2]).get(); + .endAt([2]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc3')); expect(snapshot.docs[1].id, equals('doc2')); - QuerySnapshot> snapshot2 = - await collection.orderBy('foo').endAt([2]).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy('foo') + .endAt([2]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc1')); @@ -368,14 +373,17 @@ void runSecondDatabaseTests() { QuerySnapshot> snapshot = await collection .orderBy('bar.value', descending: true) - .endAt({2}).get(); + .endAt({2}) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc3')); expect(snapshot.docs[1].id, equals('doc2')); - QuerySnapshot> snapshot2 = - await collection.orderBy('foo').endAt([2]).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy('foo') + .endAt([2]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc1')); @@ -402,7 +410,8 @@ void runSecondDatabaseTests() { QuerySnapshot> snapshot = await collection .orderBy(FieldPath(const ['bar', 'value']), descending: true) - .endAt([2]).get(); + .endAt([2]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc3')); @@ -410,7 +419,8 @@ void runSecondDatabaseTests() { QuerySnapshot> snapshot2 = await collection .orderBy(FieldPath(const ['foo'])) - .endAt([2]).get(); + .endAt([2]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc1')); @@ -464,8 +474,9 @@ void runSecondDatabaseTests() { DocumentSnapshot endAtSnapshot = await collection.doc('doc3').get(); - QuerySnapshot> snapshot = - await collection.endAtDocument(endAtSnapshot).get(); + QuerySnapshot> snapshot = await collection + .endAtDocument(endAtSnapshot) + .get(); expect(snapshot.docs.length, equals(3)); expect(snapshot.docs[0].id, equals('doc1')); @@ -499,14 +510,17 @@ void runSecondDatabaseTests() { QuerySnapshot> snapshot = await collection .orderBy('bar.value', descending: true) - .startAt([2]).get(); + .startAt([2]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); expect(snapshot.docs[1].id, equals('doc1')); - QuerySnapshot> snapshot2 = - await collection.orderBy('foo').startAt([2]).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy('foo') + .startAt([2]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc2')); @@ -533,14 +547,17 @@ void runSecondDatabaseTests() { QuerySnapshot> snapshot = await collection .orderBy('bar.value', descending: true) - .startAt([2]).get(); + .startAt([2]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); expect(snapshot.docs[1].id, equals('doc1')); - QuerySnapshot> snapshot2 = - await collection.orderBy('foo').startAt({2}).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy('foo') + .startAt({2}) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc2')); @@ -567,7 +584,8 @@ void runSecondDatabaseTests() { QuerySnapshot> snapshot = await collection .orderBy(FieldPath(const ['bar', 'value']), descending: true) - .startAt([2]).get(); + .startAt([2]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); @@ -575,7 +593,8 @@ void runSecondDatabaseTests() { QuerySnapshot> snapshot2 = await collection .orderBy(FieldPath(const ['foo'])) - .startAt([2]).get(); + .startAt([2]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc2')); @@ -629,8 +648,9 @@ void runSecondDatabaseTests() { DocumentSnapshot startAtSnapshot = await collection.doc('doc3').get(); - QuerySnapshot> snapshot = - await collection.startAtDocument(startAtSnapshot).get(); + QuerySnapshot> snapshot = await collection + .startAtDocument(startAtSnapshot) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc3')); @@ -663,14 +683,17 @@ void runSecondDatabaseTests() { QuerySnapshot> snapshot = await collection .orderBy('bar.value', descending: true) - .endBefore([1]).get(); + .endBefore([1]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc3')); expect(snapshot.docs[1].id, equals('doc2')); - QuerySnapshot> snapshot2 = - await collection.orderBy('foo').endBefore([3]).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy('foo') + .endBefore([3]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc1')); @@ -697,14 +720,17 @@ void runSecondDatabaseTests() { QuerySnapshot> snapshot = await collection .orderBy('bar.value', descending: true) - .endBefore({1}).get(); + .endBefore({1}) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc3')); expect(snapshot.docs[1].id, equals('doc2')); - QuerySnapshot> snapshot2 = - await collection.orderBy('foo').endBefore([3]).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy('foo') + .endBefore([3]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc1')); @@ -731,7 +757,8 @@ void runSecondDatabaseTests() { QuerySnapshot> snapshot = await collection .orderBy(FieldPath(const ['bar', 'value']), descending: true) - .endBefore([1]).get(); + .endBefore([1]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc3')); @@ -739,40 +766,43 @@ void runSecondDatabaseTests() { QuerySnapshot> snapshot2 = await collection .orderBy(FieldPath(const ['foo'])) - .endBefore([3]).get(); + .endBefore([3]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc1')); expect(snapshot2.docs[1].id, equals('doc2')); }); - test('endbeforeDocument() ends before a document field value', - () async { - CollectionReference> collection = - await initializeTest('endBefore-document-field-value'); - await Future.wait([ - collection.doc('doc1').set({ - 'bar': {'value': 3}, - }), - collection.doc('doc2').set({ - 'bar': {'value': 2}, - }), - collection.doc('doc3').set({ - 'bar': {'value': 1}, - }), - ]); + test( + 'endbeforeDocument() ends before a document field value', + () async { + CollectionReference> collection = + await initializeTest('endBefore-document-field-value'); + await Future.wait([ + collection.doc('doc1').set({ + 'bar': {'value': 3}, + }), + collection.doc('doc2').set({ + 'bar': {'value': 2}, + }), + collection.doc('doc3').set({ + 'bar': {'value': 1}, + }), + ]); - DocumentSnapshot endAtSnapshot = await collection.doc('doc1').get(); + DocumentSnapshot endAtSnapshot = await collection.doc('doc1').get(); - QuerySnapshot> snapshot = await collection - .orderBy('bar.value') - .endBeforeDocument(endAtSnapshot) - .get(); + QuerySnapshot> snapshot = await collection + .orderBy('bar.value') + .endBeforeDocument(endAtSnapshot) + .get(); - expect(snapshot.docs.length, equals(2)); - expect(snapshot.docs[0].id, equals('doc3')); - expect(snapshot.docs[1].id, equals('doc2')); - }); + expect(snapshot.docs.length, equals(2)); + expect(snapshot.docs[0].id, equals('doc3')); + expect(snapshot.docs[1].id, equals('doc2')); + }, + ); test('endBeforeDocument() ends before a document', () async { CollectionReference> collection = @@ -794,8 +824,9 @@ void runSecondDatabaseTests() { DocumentSnapshot endAtSnapshot = await collection.doc('doc4').get(); - QuerySnapshot> snapshot = - await collection.endBeforeDocument(endAtSnapshot).get(); + QuerySnapshot> snapshot = await collection + .endBeforeDocument(endAtSnapshot) + .get(); expect(snapshot.docs.length, equals(3)); expect(snapshot.docs[0].id, equals('doc1')); @@ -828,14 +859,17 @@ void runSecondDatabaseTests() { QuerySnapshot> snapshot = await collection .orderBy('bar.value', descending: true) - .startAfter([3]).get(); + .startAfter([3]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); expect(snapshot.docs[1].id, equals('doc1')); - QuerySnapshot> snapshot2 = - await collection.orderBy('foo').startAfter([1]).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy('foo') + .startAfter([1]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc2')); @@ -862,7 +896,8 @@ void runSecondDatabaseTests() { QuerySnapshot> snapshot = await collection .orderBy(FieldPath(const ['bar', 'value']), descending: true) - .startAfter([3]).get(); + .startAfter([3]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); @@ -870,41 +905,45 @@ void runSecondDatabaseTests() { QuerySnapshot> snapshot2 = await collection .orderBy(FieldPath(const ['foo'])) - .startAfter([1]).get(); + .startAfter([1]) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc2')); expect(snapshot2.docs[1].id, equals('doc3')); }); - test('startAfterDocument() starts after a document field value', - () async { - CollectionReference> collection = - await initializeTest('startAfter-document-field-value'); - await Future.wait([ - collection.doc('doc1').set({ - 'bar': {'value': 3}, - }), - collection.doc('doc2').set({ - 'bar': {'value': 2}, - }), - collection.doc('doc3').set({ - 'bar': {'value': 1}, - }), - ]); + test( + 'startAfterDocument() starts after a document field value', + () async { + CollectionReference> collection = + await initializeTest('startAfter-document-field-value'); + await Future.wait([ + collection.doc('doc1').set({ + 'bar': {'value': 3}, + }), + collection.doc('doc2').set({ + 'bar': {'value': 2}, + }), + collection.doc('doc3').set({ + 'bar': {'value': 1}, + }), + ]); - DocumentSnapshot startAfterSnapshot = - await collection.doc('doc3').get(); + DocumentSnapshot startAfterSnapshot = await collection + .doc('doc3') + .get(); - QuerySnapshot> snapshot = await collection - .orderBy('bar.value') - .startAfterDocument(startAfterSnapshot) - .get(); + QuerySnapshot> snapshot = await collection + .orderBy('bar.value') + .startAfterDocument(startAfterSnapshot) + .get(); - expect(snapshot.docs.length, equals(2)); - expect(snapshot.docs[0].id, equals('doc2')); - expect(snapshot.docs[1].id, equals('doc1')); - }); + expect(snapshot.docs.length, equals(2)); + expect(snapshot.docs[0].id, equals('doc2')); + expect(snapshot.docs[1].id, equals('doc1')); + }, + ); test('startAfterDocument() starts after a document', () async { CollectionReference> collection = @@ -926,8 +965,9 @@ void runSecondDatabaseTests() { DocumentSnapshot startAtSnapshot = await collection.doc('doc2').get(); - QuerySnapshot> snapshot = - await collection.startAfterDocument(startAtSnapshot).get(); + QuerySnapshot> snapshot = await collection + .startAfterDocument(startAtSnapshot) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc3')); @@ -944,22 +984,17 @@ void runSecondDatabaseTests() { CollectionReference> collection = await initializeTest('start-end-string'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 1, - }), - collection.doc('doc2').set({ - 'foo': 2, - }), - collection.doc('doc3').set({ - 'foo': 3, - }), - collection.doc('doc4').set({ - 'foo': 4, - }), + collection.doc('doc1').set({'foo': 1}), + collection.doc('doc2').set({'foo': 2}), + collection.doc('doc3').set({'foo': 3}), + collection.doc('doc4').set({'foo': 4}), ]); - QuerySnapshot> snapshot = - await collection.orderBy('foo').startAt([2]).endAt([3]).get(); + QuerySnapshot> snapshot = await collection + .orderBy('foo') + .startAt([2]) + .endAt([3]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); @@ -970,22 +1005,17 @@ void runSecondDatabaseTests() { CollectionReference> collection = await initializeTest('start-end-string'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 1, - }), - collection.doc('doc2').set({ - 'foo': 2, - }), - collection.doc('doc3').set({ - 'foo': 3, - }), - collection.doc('doc4').set({ - 'foo': 4, - }), + collection.doc('doc1').set({'foo': 1}), + collection.doc('doc2').set({'foo': 2}), + collection.doc('doc3').set({'foo': 3}), + collection.doc('doc4').set({'foo': 4}), ]); - QuerySnapshot> snapshot = - await collection.orderBy('foo').startAt([2]).endBefore([4]).get(); + QuerySnapshot> snapshot = await collection + .orderBy('foo') + .startAt([2]) + .endBefore([4]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); @@ -996,22 +1026,17 @@ void runSecondDatabaseTests() { CollectionReference> collection = await initializeTest('start-end-field-path'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 1, - }), - collection.doc('doc2').set({ - 'foo': 2, - }), - collection.doc('doc3').set({ - 'foo': 3, - }), - collection.doc('doc4').set({ - 'foo': 4, - }), + collection.doc('doc1').set({'foo': 1}), + collection.doc('doc2').set({'foo': 2}), + collection.doc('doc3').set({'foo': 3}), + collection.doc('doc4').set({'foo': 4}), ]); - QuerySnapshot> snapshot = - await collection.orderBy('foo').startAfter([1]).endAt([3]).get(); + QuerySnapshot> snapshot = await collection + .orderBy('foo') + .startAfter([1]) + .endAt([3]) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); @@ -1022,23 +1047,16 @@ void runSecondDatabaseTests() { CollectionReference> collection = await initializeTest('start-end-document'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 1, - }), - collection.doc('doc2').set({ - 'foo': 2, - }), - collection.doc('doc3').set({ - 'foo': 3, - }), - collection.doc('doc4').set({ - 'foo': 4, - }), + collection.doc('doc1').set({'foo': 1}), + collection.doc('doc2').set({'foo': 2}), + collection.doc('doc3').set({'foo': 3}), + collection.doc('doc4').set({'foo': 4}), ]); DocumentSnapshot startAtSnapshot = await collection.doc('doc2').get(); - DocumentSnapshot endBeforeSnapshot = - await collection.doc('doc4').get(); + DocumentSnapshot endBeforeSnapshot = await collection + .doc('doc4') + .get(); QuerySnapshot> snapshot = await collection .startAtDocument(startAtSnapshot) @@ -1060,26 +1078,23 @@ void runSecondDatabaseTests() { CollectionReference> collection = await initializeTest('limit'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 1, - }), - collection.doc('doc2').set({ - 'foo': 2, - }), - collection.doc('doc3').set({ - 'foo': 3, - }), + collection.doc('doc1').set({'foo': 1}), + collection.doc('doc2').set({'foo': 2}), + collection.doc('doc3').set({'foo': 3}), ]); - QuerySnapshot> snapshot = - await collection.limit(2).get(); + QuerySnapshot> snapshot = await collection + .limit(2) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc1')); expect(snapshot.docs[1].id, equals('doc2')); - QuerySnapshot> snapshot2 = - await collection.orderBy('foo', descending: true).limit(2).get(); + QuerySnapshot> snapshot2 = await collection + .orderBy('foo', descending: true) + .limit(2) + .get(); expect(snapshot2.docs.length, equals(2)); expect(snapshot2.docs[0].id, equals('doc3')); @@ -1090,19 +1105,15 @@ void runSecondDatabaseTests() { CollectionReference> collection = await initializeTest('limitToLast'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 1, - }), - collection.doc('doc2').set({ - 'foo': 2, - }), - collection.doc('doc3').set({ - 'foo': 3, - }), + collection.doc('doc1').set({'foo': 1}), + collection.doc('doc2').set({'foo': 2}), + collection.doc('doc3').set({'foo': 3}), ]); - QuerySnapshot> snapshot = - await collection.orderBy('foo').limitToLast(2).get(); + QuerySnapshot> snapshot = await collection + .orderBy('foo') + .limitToLast(2) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].id, equals('doc2')); @@ -1128,18 +1139,10 @@ void runSecondDatabaseTests() { await initializeTest('order-document-id'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 1, - }), - collection.doc('doc2').set({ - 'foo': 1, - }), - collection.doc('doc3').set({ - 'foo': 1, - }), - collection.doc('doc4').set({ - 'bar': 1, - }), + collection.doc('doc1').set({'foo': 1}), + collection.doc('doc2').set({'foo': 1}), + collection.doc('doc3').set({'foo': 1}), + collection.doc('doc4').set({'bar': 1}), ]); QuerySnapshot> snapshot = await collection @@ -1158,19 +1161,14 @@ void runSecondDatabaseTests() { await initializeTest('order-asc'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 3, - }), - collection.doc('doc2').set({ - 'foo': 2, - }), - collection.doc('doc3').set({ - 'foo': 1, - }), + collection.doc('doc1').set({'foo': 3}), + collection.doc('doc2').set({'foo': 2}), + collection.doc('doc3').set({'foo': 1}), ]); - QuerySnapshot> snapshot = - await collection.orderBy('foo').get(); + QuerySnapshot> snapshot = await collection + .orderBy('foo') + .get(); expect(snapshot.docs.length, equals(3)); expect(snapshot.docs[0].id, equals('doc3')); @@ -1182,19 +1180,14 @@ void runSecondDatabaseTests() { CollectionReference> collection = await initializeTest('order-desc'); await Future.wait([ - collection.doc('doc1').set({ - 'foo': 1, - }), - collection.doc('doc2').set({ - 'foo': 2, - }), - collection.doc('doc3').set({ - 'foo': 3, - }), + collection.doc('doc1').set({'foo': 1}), + collection.doc('doc2').set({'foo': 2}), + collection.doc('doc3').set({'foo': 3}), ]); - QuerySnapshot> snapshot = - await collection.orderBy('foo', descending: true).get(); + QuerySnapshot> snapshot = await collection + .orderBy('foo', descending: true) + .get(); expect(snapshot.docs.length, equals(3)); expect(snapshot.docs[0].id, equals('doc3')); @@ -1208,53 +1201,46 @@ void runSecondDatabaseTests() { */ group('Query.where()', () { - test('returns documents when querying for properties that are not null', - () async { - CollectionReference> collection = - await initializeTest('not-null'); - await Future.wait([ - collection.doc('doc1').set({ - 'foo': 'bar', - }), - collection.doc('doc2').set({ - 'foo': 'bar', - }), - collection.doc('doc3').set({ - 'foo': null, - }), - ]); + test( + 'returns documents when querying for properties that are not null', + () async { + CollectionReference> collection = + await initializeTest('not-null'); + await Future.wait([ + collection.doc('doc1').set({'foo': 'bar'}), + collection.doc('doc2').set({'foo': 'bar'}), + collection.doc('doc3').set({'foo': null}), + ]); - QuerySnapshot> snapshot = - await collection.where('foo', isNull: false).get(); + QuerySnapshot> snapshot = await collection + .where('foo', isNull: false) + .get(); - expect(snapshot.docs.length, equals(2)); - expect(snapshot.docs[0].id, equals('doc1')); - expect(snapshot.docs[1].id, equals('doc2')); - }); + expect(snapshot.docs.length, equals(2)); + expect(snapshot.docs[0].id, equals('doc1')); + expect(snapshot.docs[1].id, equals('doc2')); + }, + ); test( - 'returns documents when querying properties that are equal to null', - () async { - CollectionReference> collection = - await initializeTest('not-null'); - await Future.wait([ - collection.doc('doc1').set({ - 'foo': 'bar', - }), - collection.doc('doc2').set({ - 'foo': 'bar', - }), - collection.doc('doc3').set({ - 'foo': null, - }), - ]); + 'returns documents when querying properties that are equal to null', + () async { + CollectionReference> collection = + await initializeTest('not-null'); + await Future.wait([ + collection.doc('doc1').set({'foo': 'bar'}), + collection.doc('doc2').set({'foo': 'bar'}), + collection.doc('doc3').set({'foo': null}), + ]); - QuerySnapshot> snapshot = - await collection.where('foo', isNull: true).get(); + QuerySnapshot> snapshot = await collection + .where('foo', isNull: true) + .get(); - expect(snapshot.docs.length, equals(1)); - expect(snapshot.docs[0].id, equals('doc3')); - }); + expect(snapshot.docs.length, equals(1)); + expect(snapshot.docs[0].id, equals('doc3')); + }, + ); test('returns with equal checks', () async { CollectionReference> collection = @@ -1262,19 +1248,14 @@ void runSecondDatabaseTests() { int rand = Random().nextInt(9999); await Future.wait([ - collection.doc('doc1').set({ - 'foo': rand, - }), - collection.doc('doc2').set({ - 'foo': rand, - }), - collection.doc('doc3').set({ - 'foo': rand + 1, - }), + collection.doc('doc1').set({'foo': rand}), + collection.doc('doc2').set({'foo': rand}), + collection.doc('doc3').set({'foo': rand + 1}), ]); - QuerySnapshot> snapshot = - await collection.where('foo', isEqualTo: rand).get(); + QuerySnapshot> snapshot = await collection + .where('foo', isEqualTo: rand) + .get(); expect(snapshot.docs.length, equals(2)); snapshot.docs.forEach((doc) { @@ -1288,19 +1269,14 @@ void runSecondDatabaseTests() { int rand = Random().nextInt(9999); await Future.wait([ - collection.doc('doc1').set({ - 'foo': rand, - }), - collection.doc('doc2').set({ - 'foo': rand, - }), - collection.doc('doc3').set({ - 'foo': rand + 1, - }), + collection.doc('doc1').set({'foo': rand}), + collection.doc('doc2').set({'foo': rand}), + collection.doc('doc3').set({'foo': rand + 1}), ]); - QuerySnapshot> snapshot = - await collection.where('foo', isNotEqualTo: rand).get(); + QuerySnapshot> snapshot = await collection + .where('foo', isNotEqualTo: rand) + .get(); expect(snapshot.docs.length, equals(1)); snapshot.docs.forEach((doc) { @@ -1314,22 +1290,15 @@ void runSecondDatabaseTests() { int rand = Random().nextInt(9999); await Future.wait([ - collection.doc('doc1').set({ - 'foo': rand - 1, - }), - collection.doc('doc2').set({ - 'foo': rand, - }), - collection.doc('doc3').set({ - 'foo': rand + 1, - }), - collection.doc('doc4').set({ - 'foo': rand + 2, - }), + collection.doc('doc1').set({'foo': rand - 1}), + collection.doc('doc2').set({'foo': rand}), + collection.doc('doc3').set({'foo': rand + 1}), + collection.doc('doc4').set({'foo': rand + 2}), ]); - QuerySnapshot> snapshot = - await collection.where('foo', isGreaterThan: rand).get(); + QuerySnapshot> snapshot = await collection + .where('foo', isGreaterThan: rand) + .get(); expect(snapshot.docs.length, equals(2)); snapshot.docs.forEach((doc) { @@ -1343,22 +1312,15 @@ void runSecondDatabaseTests() { int rand = Random().nextInt(9999); await Future.wait([ - collection.doc('doc1').set({ - 'foo': rand - 1, - }), - collection.doc('doc2').set({ - 'foo': rand, - }), - collection.doc('doc3').set({ - 'foo': rand + 1, - }), - collection.doc('doc4').set({ - 'foo': rand + 2, - }), + collection.doc('doc1').set({'foo': rand - 1}), + collection.doc('doc2').set({'foo': rand}), + collection.doc('doc3').set({'foo': rand + 1}), + collection.doc('doc4').set({'foo': rand + 2}), ]); - QuerySnapshot> snapshot = - await collection.where('foo', isGreaterThanOrEqualTo: rand).get(); + QuerySnapshot> snapshot = await collection + .where('foo', isGreaterThanOrEqualTo: rand) + .get(); expect(snapshot.docs.length, equals(3)); snapshot.docs.forEach((doc) { @@ -1372,19 +1334,14 @@ void runSecondDatabaseTests() { int rand = Random().nextInt(9999); await Future.wait([ - collection.doc('doc1').set({ - 'foo': -rand + 1, - }), - collection.doc('doc2').set({ - 'foo': -rand + 2, - }), - collection.doc('doc3').set({ - 'foo': rand, - }), + collection.doc('doc1').set({'foo': -rand + 1}), + collection.doc('doc2').set({'foo': -rand + 2}), + collection.doc('doc3').set({'foo': rand}), ]); - QuerySnapshot> snapshot = - await collection.where('foo', isLessThan: rand).get(); + QuerySnapshot> snapshot = await collection + .where('foo', isLessThan: rand) + .get(); expect(snapshot.docs.length, equals(2)); snapshot.docs.forEach((doc) { @@ -1398,22 +1355,15 @@ void runSecondDatabaseTests() { int rand = Random().nextInt(9999); await Future.wait([ - collection.doc('doc1').set({ - 'foo': -rand + 1, - }), - collection.doc('doc2').set({ - 'foo': -rand + 2, - }), - collection.doc('doc3').set({ - 'foo': rand, - }), - collection.doc('doc4').set({ - 'foo': rand + 1, - }), + collection.doc('doc1').set({'foo': -rand + 1}), + collection.doc('doc2').set({'foo': -rand + 2}), + collection.doc('doc3').set({'foo': rand}), + collection.doc('doc4').set({'foo': rand + 1}), ]); - QuerySnapshot> snapshot = - await collection.where('foo', isLessThanOrEqualTo: rand).get(); + QuerySnapshot> snapshot = await collection + .where('foo', isLessThanOrEqualTo: rand) + .get(); expect(snapshot.docs.length, equals(3)); snapshot.docs.forEach((doc) { @@ -1438,8 +1388,9 @@ void runSecondDatabaseTests() { }), ]); - QuerySnapshot> snapshot = - await collection.where('foo', arrayContains: '$rand').get(); + QuerySnapshot> snapshot = await collection + .where('foo', arrayContains: '$rand') + .get(); expect(snapshot.docs.length, equals(2)); snapshot.docs.forEach((doc) { @@ -1452,22 +1403,15 @@ void runSecondDatabaseTests() { await initializeTest('where-in'); await Future.wait([ - collection.doc('doc1').set({ - 'status': 'Ordered', - }), - collection.doc('doc2').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc3').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc4').set({ - 'status': 'Incomplete', - }), + collection.doc('doc1').set({'status': 'Ordered'}), + collection.doc('doc2').set({'status': 'Ready to Ship'}), + collection.doc('doc3').set({'status': 'Ready to Ship'}), + collection.doc('doc4').set({'status': 'Incomplete'}), ]); QuerySnapshot> snapshot = await collection - .where('status', whereIn: ['Ready to Ship', 'Ordered']).get(); + .where('status', whereIn: ['Ready to Ship', 'Ordered']) + .get(); expect(snapshot.docs.length, equals(3)); snapshot.docs.forEach((doc) { @@ -1481,18 +1425,10 @@ void runSecondDatabaseTests() { await initializeTest('where-in-iterable'); await Future.wait([ - collection.doc('doc1').set({ - 'status': 'Ordered', - }), - collection.doc('doc2').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc3').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc4').set({ - 'status': 'Incomplete', - }), + collection.doc('doc1').set({'status': 'Ordered'}), + collection.doc('doc2').set({'status': 'Ready to Ship'}), + collection.doc('doc3').set({'status': 'Ready to Ship'}), + collection.doc('doc4').set({'status': 'Incomplete'}), ]); QuerySnapshot> snapshot = await collection @@ -1515,22 +1451,15 @@ void runSecondDatabaseTests() { await initializeTest('where-in'); await Future.wait([ - collection.doc('doc1').set({ - 'status': 'Ordered', - }), - collection.doc('doc2').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc3').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc4').set({ - 'status': 'Incomplete', - }), + collection.doc('doc1').set({'status': 'Ordered'}), + collection.doc('doc2').set({'status': 'Ready to Ship'}), + collection.doc('doc3').set({'status': 'Ready to Ship'}), + collection.doc('doc4').set({'status': 'Incomplete'}), ]); QuerySnapshot> snapshot = await collection - .where('status', whereIn: {'Ready to Ship', 'Ordered'}).get(); + .where('status', whereIn: {'Ready to Ship', 'Ordered'}) + .get(); expect(snapshot.docs.length, equals(3)); snapshot.docs.forEach((doc) { @@ -1544,22 +1473,15 @@ void runSecondDatabaseTests() { await initializeTest('where-not-in'); await Future.wait([ - collection.doc('doc1').set({ - 'status': 'Ordered', - }), - collection.doc('doc2').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc3').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc4').set({ - 'status': 'Incomplete', - }), + collection.doc('doc1').set({'status': 'Ordered'}), + collection.doc('doc2').set({'status': 'Ready to Ship'}), + collection.doc('doc3').set({'status': 'Ready to Ship'}), + collection.doc('doc4').set({'status': 'Incomplete'}), ]); QuerySnapshot> snapshot = await collection - .where('status', whereNotIn: ['Ready to Ship', 'Ordered']).get(); + .where('status', whereNotIn: ['Ready to Ship', 'Ordered']) + .get(); expect(snapshot.docs.length, equals(1)); snapshot.docs.forEach((doc) { @@ -1573,22 +1495,15 @@ void runSecondDatabaseTests() { await initializeTest('where-not-in'); await Future.wait([ - collection.doc('doc1').set({ - 'status': 'Ordered', - }), - collection.doc('doc2').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc3').set({ - 'status': 'Ready to Ship', - }), - collection.doc('doc4').set({ - 'status': 'Incomplete', - }), + collection.doc('doc1').set({'status': 'Ordered'}), + collection.doc('doc2').set({'status': 'Ready to Ship'}), + collection.doc('doc3').set({'status': 'Ready to Ship'}), + collection.doc('doc4').set({'status': 'Incomplete'}), ]); QuerySnapshot> snapshot = await collection - .where('status', whereNotIn: {'Ready to Ship', 'Ordered'}).get(); + .where('status', whereNotIn: {'Ready to Ship', 'Ordered'}) + .get(); expect(snapshot.docs.length, equals(1)); snapshot.docs.forEach((doc) { @@ -1616,10 +1531,12 @@ void runSecondDatabaseTests() { }), ]); - QuerySnapshot> snapshot = await collection.where( - 'category', - arrayContainsAny: ['Appliances', 'Electronics'], - ).get(); + QuerySnapshot> snapshot = await collection + .where( + 'category', + arrayContainsAny: ['Appliances', 'Electronics'], + ) + .get(); // 2nd record should only be returned once expect(snapshot.docs.length, equals(3)); @@ -1644,10 +1561,12 @@ void runSecondDatabaseTests() { }), ]); - QuerySnapshot> snapshot = await collection.where( - 'category', - arrayContainsAny: {'Appliances', 'Electronics'}, - ).get(); + QuerySnapshot> snapshot = await collection + .where( + 'category', + arrayContainsAny: {'Appliances', 'Electronics'}, + ) + .get(); // 2nd record should only be returned once expect(snapshot.docs.length, equals(3)); @@ -1659,30 +1578,27 @@ void runSecondDatabaseTests() { CollectionReference> collection = await initializeTest('where-field-path'); - FieldPath fieldPath = - FieldPath(const ['nested', 'foo.bar@gmail.com']); + FieldPath fieldPath = FieldPath(const [ + 'nested', + 'foo.bar@gmail.com', + ]); await Future.wait([ collection.doc('doc1').set({ - 'nested': { - 'foo.bar@gmail.com': true, - }, + 'nested': {'foo.bar@gmail.com': true}, }), collection.doc('doc2').set({ - 'nested': { - 'foo.bar@gmail.com': true, - }, + 'nested': {'foo.bar@gmail.com': true}, 'foo': 'bar', }), collection.doc('doc3').set({ - 'nested': { - 'foo.bar@gmail.com': false, - }, + 'nested': {'foo.bar@gmail.com': false}, }), ]); - QuerySnapshot> snapshot = - await collection.where(fieldPath, isEqualTo: true).get(); + QuerySnapshot> snapshot = await collection + .where(fieldPath, isEqualTo: true) + .get(); expect(snapshot.docs.length, equals(2)); expect(snapshot.docs[0].get(fieldPath), isTrue); @@ -1694,15 +1610,12 @@ void runSecondDatabaseTests() { CollectionReference> collection = await initializeTest('where-field-path-document-id'); - DocumentReference> docRef = - await collection.add({ - 'foo': 'bar', - }); + DocumentReference> docRef = await collection.add( + {'foo': 'bar'}, + ); // Add secondary document for sanity check - await collection.add({ - 'bar': 'baz', - }); + await collection.add({'bar': 'baz'}); QuerySnapshot> snapshot = await collection .where(FieldPath.documentId, isEqualTo: docRef.id) @@ -1716,19 +1629,14 @@ void runSecondDatabaseTests() { CollectionReference> collection = await initializeTest('where-document-reference'); - DocumentReference> ref = - firestore.doc('foo/bar'); + DocumentReference> ref = firestore.doc( + 'foo/bar', + ); await Future.wait([ - collection.add({ - 'foo': ref, - }), - collection.add({ - 'foo': firestore.doc('bar/baz'), - }), - collection.add({ - 'foo': 'foo/bar', - }), + collection.add({'foo': ref}), + collection.add({'foo': firestore.doc('bar/baz')}), + collection.add({'foo': 'foo/bar'}), ]); QuerySnapshot> snapshot = await collection @@ -1751,9 +1659,7 @@ void runSecondDatabaseTests() { ]); final results = await collection - .where( - Filter('value', isEqualTo: 5), - ) + .where(Filter('value', isEqualTo: 5)) .get(); expect(results.docs.length, equals(2)); @@ -1771,9 +1677,7 @@ void runSecondDatabaseTests() { ]); final results = await collection - .where( - Filter('value', isNotEqualTo: 5), - ) + .where(Filter('value', isNotEqualTo: 5)) .get(); expect(results.docs.length, equals(1)); @@ -1790,9 +1694,7 @@ void runSecondDatabaseTests() { ]); final results = await collection - .where( - Filter('value', isLessThan: 7), - ) + .where(Filter('value', isLessThan: 7)) .get(); expect(results.docs.length, equals(1)); @@ -1809,9 +1711,7 @@ void runSecondDatabaseTests() { ]); final results = await collection - .where( - Filter('value', isLessThanOrEqualTo: 7), - ) + .where(Filter('value', isLessThanOrEqualTo: 7)) .get(); expect(results.docs.length, equals(2)); @@ -1829,9 +1729,7 @@ void runSecondDatabaseTests() { ]); final results = await collection - .where( - Filter('value', isGreaterThan: 5), - ) + .where(Filter('value', isGreaterThan: 5)) .get(); expect(results.docs.length, equals(2)); @@ -1849,9 +1747,7 @@ void runSecondDatabaseTests() { ]); final results = await collection - .where( - Filter('value', isGreaterThanOrEqualTo: 7), - ) + .where(Filter('value', isGreaterThanOrEqualTo: 7)) .get(); expect(results.docs.length, equals(2)); @@ -1875,9 +1771,7 @@ void runSecondDatabaseTests() { ]); final results = await collection - .where( - Filter('value', arrayContains: 1), - ) + .where(Filter('value', arrayContains: 1)) .get(); expect(results.docs.length, equals(2)); @@ -1901,9 +1795,7 @@ void runSecondDatabaseTests() { ]); final results = await collection - .where( - Filter('value', arrayContainsAny: [1, 7]), - ) + .where(Filter('value', arrayContainsAny: [1, 7])) .get(); expect(results.docs.length, equals(3)); @@ -1919,9 +1811,7 @@ void runSecondDatabaseTests() { ]); final results = await collection - .where( - Filter('value', whereIn: ['A', 'C']), - ) + .where(Filter('value', whereIn: ['A', 'C'])) .get(); expect(results.docs.length, equals(2)); @@ -1939,9 +1829,7 @@ void runSecondDatabaseTests() { ]); final results = await collection - .where( - Filter('value', whereNotIn: ['A', 'C']), - ) + .where(Filter('value', whereNotIn: ['A', 'C'])) .get(); expect(results.docs.length, equals(1)); @@ -1958,9 +1846,7 @@ void runSecondDatabaseTests() { ]); final results = await collection - .where( - Filter('value', isNull: true), - ) + .where(Filter('value', isNull: true)) .get(); expect(results.docs.length, equals(1)); @@ -1983,7 +1869,8 @@ void runSecondDatabaseTests() { results = await collection .where(Filter('value', isGreaterThan: 1)) .orderBy('value', descending: false) - .endAt([3]).get(); + .endAt([3]) + .get(); expect(results.docs.length, equals(2)); expect(results.docs[0].data()['title'], equals('B')); expect(results.docs[1].data()['title'], equals('C')); @@ -2006,7 +1893,8 @@ void runSecondDatabaseTests() { results = await collection .where(Filter('value', isGreaterThan: 1)) .orderBy('value', descending: false) - .endBefore([4]).get(); + .endBefore([4]) + .get(); expect(results.docs.length, equals(2)); expect(results.docs[0].data()['title'], equals('B')); expect(results.docs[1].data()['title'], equals('C')); @@ -2128,7 +2016,8 @@ void runSecondDatabaseTests() { results = await collection .where(Filter('value', isGreaterThan: 3)) .orderBy('value', descending: false) - .startAfter([2]).get(); + .startAfter([2]) + .get(); expect(results.docs.length, equals(2)); expect(results.docs[0].data()['title'], equals('D')); expect(results.docs[1].data()['title'], equals('E')); @@ -2149,7 +2038,7 @@ void runSecondDatabaseTests() { final documentSnapshot = await collection.doc('doc2').get(); -// startAfterDocument + // startAfterDocument results = await collection .where(Filter('value', isGreaterThan: 1)) .orderBy('value', descending: false) @@ -2174,11 +2063,12 @@ void runSecondDatabaseTests() { QuerySnapshot> results; -// startAt + // startAt results = await collection .where(Filter('value', isGreaterThan: 1)) .orderBy('value', descending: false) - .startAt([2]).get(); + .startAt([2]) + .get(); expect(results.docs.length, equals(4)); expect(results.docs[0].data()['title'], equals('B')); expect(results.docs[1].data()['title'], equals('C')); @@ -2201,7 +2091,7 @@ void runSecondDatabaseTests() { final documentSnapshot = await collection.doc('doc2').get(); -// startAtDocument + // startAtDocument results = await collection .where(Filter('value', isGreaterThan: 1)) .orderBy('value', descending: false) @@ -2216,268 +2106,243 @@ void runSecondDatabaseTests() { }); group('withConverter', () { - test( - 'from a query instead of collection', - () async { - final collection = await initializeTest('foo'); + test('from a query instead of collection', () async { + final collection = await initializeTest('foo'); - final query = collection // - .where('value', isGreaterThan: 0) - .withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); - - await collection.add({'value': 42}); - await collection.add({'value': -1}); - - final snapshot = query.snapshots(); - - await expectLater( - snapshot, - emits( - isA>().having((e) => e.docs, 'docs', [ - isA>() - .having((e) => e.data(), 'data', 42), - ]), - ), - ); + final query = + collection // + .where('value', isGreaterThan: 0) + .withConverter( + fromFirestore: (snapshots, _) => + snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await collection.add({'value': 21}); - - await expectLater( - snapshot, - emits( - isA>().having( - (e) => e.docs, - 'docs', - unorderedEquals( - [ - isA>() - .having((e) => e.data(), 'data', 42), - isA>() - .having((e) => e.data(), 'data', 21), - ], - ), + await collection.add({'value': 42}); + await collection.add({'value': -1}); + + final snapshot = query.snapshots(); + + await expectLater( + snapshot, + emits( + isA>().having((e) => e.docs, 'docs', [ + isA>().having( + (e) => e.data(), + 'data', + 42, ), - ), - ); - }, - timeout: const Timeout.factor(3), - ); + ]), + ), + ); - test( - 'from a Filter query instead of collection', - () async { - final collection = await initializeTest('foo'); - - final query = collection // - .where(Filter('value', isGreaterThan: 0)) - .withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); - - await collection.add({'value': 42}); - await collection.add({'value': -1}); - - final snapshot = query.snapshots(); - - await expectLater( - snapshot, - emits( - isA>().having((e) => e.docs, 'docs', [ - isA>() - .having((e) => e.data(), 'data', 42), + await collection.add({'value': 21}); + + await expectLater( + snapshot, + emits( + isA>().having( + (e) => e.docs, + 'docs', + unorderedEquals([ + isA>().having( + (e) => e.data(), + 'data', + 42, + ), + isA>().having( + (e) => e.data(), + 'data', + 21, + ), ]), ), - ); + ), + ); + }, timeout: const Timeout.factor(3)); - await collection.add({'value': 21}); - - await expectLater( - snapshot, - emits( - isA>().having( - (e) => e.docs, - 'docs', - unorderedEquals( - [ - isA>() - .having((e) => e.data(), 'data', 42), - isA>() - .having((e) => e.data(), 'data', 21), - ], - ), - ), - ), - ); - }, - timeout: const Timeout.factor(3), - ); + test('from a Filter query instead of collection', () async { + final collection = await initializeTest('foo'); - test( - 'snapshots', - () async { - final collection = await initializeTest('foo'); + final query = + collection // + .where(Filter('value', isGreaterThan: 0)) + .withConverter( + fromFirestore: (snapshots, _) => + snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + await collection.add({'value': 42}); + await collection.add({'value': -1}); - await converted.add(42); - await converted.add(-1); + final snapshot = query.snapshots(); - final snapshot = - converted.where('value', isGreaterThan: 0).snapshots(); + await expectLater( + snapshot, + emits( + isA>().having((e) => e.docs, 'docs', [ + isA>().having( + (e) => e.data(), + 'data', + 42, + ), + ]), + ), + ); - await expectLater( - snapshot, - emits( - isA>().having((e) => e.docs, 'docs', [ - isA>() - .having((e) => e.data(), 'data', 42), + await collection.add({'value': 21}); + + await expectLater( + snapshot, + emits( + isA>().having( + (e) => e.docs, + 'docs', + unorderedEquals([ + isA>().having( + (e) => e.data(), + 'data', + 42, + ), + isA>().having( + (e) => e.data(), + 'data', + 21, + ), ]), ), - ); + ), + ); + }, timeout: const Timeout.factor(3)); - await converted.add(21); - - await expectLater( - snapshot, - emits( - isA>().having( - (e) => e.docs, - 'docs', - unorderedEquals([ - isA>() - .having((e) => e.data(), 'data', 42), - isA>() - .having((e) => e.data(), 'data', 21), - ]), + test('snapshots', () async { + final collection = await initializeTest('foo'); + + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); + + await converted.add(42); + await converted.add(-1); + + final snapshot = converted + .where('value', isGreaterThan: 0) + .snapshots(); + + await expectLater( + snapshot, + emits( + isA>().having((e) => e.docs, 'docs', [ + isA>().having( + (e) => e.data(), + 'data', + 42, ), + ]), + ), + ); + + await converted.add(21); + + await expectLater( + snapshot, + emits( + isA>().having( + (e) => e.docs, + 'docs', + unorderedEquals([ + isA>().having( + (e) => e.data(), + 'data', + 42, + ), + isA>().having( + (e) => e.data(), + 'data', + 21, + ), + ]), ), - ); - }, - timeout: const Timeout.factor(3), - ); + ), + ); + }, timeout: const Timeout.factor(3)); - test( - 'get', - () async { - final collection = await initializeTest('foo'); + test('get', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(42); - await converted.add(-1); + await converted.add(42); + await converted.add(-1); - expect( - await converted - .where('value', isGreaterThan: 0) - .get() - .then((d) => d.docs), - [ - isA>() - .having((e) => e.data(), 'data', 42), - ], - ); - }, - timeout: const Timeout.factor(3), - ); + expect( + await converted + .where('value', isGreaterThan: 0) + .get() + .then((d) => d.docs), + [isA>().having((e) => e.data(), 'data', 42)], + ); + }, timeout: const Timeout.factor(3)); - test( - 'orderBy', - () async { - final collection = await initializeTest('foo'); + test('orderBy', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(42); - await converted.add(21); - - expect( - await converted.orderBy('value').get().then((d) => d.docs), - [ - isA>() - .having((e) => e.data(), 'data', 21), - isA>() - .having((e) => e.data(), 'data', 42), - ], - ); - }, - timeout: const Timeout.factor(3), - ); + await converted.add(42); + await converted.add(21); - test( - 'limit', - () async { - final collection = await initializeTest('foo'); + expect(await converted.orderBy('value').get().then((d) => d.docs), [ + isA>().having((e) => e.data(), 'data', 21), + isA>().having((e) => e.data(), 'data', 42), + ]); + }, timeout: const Timeout.factor(3)); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + test('limit', () async { + final collection = await initializeTest('foo'); - await converted.add(42); - await converted.add(21); - - expect( - await converted - .orderBy('value') - .limit(1) - .get() - .then((d) => d.docs), - [ - isA>() - .having((e) => e.data(), 'data', 21), - ], - ); - }, - timeout: const Timeout.factor(3), - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - test( - 'limitToLast', - () async { - final collection = await initializeTest('foo'); + await converted.add(42); + await converted.add(21); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + expect( + await converted.orderBy('value').limit(1).get().then((d) => d.docs), + [isA>().having((e) => e.data(), 'data', 21)], + ); + }, timeout: const Timeout.factor(3)); - await converted.add(42); - await converted.add(21); - - expect( - await converted - .orderBy('value') - .limitToLast(1) - .get() - .then((d) => d.docs), - [ - isA>() - .having((e) => e.data(), 'data', 42), - ], - ); - }, - timeout: const Timeout.factor(3), - ); + test('limitToLast', () async { + final collection = await initializeTest('foo'); + + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); + + await converted.add(42); + await converted.add(21); + + expect( + await converted + .orderBy('value') + .limitToLast(1) + .get() + .then((d) => d.docs), + [isA>().having((e) => e.data(), 'data', 42)], + ); + }, timeout: const Timeout.factor(3)); test('endAt', () async { final collection = await initializeTest('foo'); @@ -2529,35 +2394,30 @@ void runSecondDatabaseTests() { ); }); - test( - 'endAtDocument', - () async { - final collection = await initializeTest('foo'); + test('endAtDocument', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(1); - final doc2 = await converted.add(2); - await converted.add(3); - - expect( - await converted - .orderBy('value') - .endAtDocument(await doc2.get()) - .get() - .then((d) => d.docs), - [ - isA>().having((e) => e.data(), 'data', 1), - isA>().having((e) => e.data(), 'data', 2), - ], - ); - }, - timeout: const Timeout.factor(3), - ); + await converted.add(1); + final doc2 = await converted.add(2); + await converted.add(3); + + expect( + await converted + .orderBy('value') + .endAtDocument(await doc2.get()) + .get() + .then((d) => d.docs), + [ + isA>().having((e) => e.data(), 'data', 1), + isA>().having((e) => e.data(), 'data', 2), + ], + ); + }, timeout: const Timeout.factor(3)); test('endBefore', () async { final collection = await initializeTest('foo'); @@ -2603,271 +2463,226 @@ void runSecondDatabaseTests() { ); }); - test( - 'endBeforeDocument', - () async { - final collection = await initializeTest('foo'); + test('endBeforeDocument', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(1); - final doc2 = await converted.add(2); - await converted.add(3); - - expect( - await converted - .orderBy('value') - .endBeforeDocument(await doc2.get()) - .get() - .then((d) => d.docs), - [isA>().having((e) => e.data(), 'data', 1)], - ); - }, - timeout: const Timeout.factor(3), - ); + await converted.add(1); + final doc2 = await converted.add(2); + await converted.add(3); - test( - 'startAt', - () async { - final collection = await initializeTest('foo'); + expect( + await converted + .orderBy('value') + .endBeforeDocument(await doc2.get()) + .get() + .then((d) => d.docs), + [isA>().having((e) => e.data(), 'data', 1)], + ); + }, timeout: const Timeout.factor(3)); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + test('startAt', () async { + final collection = await initializeTest('foo'); - await converted.add(1); - await converted.add(2); - await converted.add(3); - - expect( - await converted - .orderBy('value') - .startAt([2]) - .get() - .then((d) => d.docs), - [ - isA>().having((e) => e.data(), 'data', 2), - isA>().having((e) => e.data(), 'data', 3), - ], - ); - }, - timeout: const Timeout.factor(3), - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - test( - 'startAt with Iterable', - () async { - final collection = await initializeTest('foo'); + await converted.add(1); + await converted.add(2); + await converted.add(3); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + expect( + await converted + .orderBy('value') + .startAt([2]) + .get() + .then((d) => d.docs), + [ + isA>().having((e) => e.data(), 'data', 2), + isA>().having((e) => e.data(), 'data', 3), + ], + ); + }, timeout: const Timeout.factor(3)); - await converted.add(1); - await converted.add(2); - await converted.add(3); - - expect( - await converted - .orderBy('value') - .startAt({2}) - .get() - .then((d) => d.docs), - [ - isA>().having((e) => e.data(), 'data', 2), - isA>().having((e) => e.data(), 'data', 3), - ], - ); - }, - timeout: const Timeout.factor(3), - ); + test('startAt with Iterable', () async { + final collection = await initializeTest('foo'); - test( - 'startAtDocument', - () async { - final collection = await initializeTest('foo'); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + await converted.add(1); + await converted.add(2); + await converted.add(3); - await converted.add(1); - final doc2 = await converted.add(2); - await converted.add(3); - - expect( - await converted - .orderBy('value') - .startAtDocument(await doc2.get()) - .get() - .then((d) => d.docs), - [ - isA>().having((e) => e.data(), 'data', 2), - isA>().having((e) => e.data(), 'data', 3), - ], - ); - }, - timeout: const Timeout.factor(3), - ); + expect( + await converted + .orderBy('value') + .startAt({2}) + .get() + .then((d) => d.docs), + [ + isA>().having((e) => e.data(), 'data', 2), + isA>().having((e) => e.data(), 'data', 3), + ], + ); + }, timeout: const Timeout.factor(3)); - test( - 'startAfter', - () async { - final collection = await initializeTest('foo'); + test('startAtDocument', () async { + final collection = await initializeTest('foo'); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await converted.add(1); - await converted.add(2); - await converted.add(3); - - expect( - await converted - .orderBy('value') - .startAfter([2]) - .get() - .then((d) => d.docs), - [isA>().having((e) => e.data(), 'data', 3)], - ); - }, - timeout: const Timeout.factor(3), - ); + await converted.add(1); + final doc2 = await converted.add(2); + await converted.add(3); - test( - 'startAfter with Iterable', - () async { - final collection = await initializeTest('foo'); + expect( + await converted + .orderBy('value') + .startAtDocument(await doc2.get()) + .get() + .then((d) => d.docs), + [ + isA>().having((e) => e.data(), 'data', 2), + isA>().having((e) => e.data(), 'data', 3), + ], + ); + }, timeout: const Timeout.factor(3)); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + test('startAfter', () async { + final collection = await initializeTest('foo'); - await converted.add(1); - await converted.add(2); - await converted.add(3); - - expect( - await converted - .orderBy('value') - .startAfter({2}) - .get() - .then((d) => d.docs), - [isA>().having((e) => e.data(), 'data', 3)], - ); - }, - timeout: const Timeout.factor(3), - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - test( - 'startAfterDocument', - () async { - final collection = await initializeTest('foo'); + await converted.add(1); + await converted.add(2); + await converted.add(3); - final converted = collection.withConverter( - fromFirestore: (snapshots, _) => - snapshots.data()!['value']! as int, - toFirestore: (value, _) => {'value': value}, - ); + expect( + await converted + .orderBy('value') + .startAfter([2]) + .get() + .then((d) => d.docs), + [isA>().having((e) => e.data(), 'data', 3)], + ); + }, timeout: const Timeout.factor(3)); - await converted.add(1); - final doc2 = await converted.add(2); - await converted.add(3); - - expect( - await converted - .orderBy('value') - .startAfterDocument(await doc2.get()) - .get() - .then((d) => d.docs), - [isA>().having((e) => e.data(), 'data', 3)], - ); - }, - timeout: const Timeout.factor(3), - ); + test('startAfter with Iterable', () async { + final collection = await initializeTest('foo'); - test( - 'count()', - () async { - final collection = await initializeTest('count'); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - await Future.wait([ - collection.add({'foo': 'bar'}), - collection.add({'bar': 'baz'}), - ]); + await converted.add(1); + await converted.add(2); + await converted.add(3); - AggregateQuery query = collection.count(); + expect( + await converted + .orderBy('value') + .startAfter({2}) + .get() + .then((d) => d.docs), + [isA>().having((e) => e.data(), 'data', 3)], + ); + }, timeout: const Timeout.factor(3)); - AggregateQuerySnapshot snapshot = await query.get(); + test('startAfterDocument', () async { + final collection = await initializeTest('foo'); - expect( - snapshot.count, - 2, - ); - }, - ); + final converted = collection.withConverter( + fromFirestore: (snapshots, _) => snapshots.data()!['value']! as int, + toFirestore: (value, _) => {'value': value}, + ); - test( - 'count() with query', - () async { - final collection = await initializeTest('count'); + await converted.add(1); + final doc2 = await converted.add(2); + await converted.add(3); - await Future.wait([ - collection.add({'foo': 'bar'}), - collection.add({'foo': 'baz'}), - ]); + expect( + await converted + .orderBy('value') + .startAfterDocument(await doc2.get()) + .get() + .then((d) => d.docs), + [isA>().having((e) => e.data(), 'data', 3)], + ); + }, timeout: const Timeout.factor(3)); - AggregateQuery query = - collection.where('foo', isEqualTo: 'bar').count(); + test('count()', () async { + final collection = await initializeTest('count'); - AggregateQuerySnapshot snapshot = await query.get(); + await Future.wait([ + collection.add({'foo': 'bar'}), + collection.add({'bar': 'baz'}), + ]); - expect( - snapshot.count, - 1, - ); - }, - ); + AggregateQuery query = collection.count(); + + AggregateQuerySnapshot snapshot = await query.get(); + + expect(snapshot.count, 2); + }); + + test('count() with query', () async { + final collection = await initializeTest('count'); + + await Future.wait([ + collection.add({'foo': 'bar'}), + collection.add({'foo': 'baz'}), + ]); + + AggregateQuery query = collection + .where('foo', isEqualTo: 'bar') + .count(); + + AggregateQuerySnapshot snapshot = await query.get(); + + expect(snapshot.count, 1); + }); }); group('startAfterDocument', () { test( - 'startAfterDocument() accept DocumentReference in query parameters', - () async { - final collection = await initializeTest('start-after-document'); - - final doc1 = collection.doc('1'); - final doc2 = collection.doc('2'); - final doc3 = collection.doc('3'); - final doc4 = collection.doc('4'); - await doc1.set({'ref': doc1}); - await doc2.set({'ref': doc2}); - await doc3.set({'ref': doc3}); - await doc4.set({'ref': null}); - - final q = collection - .where('ref', isNull: false) - .orderBy('ref') - .startAfterDocument(await doc1.get()); - - final res = await q.get(); - expect(res.docs.map((e) => e.reference), [doc2, doc3]); - }); + 'startAfterDocument() accept DocumentReference in query parameters', + () async { + final collection = await initializeTest('start-after-document'); + + final doc1 = collection.doc('1'); + final doc2 = collection.doc('2'); + final doc3 = collection.doc('3'); + final doc4 = collection.doc('4'); + await doc1.set({'ref': doc1}); + await doc2.set({'ref': doc2}); + await doc3.set({'ref': doc3}); + await doc4.set({'ref': null}); + + final q = collection + .where('ref', isNull: false) + .orderBy('ref') + .startAfterDocument(await doc1.get()); + + final res = await q.get(); + expect(res.docs.map((e) => e.reference), [doc2, doc3]); + }, + ); }); }, // Skipped on CI for web as the data is live and it clashes with other tests running in CI diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/settings_e2e.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/settings_e2e.dart index 10de2f3bef55..79436e4df8aa 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/settings_e2e.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/settings_e2e.dart @@ -6,79 +6,75 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter_test/flutter_test.dart'; void runSettingsTest() { - group( - '$Settings', - () { - late FirebaseFirestore firestore; - - setUpAll(() async { - firestore = FirebaseFirestore.instance; - }); - - Future initializeTest() async { - Settings firestoreSettings = const Settings( - persistenceEnabled: false, - webExperimentalForceLongPolling: true, - webExperimentalAutoDetectLongPolling: true, - webExperimentalLongPollingOptions: WebExperimentalLongPollingOptions( - timeoutDuration: Duration(seconds: 15), - ), - ); - - return firestore.settings = firestoreSettings; - } - - test('checks if long polling settings were applied', () async { - Settings settings = await initializeTest(); - - expect(settings.webExperimentalForceLongPolling, true); - - expect(settings.webExperimentalAutoDetectLongPolling, true); - - expect( - settings.webExperimentalLongPollingOptions, - settings.webExperimentalLongPollingOptions, - ); - }); - - test('can apply WebPersistentMultipleTabManager setting', () async { - const settings = Settings( - persistenceEnabled: true, - webPersistentTabManager: WebPersistentMultipleTabManager(), - ); - - firestore.settings = settings; - - expect( - firestore.settings.webPersistentTabManager, - isA(), - ); - }); - - test('can apply WebPersistentSingleTabManager setting', () async { - const settings = Settings( - persistenceEnabled: true, - webPersistentTabManager: - WebPersistentSingleTabManager(forceOwnership: true), - ); - - firestore.settings = settings; - - final tabManager = firestore.settings.webPersistentTabManager; - expect(tabManager, isA()); - expect( - (tabManager! as WebPersistentSingleTabManager).forceOwnership, - true, - ); - }); - - test('webPersistentTabManager defaults to null', () async { - const settings = Settings( - persistenceEnabled: true, - ); - - expect(settings.webPersistentTabManager, isNull); - }); - }, - ); + group('$Settings', () { + late FirebaseFirestore firestore; + + setUpAll(() async { + firestore = FirebaseFirestore.instance; + }); + + Future initializeTest() async { + Settings firestoreSettings = const Settings( + persistenceEnabled: false, + webExperimentalForceLongPolling: true, + webExperimentalAutoDetectLongPolling: true, + webExperimentalLongPollingOptions: WebExperimentalLongPollingOptions( + timeoutDuration: Duration(seconds: 15), + ), + ); + + return firestore.settings = firestoreSettings; + } + + test('checks if long polling settings were applied', () async { + Settings settings = await initializeTest(); + + expect(settings.webExperimentalForceLongPolling, true); + + expect(settings.webExperimentalAutoDetectLongPolling, true); + + expect( + settings.webExperimentalLongPollingOptions, + settings.webExperimentalLongPollingOptions, + ); + }); + + test('can apply WebPersistentMultipleTabManager setting', () async { + const settings = Settings( + persistenceEnabled: true, + webPersistentTabManager: WebPersistentMultipleTabManager(), + ); + + firestore.settings = settings; + + expect( + firestore.settings.webPersistentTabManager, + isA(), + ); + }); + + test('can apply WebPersistentSingleTabManager setting', () async { + const settings = Settings( + persistenceEnabled: true, + webPersistentTabManager: WebPersistentSingleTabManager( + forceOwnership: true, + ), + ); + + firestore.settings = settings; + + final tabManager = firestore.settings.webPersistentTabManager; + expect(tabManager, isA()); + expect( + (tabManager! as WebPersistentSingleTabManager).forceOwnership, + true, + ); + }); + + test('webPersistentTabManager defaults to null', () async { + const settings = Settings(persistenceEnabled: true); + + expect(settings.webPersistentTabManager, isNull); + }); + }); } diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/snapshot_metadata_e2e.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/snapshot_metadata_e2e.dart index a6bb69e5a0ca..ee4dc7c8f356 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/snapshot_metadata_e2e.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/snapshot_metadata_e2e.dart @@ -7,38 +7,37 @@ import 'package:flutter/foundation.dart'; import 'package:flutter_test/flutter_test.dart'; void runSnapshotMetadataTests() { - group( - '$SnapshotMetadata', - () { - late FirebaseFirestore /*?*/ firestore; + group('$SnapshotMetadata', () { + late FirebaseFirestore /*?*/ firestore; - setUpAll(() async { - firestore = FirebaseFirestore.instance; - }); + setUpAll(() async { + firestore = FirebaseFirestore.instance; + }); - Future initializeTest(String id) async { - CollectionReference collection = - firestore.collection('flutter-tests/$id/query-tests'); - QuerySnapshot snapshot = await collection.get(); - await Future.forEach(snapshot.docs, - (DocumentSnapshot documentSnapshot) { - return documentSnapshot.reference.delete(); - }); - return collection; - } + Future initializeTest(String id) async { + CollectionReference collection = firestore.collection( + 'flutter-tests/$id/query-tests', + ); + QuerySnapshot snapshot = await collection.get(); + await Future.forEach(snapshot.docs, (DocumentSnapshot documentSnapshot) { + return documentSnapshot.reference.delete(); + }); + return collection; + } - test('a snapshot returns the correct [isFromCache] value', () async { - CollectionReference collection = - await initializeTest('snapshot-metadata-is-from-cache'); - QuerySnapshot qs = - await collection.get(const GetOptions(source: Source.cache)); - expect(qs.metadata.isFromCache, isTrue); + test('a snapshot returns the correct [isFromCache] value', () async { + CollectionReference collection = await initializeTest( + 'snapshot-metadata-is-from-cache', + ); + QuerySnapshot qs = await collection.get( + const GetOptions(source: Source.cache), + ); + expect(qs.metadata.isFromCache, isTrue); - QuerySnapshot qs2 = - await collection.get(const GetOptions(source: Source.server)); - expect(qs2.metadata.isFromCache, isFalse); - }); - }, - skip: kIsWeb, - ); + QuerySnapshot qs2 = await collection.get( + const GetOptions(source: Source.server), + ); + expect(qs2.metadata.isFromCache, isFalse); + }); + }, skip: kIsWeb); } diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/timestamp_e2e.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/timestamp_e2e.dart index 99b055558f84..90b61d7682b3 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/timestamp_e2e.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/timestamp_e2e.dart @@ -22,8 +22,9 @@ void runTimestampTests() { } test('sets a $Timestamp & returns one', () async { - DocumentReference> doc = - await initializeTest('timestamp'); + DocumentReference> doc = await initializeTest( + 'timestamp', + ); DateTime date = DateTime.utc(3000); await doc.set({'foo': Timestamp.fromDate(date)}); @@ -37,23 +38,26 @@ void runTimestampTests() { ); }); - test('implicitly converts a DateTime without losing microseconds', - () async { - final doc = await initializeTest('datetime-microseconds'); - final date = DateTime.utc(2023, 11, 1, 0, 0, 0, 999, 999); + test( + 'implicitly converts a DateTime without losing microseconds', + () async { + final doc = await initializeTest('datetime-microseconds'); + final date = DateTime.utc(2023, 11, 1, 0, 0, 0, 999, 999); - await doc.set({'foo': date}); + await doc.set({'foo': date}); - final snapshot = await doc.get(); - final timestamp = snapshot.data()!['foo'] as Timestamp; + final snapshot = await doc.get(); + final timestamp = snapshot.data()!['foo'] as Timestamp; - expect(timestamp, Timestamp.fromDate(date)); - expect(timestamp.microsecondsSinceEpoch, date.microsecondsSinceEpoch); - }); + expect(timestamp, Timestamp.fromDate(date)); + expect(timestamp.microsecondsSinceEpoch, date.microsecondsSinceEpoch); + }, + ); test('updates a $Timestamp & returns', () async { - DocumentReference> doc = - await initializeTest('geo-point-update'); + DocumentReference> doc = await initializeTest( + 'geo-point-update', + ); DateTime date = DateTime.utc(3000, 01, 02); await doc.set({'foo': DateTime.utc(3000)}); @@ -69,8 +73,9 @@ void runTimestampTests() { }); test('set pre-1970 $Timestamp and return', () async { - DocumentReference> doc = - await initializeTest('timestamp'); + DocumentReference> doc = await initializeTest( + 'timestamp', + ); final date = DateTime(1969, 06, 22, 0, 0, 0, 123); final localTimestamp = Timestamp.fromDate(date); @@ -79,10 +84,7 @@ void runTimestampTests() { DocumentSnapshot> snapshot = await doc.get(); Timestamp retievedTimestamp = snapshot.data()!['foo']; expect(retievedTimestamp, isA()); - expect( - retievedTimestamp, - equals(localTimestamp), - ); + expect(retievedTimestamp, equals(localTimestamp)); }); }); } diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/transaction_e2e.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/transaction_e2e.dart index d0fe0e78b66f..258bdb1d9eb3 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/transaction_e2e.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/transaction_e2e.dart @@ -10,322 +10,318 @@ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; void runTransactionTests() { - group( - '$Transaction', - () { - late FirebaseFirestore firestore; + group('$Transaction', () { + late FirebaseFirestore firestore; + + setUpAll(() async { + firestore = FirebaseFirestore.instance; + }); + + Future>> initializeTest( + String path, + ) async { + String prefixedPath = 'flutter-tests/$path'; + await firestore.doc(prefixedPath).delete(); + return firestore.doc(prefixedPath); + } + + test('works with withConverter', () async { + DocumentReference> rawDoc = await initializeTest( + 'with-converter-batch', + ); - setUpAll(() async { - firestore = FirebaseFirestore.instance; - }); + DocumentReference doc = rawDoc.withConverter( + fromFirestore: (snapshot, options) { + return snapshot.data()!['value'] as int; + }, + toFirestore: (value, options) => {'value': value}, + ); - Future>> initializeTest( - String path, - ) async { - String prefixedPath = 'flutter-tests/$path'; - await firestore.doc(prefixedPath).delete(); - return firestore.doc(prefixedPath); - } + await doc.set(42); - test('works with withConverter', () async { - DocumentReference> rawDoc = - await initializeTest('with-converter-batch'); + expect( + await firestore.runTransaction((transaction) async { + final snapshot = await transaction.get(doc); + return snapshot.data(); + }), + 42, + ); - DocumentReference doc = rawDoc.withConverter( - fromFirestore: (snapshot, options) { - return snapshot.data()!['value'] as int; - }, - toFirestore: (value, options) => {'value': value}, - ); + await firestore.runTransaction((transaction) async { + transaction.set(doc, 21); + }); - await doc.set(42); + expect(await doc.get().then((s) => s.data()), 21); - expect( - await firestore.runTransaction((transaction) async { - final snapshot = await transaction.get(doc); - return snapshot.data(); - }), - 42, - ); + await firestore.runTransaction((transaction) async { + transaction.update(doc, {'value': 0}); + }); - await firestore.runTransaction((transaction) async { - transaction.set(doc, 21); + expect(await doc.get().then((s) => s.data()), 0); + }); + + test('should resolve with user value', () async { + int randomValue = Random().nextInt(9999); + int response = await firestore.runTransaction(( + Transaction transaction, + ) async { + return randomValue; + }); + expect(response, equals(randomValue)); + }); + + test( + 'does not report an error when the transaction stream is cancelled', + () async { + final List reportedErrors = []; + final FlutterExceptionHandler? previousOnError = FlutterError.onError; + FlutterError.onError = (FlutterErrorDetails details) { + reportedErrors.add(details.exception); + }; + addTearDown(() { + FlutterError.onError = previousOnError; }); - expect(await doc.get().then((s) => s.data()), 21); + final DocumentReference> doc = + await initializeTest('transaction-cancel-cleanup'); - await firestore.runTransaction((transaction) async { - transaction.update(doc, {'value': 0}); + await firestore.runTransaction((Transaction transaction) async { + transaction.set(doc, {'updatedAt': DateTime.now().toIso8601String()}); }); - expect(await doc.get().then((s) => s.data()), 0); - }); + await Future.delayed(const Duration(milliseconds: 100)); - test('should resolve with user value', () async { - int randomValue = Random().nextInt(9999); - int response = await firestore - .runTransaction((Transaction transaction) async { - return randomValue; + final Iterable transactionCancelErrors = reportedErrors.where(( + Object error, + ) { + final String text = error.toString(); + return error is MissingPluginException && + text.contains('firebase_firestore/transaction'); }); - expect(response, equals(randomValue)); - }); - test( - 'does not report an error when the transaction stream is cancelled', - () async { - final List reportedErrors = []; - final FlutterExceptionHandler? previousOnError = FlutterError.onError; - FlutterError.onError = (FlutterErrorDetails details) { - reportedErrors.add(details.exception); - }; - addTearDown(() { - FlutterError.onError = previousOnError; - }); + expect( + transactionCancelErrors, + isEmpty, + reason: 'Unexpected FlutterError(s): $reportedErrors', + ); + }, + skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android + ? 'Android-only EventChannel teardown race' + : false, + ); + + test('runs after reading a document', () async { + final documentReference = await initializeTest('transaction-after-get'); + await documentReference.set({'value': 0}); + await documentReference.get(); + + await firestore.runTransaction((transaction) async { + final snapshot = await transaction.get(documentReference); + transaction.update(documentReference, { + 'value': snapshot.data()!['value'] + 1, + }); + }); - final DocumentReference> doc = - await initializeTest('transaction-cancel-cleanup'); + final snapshot = await documentReference.get(); + expect(snapshot.data()!['value'], 1); + }, skip: defaultTargetPlatform != TargetPlatform.windows); - await firestore.runTransaction((Transaction transaction) async { - transaction.set(doc, { - 'updatedAt': DateTime.now().toIso8601String(), - }); - }); + test('should abort if thrown and not continue', () async { + DocumentReference> documentReference = + await initializeTest('transaction-abort'); - await Future.delayed(const Duration(milliseconds: 100)); + await documentReference.set({'foo': 'bar'}); - final Iterable transactionCancelErrors = - reportedErrors.where((Object error) { - final String text = error.toString(); - return error is MissingPluginException && - text.contains('firebase_firestore/transaction'); - }); + try { + await firestore.runTransaction((Transaction transaction) async { + transaction.set(documentReference, {'foo': 'baz'}); + throw 'Stop'; + }); + // ignore: dead_code + fail('Should have thrown'); + } catch (e) { + DocumentSnapshot> snapshot = + await documentReference.get(); + expect(snapshot.data()!['foo'], equals('bar')); + } + }); - expect( - transactionCancelErrors, - isEmpty, - reason: 'Unexpected FlutterError(s): $reportedErrors', - ); - }, - skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android - ? 'Android-only EventChannel teardown race' - : false, + test('should not collide if number of maxAttempts is enough', () async { + DocumentReference> doc1 = await initializeTest( + 'transaction-maxAttempts-1', ); - test( - 'runs after reading a document', - () async { - final documentReference = - await initializeTest('transaction-after-get'); - await documentReference.set({'value': 0}); - await documentReference.get(); - - await firestore.runTransaction((transaction) async { - final snapshot = await transaction.get(documentReference); - transaction.update(documentReference, { - 'value': snapshot.data()!['value'] + 1, - }); - }); - - final snapshot = await documentReference.get(); - expect(snapshot.data()!['value'], 1); - }, - skip: defaultTargetPlatform != TargetPlatform.windows, + await doc1.set({'test': 0}); + + await Future.wait([ + firestore.runTransaction((Transaction transaction) async { + final value = await transaction.get(doc1); + transaction.set(doc1, {'test': value['test'] + 1}); + }, maxAttempts: 2), + firestore.runTransaction((Transaction transaction) async { + final value = await transaction.get(doc1); + transaction.set(doc1, {'test': value['test'] + 1}); + }, maxAttempts: 2), + ]); + + DocumentSnapshot> snapshot1 = await doc1.get(); + expect(snapshot1.data()!['test'], equals(2)); + }, retry: 2); + + test('should collide if number of maxAttempts is too low', () async { + DocumentReference> doc1 = await initializeTest( + 'transaction-maxAttempts-2', ); - test('should abort if thrown and not continue', () async { - DocumentReference> documentReference = - await initializeTest('transaction-abort'); - - await documentReference.set({'foo': 'bar'}); - - try { - await firestore.runTransaction((Transaction transaction) async { - transaction.set(documentReference, { - 'foo': 'baz', - }); - throw 'Stop'; - }); - // ignore: dead_code - fail('Should have thrown'); - } catch (e) { - DocumentSnapshot> snapshot = - await documentReference.get(); - expect(snapshot.data()!['foo'], equals('bar')); - } - }); + await doc1.set({'test': 0}); - test( - 'should not collide if number of maxAttempts is enough', - () async { - DocumentReference> doc1 = - await initializeTest('transaction-maxAttempts-1'); - - await doc1.set({'test': 0}); - - await Future.wait([ - firestore.runTransaction( - (Transaction transaction) async { - final value = await transaction.get(doc1); - transaction.set(doc1, { - 'test': value['test'] + 1, - }); - }, - maxAttempts: 2, - ), - firestore.runTransaction( - (Transaction transaction) async { - final value = await transaction.get(doc1); - transaction.set(doc1, { - 'test': value['test'] + 1, - }); - }, - maxAttempts: 2, - ), - ]); - - DocumentSnapshot> snapshot1 = await doc1.get(); - expect(snapshot1.data()!['test'], equals(2)); - }, - retry: 2, + await expectLater( + Future.wait([ + firestore.runTransaction((Transaction transaction) async { + final value = await transaction.get(doc1); + transaction.set(doc1, {'test': value['test'] + 1}); + }, maxAttempts: 1), + firestore.runTransaction((Transaction transaction) async { + final value = await transaction.get(doc1); + transaction.set(doc1, {'test': value['test'] + 1}); + }, maxAttempts: 1), + ]), + throwsA( + isA().having( + (e) => e.code, + 'code', + 'failed-precondition', + ), + ), ); + }, skip: kIsWeb || defaultTargetPlatform == TargetPlatform.windows); - test( - 'should collide if number of maxAttempts is too low', - () async { - DocumentReference> doc1 = - await initializeTest('transaction-maxAttempts-2'); - - await doc1.set({'test': 0}); - - await expectLater( - Future.wait([ - firestore.runTransaction( - (Transaction transaction) async { - final value = await transaction.get(doc1); - transaction.set(doc1, { - 'test': value['test'] + 1, - }); - }, - maxAttempts: 1, - ), - firestore.runTransaction( - (Transaction transaction) async { - final value = await transaction.get(doc1); - transaction.set(doc1, { - 'test': value['test'] + 1, - }); - }, - maxAttempts: 1, - ), - ]), - throwsA( - isA() - .having((e) => e.code, 'code', 'failed-precondition'), - ), - ); - }, - skip: kIsWeb || defaultTargetPlatform == TargetPlatform.windows, + test('runs multiple transactions in parallel', () async { + DocumentReference> doc1 = await initializeTest( + 'transaction-multi-1', + ); + DocumentReference> doc2 = await initializeTest( + 'transaction-multi-2', ); - test('runs multiple transactions in parallel', () async { - DocumentReference> doc1 = - await initializeTest('transaction-multi-1'); - DocumentReference> doc2 = - await initializeTest('transaction-multi-2'); - - await doc1.set({'test': 'value1'}); - await doc2.set({'test': 'value2'}); + await doc1.set({'test': 'value1'}); + await doc2.set({'test': 'value2'}); + + await Future.wait([ + firestore.runTransaction((Transaction transaction) async { + transaction.set(doc1, {'test': 'value3'}); + }), + firestore.runTransaction((Transaction transaction) async { + transaction.set(doc2, {'test': 'value4'}); + }), + ]); + + DocumentSnapshot> snapshot1 = await doc1.get(); + expect(snapshot1.data()!['test'], equals('value3')); + DocumentSnapshot> snapshot2 = await doc2.get(); + expect(snapshot2.data()!['test'], equals('value4')); + }); + + test('runs many sequential transactions with large payloads', () async { + DocumentReference> doc = await initializeTest( + 'transaction-cleanup-stress', + ); + final payload = { + for (var i = 0; i < 100; i++) 'field_$i': 'x' * 100, + }; - await Future.wait([ - firestore.runTransaction((Transaction transaction) async { - transaction.set(doc1, { - 'test': 'value3', - }); - }), - firestore.runTransaction((Transaction transaction) async { - transaction.set(doc2, { - 'test': 'value4', - }); - }), - ]); + await doc.set({'count': 0, ...payload}); - DocumentSnapshot> snapshot1 = await doc1.get(); - expect(snapshot1.data()!['test'], equals('value3')); - DocumentSnapshot> snapshot2 = await doc2.get(); - expect(snapshot2.data()!['test'], equals('value4')); - }); + for (var i = 0; i < 100; i++) { + await firestore.runTransaction((transaction) async { + final snapshot = await transaction.get(doc); + final count = snapshot.data()!['count'] as int; - test( - 'runs many sequential transactions with large payloads', - () async { - DocumentReference> doc = - await initializeTest('transaction-cleanup-stress'); - final payload = { - for (var i = 0; i < 100; i++) 'field_$i': 'x' * 100, - }; - - await doc.set({'count': 0, ...payload}); - - for (var i = 0; i < 100; i++) { - await firestore.runTransaction((transaction) async { - final snapshot = await transaction.get(doc); - final count = snapshot.data()!['count'] as int; - - transaction.update(doc, { - 'count': count + 1, - ...payload, - }); - }); - } + transaction.update(doc, {'count': count + 1, ...payload}); + }); + } - final snapshot = await doc.get(); - expect(snapshot.data()!['count'], 100); - }, - skip: kIsWeb, + final snapshot = await doc.get(); + expect(snapshot.data()!['count'], 100); + }, skip: kIsWeb); + + test('should abort if timeout is exceeded', () async { + await expectLater( + firestore.runTransaction( + (Transaction transaction) => + Future.delayed(const Duration(seconds: 2)), + timeout: const Duration(seconds: 1), + ), + throwsA( + isA().having( + (e) => e.code, + 'code', + 'deadline-exceeded', + ), + ), ); + }, skip: kIsWeb || defaultTargetPlatform == TargetPlatform.windows); - test( - 'should abort if timeout is exceeded', - () async { - await expectLater( - firestore.runTransaction( - (Transaction transaction) => - Future.delayed(const Duration(seconds: 2)), - timeout: const Duration(seconds: 1), - ), - throwsA( - isA() - .having((e) => e.code, 'code', 'deadline-exceeded'), - ), - ); - }, - skip: kIsWeb || defaultTargetPlatform == TargetPlatform.windows, - ); + test('should throw with exception', () async { + try { + await firestore.runTransaction((Transaction transaction) async { + throw StateError('foo'); + }); + // ignore: dead_code + fail('Transaction should not have resolved'); + } on StateError catch (e) { + expect(e.message, equals('foo')); + return; + } catch (e) { + fail('Transaction threw invalid exeption'); + } + }); + + test( + 'should throw a native error, and convert to a [FirebaseException]', + () async { + DocumentReference> documentReference = firestore + .doc('not-allowed/document'); - test('should throw with exception', () async { try { await firestore.runTransaction((Transaction transaction) async { - throw StateError('foo'); + transaction.set(documentReference, {'foo': 'bar'}); }); - // ignore: dead_code fail('Transaction should not have resolved'); - } on StateError catch (e) { - expect(e.message, equals('foo')); + } on FirebaseException catch (e) { + expect(e.code, equals('permission-denied')); return; } catch (e) { - fail('Transaction threw invalid exeption'); + fail('Transaction threw invalid exception'); } + }, + skip: kIsWeb || defaultTargetPlatform == TargetPlatform.windows, + ); + + group('Transaction.get()', () { + test('should throw if get is called after a command', () async { + DocumentReference> documentReference = firestore + .doc('flutter-tests/foo'); + + expect( + () => firestore.runTransaction((Transaction transaction) async { + await transaction.get(documentReference); + transaction.set(documentReference, {'foo': 'bar'}); + await transaction.get(documentReference); + }), + throwsAssertionError, + ); }); test( 'should throw a native error, and convert to a [FirebaseException]', () async { - DocumentReference> documentReference = - firestore.doc('not-allowed/document'); + DocumentReference> documentReference = firestore + .doc('not-allowed/document'); try { await firestore.runTransaction((Transaction transaction) async { - transaction.set(documentReference, {'foo': 'bar'}); + await transaction.get(documentReference); }); fail('Transaction should not have resolved'); } on FirebaseException catch (e) { @@ -337,257 +333,211 @@ void runTransactionTests() { }, skip: kIsWeb || defaultTargetPlatform == TargetPlatform.windows, ); + }); - group('Transaction.get()', () { - test('should throw if get is called after a command', () async { - DocumentReference> documentReference = - firestore.doc('flutter-tests/foo'); + group('Transaction.delete()', () { + test('should delete a document', () async { + DocumentReference> documentReference = + await initializeTest('transaction-delete'); - expect( - () => firestore.runTransaction((Transaction transaction) async { - await transaction.get(documentReference); - transaction.set(documentReference, {'foo': 'bar'}); - await transaction.get(documentReference); - }), - throwsAssertionError, - ); - }); + await documentReference.set({'foo': 'bar'}); - test( - 'should throw a native error, and convert to a [FirebaseException]', - () async { - DocumentReference> documentReference = - firestore.doc('not-allowed/document'); + await firestore.runTransaction((Transaction transaction) async { + transaction.delete(documentReference); + }); - try { - await firestore.runTransaction((Transaction transaction) async { - await transaction.get(documentReference); - }); - fail('Transaction should not have resolved'); - } on FirebaseException catch (e) { - expect(e.code, equals('permission-denied')); - return; - } catch (e) { - fail('Transaction threw invalid exception'); - } - }, - skip: kIsWeb || defaultTargetPlatform == TargetPlatform.windows, - ); + DocumentSnapshot> snapshot = + await documentReference.get(); + expect(snapshot.exists, isFalse); }); + }); - group('Transaction.delete()', () { - test('should delete a document', () async { - DocumentReference> documentReference = - await initializeTest('transaction-delete'); + group('Transaction.update()', () { + test('should update a document', () async { + DocumentReference> documentReference = + await initializeTest('transaction-update'); - await documentReference.set({'foo': 'bar'}); + await documentReference.set({'foo': 'bar', 'bar': 1}); - await firestore.runTransaction((Transaction transaction) async { - transaction.delete(documentReference); + await firestore.runTransaction((Transaction transaction) async { + DocumentSnapshot> documentSnapshot = + await transaction.get(documentReference); + transaction.update(documentReference, { + 'bar': documentSnapshot.data()!['bar'] + 1, }); - - DocumentSnapshot> snapshot = - await documentReference.get(); - expect(snapshot.exists, isFalse); }); - }); - group('Transaction.update()', () { - test('should update a document', () async { - DocumentReference> documentReference = - await initializeTest('transaction-update'); - - await documentReference.set({'foo': 'bar', 'bar': 1}); + DocumentSnapshot> snapshot = + await documentReference.get(); + expect(snapshot.exists, isTrue); + expect(snapshot.data()!['bar'], equals(2)); + expect(snapshot.data()!['foo'], equals('bar')); + }); - await firestore.runTransaction((Transaction transaction) async { - DocumentSnapshot> documentSnapshot = - await transaction.get(documentReference); - transaction.update(documentReference, { - 'bar': documentSnapshot.data()!['bar'] + 1, - }); - }); + test('should update a document using FieldPath keys', () async { + DocumentReference> documentReference = + await initializeTest('transaction-update-field-path'); - DocumentSnapshot> snapshot = - await documentReference.get(); - expect(snapshot.exists, isTrue); - expect(snapshot.data()!['bar'], equals(2)); - expect(snapshot.data()!['foo'], equals('bar')); + await documentReference.set({ + 'nested': {'field': 'old_value'}, + 'top': 'value', }); - test('should update a document using FieldPath keys', () async { - DocumentReference> documentReference = - await initializeTest('transaction-update-field-path'); - - await documentReference.set({ - 'nested': {'field': 'old_value'}, - 'top': 'value', - }); - - await firestore.runTransaction((Transaction transaction) async { - await transaction.get(documentReference); - transaction.update(documentReference, { - FieldPath(const ['nested', 'field']): 'new_value', - }); + await firestore.runTransaction((Transaction transaction) async { + await transaction.get(documentReference); + transaction.update(documentReference, { + FieldPath(const ['nested', 'field']): 'new_value', }); - - DocumentSnapshot> snapshot = - await documentReference.get(); - expect(snapshot.exists, isTrue); - expect(snapshot.data()!['nested']['field'], equals('new_value')); - expect(snapshot.data()!['top'], equals('value')); }); + + DocumentSnapshot> snapshot = + await documentReference.get(); + expect(snapshot.exists, isTrue); + expect(snapshot.data()!['nested']['field'], equals('new_value')); + expect(snapshot.data()!['top'], equals('value')); }); + }); - group('Transaction.set()', () { - test('sets a document', () async { - DocumentReference> documentReference = - await initializeTest('transaction-set'); + group('Transaction.set()', () { + test('sets a document', () async { + DocumentReference> documentReference = + await initializeTest('transaction-set'); - await documentReference.set({'foo': 'bar', 'bar': 1}); + await documentReference.set({'foo': 'bar', 'bar': 1}); - await firestore.runTransaction((Transaction transaction) async { - DocumentSnapshot> documentSnapshot = - await transaction.get(documentReference); - transaction.set(documentReference, { - 'bar': documentSnapshot.data()!['bar'] + 1, - }); + await firestore.runTransaction((Transaction transaction) async { + DocumentSnapshot> documentSnapshot = + await transaction.get(documentReference); + transaction.set(documentReference, { + 'bar': documentSnapshot.data()!['bar'] + 1, }); - - DocumentSnapshot> snapshot = - await documentReference.get(); - expect(snapshot.exists, isTrue); - expect( - snapshot.data(), - equals({'bar': 2}), - ); }); - test('merges a document with set', () async { - DocumentReference> documentReference = - await initializeTest('transaction-set-merge'); + DocumentSnapshot> snapshot = + await documentReference.get(); + expect(snapshot.exists, isTrue); + expect(snapshot.data(), equals({'bar': 2})); + }); - await documentReference.set({'foo': 'bar', 'bar': 1}); + test('merges a document with set', () async { + DocumentReference> documentReference = + await initializeTest('transaction-set-merge'); - await firestore.runTransaction((Transaction transaction) async { - DocumentSnapshot> documentSnapshot = - await transaction.get(documentReference); - transaction.set( - documentReference, - {'bar': documentSnapshot.data()!['bar'] + 1}, - SetOptions(merge: true), - ); - }); + await documentReference.set({'foo': 'bar', 'bar': 1}); - DocumentSnapshot> snapshot = - await documentReference.get(); - expect(snapshot.exists, isTrue); - expect(snapshot.data()!['bar'], equals(2)); - expect(snapshot.data()!['foo'], equals('bar')); + await firestore.runTransaction((Transaction transaction) async { + DocumentSnapshot> documentSnapshot = + await transaction.get(documentReference); + transaction.set(documentReference, { + 'bar': documentSnapshot.data()!['bar'] + 1, + }, SetOptions(merge: true)); }); - test('merges fields a document with set', () async { - DocumentReference> documentReference = - await initializeTest('transaction-set-merge-fields'); - - await documentReference.set({'foo': 'bar', 'bar': 1, 'baz': 1}); - - await firestore.runTransaction((Transaction transaction) async { - DocumentSnapshot> documentSnapshot = - await transaction.get(documentReference); - transaction.set( - documentReference, - { - 'bar': documentSnapshot.data()!['bar'] + 1, - 'baz': 'ben', - }, - SetOptions(mergeFields: ['bar']), - ); - }); - - DocumentSnapshot> snapshot = - await documentReference.get(); - expect(snapshot.exists, isTrue); - expect( - snapshot.data(), - equals({'foo': 'bar', 'bar': 2, 'baz': 1}), - ); - }); + DocumentSnapshot> snapshot = + await documentReference.get(); + expect(snapshot.exists, isTrue); + expect(snapshot.data()!['bar'], equals(2)); + expect(snapshot.data()!['foo'], equals('bar')); }); - test('runs all commands in a single transaction', () async { + test('merges fields a document with set', () async { DocumentReference> documentReference = - await initializeTest('transaction-all'); - - DocumentReference> documentReference2 = - firestore.doc('flutter-tests/delete'); + await initializeTest('transaction-set-merge-fields'); - await documentReference2.set({'foo': 'bar'}); - await documentReference.set({'foo': 1}); + await documentReference.set({'foo': 'bar', 'bar': 1, 'baz': 1}); - String result = await firestore - .runTransaction((Transaction transaction) async { + await firestore.runTransaction((Transaction transaction) async { DocumentSnapshot> documentSnapshot = await transaction.get(documentReference); - transaction.set(documentReference, { - 'foo': documentSnapshot.data()!['foo'] + 1, - }); - - transaction.update(documentReference, {'bar': 'baz'}); - - transaction.delete(documentReference2); - - return 'done'; + 'bar': documentSnapshot.data()!['bar'] + 1, + 'baz': 'ben', + }, SetOptions(mergeFields: ['bar'])); }); - expect(result, equals('done')); - DocumentSnapshot> snapshot = await documentReference.get(); expect(snapshot.exists, isTrue); expect( snapshot.data(), - equals({'foo': 2, 'bar': 'baz'}), + equals({'foo': 'bar', 'bar': 2, 'baz': 1}), ); + }); + }); - DocumentSnapshot> snapshot2 = - await documentReference2.get(); - expect(snapshot2.exists, isFalse); + test('runs all commands in a single transaction', () async { + DocumentReference> documentReference = + await initializeTest('transaction-all'); + + DocumentReference> documentReference2 = firestore + .doc('flutter-tests/delete'); + + await documentReference2.set({'foo': 'bar'}); + await documentReference.set({'foo': 1}); + + String result = await firestore.runTransaction(( + Transaction transaction, + ) async { + DocumentSnapshot> documentSnapshot = + await transaction.get(documentReference); + + transaction.set(documentReference, { + 'foo': documentSnapshot.data()!['foo'] + 1, + }); + + transaction.update(documentReference, {'bar': 'baz'}); + + transaction.delete(documentReference2); + + return 'done'; }); - test( - 'runs many transactions concurrently without corrupting native state', - () async { - // Regression test for - // https://github.com/firebase/flutterfire/issues/18417: concurrent - // transactions used to mutate the plugin's shared transaction map - // from multiple threads without synchronization, which could crash - // iOS with a heap-corruption SIGABRT. - const int count = 30; - - final refs = [ - for (var i = 0; i < count; i++) - firestore.doc('flutter-tests/transaction-concurrent-$i'), - ]; - - await Future.wait([ - for (final ref in refs) - firestore.runTransaction((Transaction transaction) async { - final snapshot = await transaction.get(ref); - transaction.set(ref, { - 'value': ((snapshot.data()?['value'] as int?) ?? 0) + 1, - }); - }), - ]); - - final snapshots = await Future.wait(refs.map((ref) => ref.get())); - for (final snapshot in snapshots) { - expect(snapshot.exists, isTrue); - expect(snapshot.data()!['value'], isA()); - } - }, + expect(result, equals('done')); + + DocumentSnapshot> snapshot = await documentReference + .get(); + expect(snapshot.exists, isTrue); + expect( + snapshot.data(), + equals({'foo': 2, 'bar': 'baz'}), ); - }, - skip: kIsWeb, - ); + + DocumentSnapshot> snapshot2 = + await documentReference2.get(); + expect(snapshot2.exists, isFalse); + }); + + test( + 'runs many transactions concurrently without corrupting native state', + () async { + // Regression test for + // https://github.com/firebase/flutterfire/issues/18417: concurrent + // transactions used to mutate the plugin's shared transaction map + // from multiple threads without synchronization, which could crash + // iOS with a heap-corruption SIGABRT. + const int count = 30; + + final refs = [ + for (var i = 0; i < count; i++) + firestore.doc('flutter-tests/transaction-concurrent-$i'), + ]; + + await Future.wait([ + for (final ref in refs) + firestore.runTransaction((Transaction transaction) async { + final snapshot = await transaction.get(ref); + transaction.set(ref, { + 'value': ((snapshot.data()?['value'] as int?) ?? 0) + 1, + }); + }), + ]); + + final snapshots = await Future.wait(refs.map((ref) => ref.get())); + for (final snapshot in snapshots) { + expect(snapshot.exists, isTrue); + expect(snapshot.data()!['value'], isA()); + } + }, + ); + }, skip: kIsWeb); } diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/vector_value_e2e.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/vector_value_e2e.dart index e10b4689e642..937878b211b1 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/vector_value_e2e.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/vector_value_e2e.dart @@ -34,8 +34,9 @@ void runVectorValueTests() { } test('sets a $VectorValue & returns one', () async { - DocumentReference> doc = - await initializeTest('vector-value'); + DocumentReference> doc = await initializeTest( + 'vector-value', + ); await doc.set({ 'foo': const VectorValue([10.0, -10.0]), @@ -49,8 +50,9 @@ void runVectorValueTests() { }); test('updates a $VectorValue & returns', () async { - DocumentReference> doc = - await initializeTest('vector-value-update'); + DocumentReference> doc = await initializeTest( + 'vector-value-update', + ); await doc.set({ 'foo': const VectorValue([10.0, -10.0]), @@ -68,13 +70,12 @@ void runVectorValueTests() { }); test('handles empty vector', () async { - DocumentReference> doc = - await initializeTest('vector-value-empty'); + DocumentReference> doc = await initializeTest( + 'vector-value-empty', + ); try { - await doc.set({ - 'foo': const VectorValue([]), - }); + await doc.set({'foo': const VectorValue([])}); fail('Should have thrown an exception'); } catch (e) { expect(e, isA()); @@ -86,8 +87,9 @@ void runVectorValueTests() { }); test('handles single dimension vector', () async { - DocumentReference> doc = - await initializeTest('vector-value-single'); + DocumentReference> doc = await initializeTest( + 'vector-value-single', + ); await doc.set({ 'foo': const VectorValue([42.0]), @@ -102,12 +104,11 @@ void runVectorValueTests() { test('handles maximum dimensions vector', () async { List maxDimensions = List.filled(2048, 1); - DocumentReference> doc = - await initializeTest('vector-value-max-dimensions'); + DocumentReference> doc = await initializeTest( + 'vector-value-max-dimensions', + ); - await doc.set({ - 'foo': VectorValue(maxDimensions), - }); + await doc.set({'foo': VectorValue(maxDimensions)}); DocumentSnapshot> snapshot = await doc.get(); @@ -118,13 +119,12 @@ void runVectorValueTests() { test('handles maximum dimensions + 1 vector', () async { List maxPlusOneDimensions = List.filled(2049, 1); - DocumentReference> doc = - await initializeTest('vector-value-max-plus-one'); + DocumentReference> doc = await initializeTest( + 'vector-value-max-plus-one', + ); try { - await doc.set({ - 'foo': VectorValue(maxPlusOneDimensions), - }); + await doc.set({'foo': VectorValue(maxPlusOneDimensions)}); fail('Should have thrown an exception'); } catch (e) { @@ -137,8 +137,9 @@ void runVectorValueTests() { }); test('handles very large values in vector', () async { - DocumentReference> doc = - await initializeTest('vector-value-large-values'); + DocumentReference> doc = await initializeTest( + 'vector-value-large-values', + ); await doc.set({ 'foo': const VectorValue([1e10, -1e10]), @@ -152,8 +153,9 @@ void runVectorValueTests() { }); test('handles floats in vector', () async { - DocumentReference> doc = - await initializeTest('vector-value-floats'); + DocumentReference> doc = await initializeTest( + 'vector-value-floats', + ); await doc.set({ 'foo': const VectorValue([3.14, 2.718]), @@ -167,8 +169,9 @@ void runVectorValueTests() { }); test('handles negative values in vector', () async { - DocumentReference> doc = - await initializeTest('vector-value-negative'); + DocumentReference> doc = await initializeTest( + 'vector-value-negative', + ); await doc.set({ 'foo': const VectorValue([-42.0, -100.0]), diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/web_snapshot_listeners.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/web_snapshot_listeners.dart index c36bd7eac5a1..a33070bcdd58 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/web_snapshot_listeners.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/web_snapshot_listeners.dart @@ -22,8 +22,9 @@ void runWebSnapshotListenersTests() { late DocumentReference> document2; setUpAll(() async { firestore = FirebaseFirestore.instance; - collection = firestore - .collection('flutter-tests/web-snapshot-listeners/query-tests'); + collection = firestore.collection( + 'flutter-tests/web-snapshot-listeners/query-tests', + ); document = collection.doc('doc1'); document2 = collection.doc('doc1'); @@ -34,43 +35,39 @@ void runWebSnapshotListenersTests() { ]); }); - test( - 'document snapshot listeners in debug', - () async { - Completer completer = Completer(); - Completer completer2 = Completer(); - Completer completer3 = Completer(); - document.snapshots().listen((snapshot) { - if (completer.isCompleted) { - return; - } - completer.complete(true); - }); - - document.snapshots().listen((snapshot) { - if (completer2.isCompleted) { - return; - } - completer2.complete(true); - }); - - document.snapshots().listen((snapshot) { - if (completer3.isCompleted) { - return; - } - completer3.complete(true); - }); - - final one = await completer.future.timeout(_completerTimeout); - final two = await completer2.future.timeout(_completerTimeout); - final three = await completer3.future.timeout(_completerTimeout); - - expect(one, true); - expect(two, true); - expect(three, true); - }, - skip: !kIsWeb, - ); + test('document snapshot listeners in debug', () async { + Completer completer = Completer(); + Completer completer2 = Completer(); + Completer completer3 = Completer(); + document.snapshots().listen((snapshot) { + if (completer.isCompleted) { + return; + } + completer.complete(true); + }); + + document.snapshots().listen((snapshot) { + if (completer2.isCompleted) { + return; + } + completer2.complete(true); + }); + + document.snapshots().listen((snapshot) { + if (completer3.isCompleted) { + return; + } + completer3.complete(true); + }); + + final one = await completer.future.timeout(_completerTimeout); + final two = await completer2.future.timeout(_completerTimeout); + final three = await completer3.future.timeout(_completerTimeout); + + expect(one, true); + expect(two, true); + expect(three, true); + }, skip: !kIsWeb); test( 'document snapshot listeners with different doc refs in debug', @@ -120,79 +117,71 @@ void runWebSnapshotListenersTests() { skip: !kIsWeb, ); - test( - 'query snapshot listeners in debug', - () async { - Completer completer = Completer(); - Completer completer2 = Completer(); - Completer completer3 = Completer(); - collection.snapshots().listen((snapshot) { - if (completer.isCompleted) { - return; - } - completer.complete(true); - }); - - collection.snapshots().listen((snapshot) { - if (completer2.isCompleted) { - return; - } - completer2.complete(true); - }); - - collection.snapshots().listen((snapshot) { - if (completer3.isCompleted) { - return; - } - completer3.complete(true); - }); - final one = await completer.future.timeout(_completerTimeout); - final two = await completer2.future.timeout(_completerTimeout); - final three = await completer3.future.timeout(_completerTimeout); - - expect(one, true); - expect(two, true); - expect(three, true); - }, - skip: !kIsWeb, - ); - - test( - 'snapshot in sync listeners in debug', - () async { - Completer completer = Completer(); - Completer completer2 = Completer(); - Completer completer3 = Completer(); - firestore.snapshotsInSync().listen((snapshot) { - if (completer.isCompleted) { - return; - } - completer.complete(true); - }); - - firestore.snapshotsInSync().listen((snapshot) { - if (completer2.isCompleted) { - return; - } - completer2.complete(true); - }); - - firestore.snapshotsInSync().listen((snapshot) { - if (completer3.isCompleted) { - return; - } - completer3.complete(true); - }); - - final one = await completer.future.timeout(_completerTimeout); - final two = await completer2.future.timeout(_completerTimeout); - final three = await completer3.future.timeout(_completerTimeout); - - expect(one, true); - expect(two, true); - expect(three, true); - }, - skip: !kIsWeb, - ); + test('query snapshot listeners in debug', () async { + Completer completer = Completer(); + Completer completer2 = Completer(); + Completer completer3 = Completer(); + collection.snapshots().listen((snapshot) { + if (completer.isCompleted) { + return; + } + completer.complete(true); + }); + + collection.snapshots().listen((snapshot) { + if (completer2.isCompleted) { + return; + } + completer2.complete(true); + }); + + collection.snapshots().listen((snapshot) { + if (completer3.isCompleted) { + return; + } + completer3.complete(true); + }); + final one = await completer.future.timeout(_completerTimeout); + final two = await completer2.future.timeout(_completerTimeout); + final three = await completer3.future.timeout(_completerTimeout); + + expect(one, true); + expect(two, true); + expect(three, true); + }, skip: !kIsWeb); + + test('snapshot in sync listeners in debug', () async { + Completer completer = Completer(); + Completer completer2 = Completer(); + Completer completer3 = Completer(); + firestore.snapshotsInSync().listen((snapshot) { + if (completer.isCompleted) { + return; + } + completer.complete(true); + }); + + firestore.snapshotsInSync().listen((snapshot) { + if (completer2.isCompleted) { + return; + } + completer2.complete(true); + }); + + firestore.snapshotsInSync().listen((snapshot) { + if (completer3.isCompleted) { + return; + } + completer3.complete(true); + }); + + final one = await completer.future.timeout(_completerTimeout); + final two = await completer2.future.timeout(_completerTimeout); + final three = await completer3.future.timeout(_completerTimeout); + + expect(one, true); + expect(two, true); + expect(three, true); + }, skip: !kIsWeb); }); } diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/write_batch_e2e.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/write_batch_e2e.dart index 5853c56da4bb..e3171e705ed2 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/write_batch_e2e.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/write_batch_e2e.dart @@ -16,8 +16,8 @@ void runWriteBatchTests() { Future>> initializeTest( String id, ) async { - CollectionReference> collection = - firestore.collection('flutter-tests/$id/query-tests'); + CollectionReference> collection = firestore + .collection('flutter-tests/$id/query-tests'); QuerySnapshot> snapshot = await collection.get(); await Future.forEach(snapshot.docs, ( @@ -33,7 +33,9 @@ void runWriteBatchTests() { await initializeTest('with-converter-batch'); WriteBatch batch = firestore.batch(); - DocumentReference doc = collection.doc('doc1').withConverter( + DocumentReference doc = collection + .doc('doc1') + .withConverter( fromFirestore: (snapshot, options) { return snapshot.data()!['value'] as int; }, @@ -75,7 +77,9 @@ void runWriteBatchTests() { await initializeTest('with-converter-batch-update'); WriteBatch batch = firestore.batch(); - DocumentReference doc = collection.doc('doc1').withConverter( + DocumentReference doc = collection + .doc('doc1') + .withConverter( fromFirestore: (snapshot, options) { return snapshot.data()!['value'] as int; }, @@ -104,10 +108,7 @@ void runWriteBatchTests() { toFirestore: (value, options) => value.toFirestore(), ); - await rawDoc.set({ - 'existing': 'preserved', - 'name': 'before', - }); + await rawDoc.set({'existing': 'preserved', 'name': 'before'}); WriteBatch batch = firestore.batch(); batch.update<_WriteBatchProfile>( @@ -117,10 +118,7 @@ void runWriteBatchTests() { score: 42, address: _WriteBatchAddress(city: 'London', postcode: 'NW1'), tags: ['admin', 'tester'], - preferences: { - 'email': true, - 'theme': 'dark', - }, + preferences: {'email': true, 'theme': 'dark'}, nickname: null, ), ); @@ -132,15 +130,9 @@ void runWriteBatchTests() { 'existing': 'preserved', 'name': 'Ada', 'score': 42, - 'address': { - 'city': 'London', - 'postcode': 'NW1', - }, + 'address': {'city': 'London', 'postcode': 'NW1'}, 'tags': ['admin', 'tester'], - 'preferences': { - 'email': true, - 'theme': 'dark', - }, + 'preferences': {'email': true, 'theme': 'dark'}, 'nickname': null, }); @@ -151,10 +143,7 @@ void runWriteBatchTests() { expect(profile.address.city, 'London'); expect(profile.address.postcode, 'NW1'); expect(profile.tags, ['admin', 'tester']); - expect(profile.preferences, { - 'email': true, - 'theme': 'dark', - }); + expect(profile.preferences, {'email': true, 'theme': 'dark'}); expect(profile.nickname, isNull); }); @@ -185,16 +174,21 @@ void runWriteBatchTests() { await initializeTest('write-batch-ops'); WriteBatch batch = firestore.batch(); - DocumentReference> doc1 = - collection.doc('doc1'); // delete - DocumentReference> doc2 = - collection.doc('doc2'); // set - DocumentReference> doc3 = - collection.doc('doc3'); // update - DocumentReference> doc4 = - collection.doc('doc4'); // update w/ merge - DocumentReference> doc5 = - collection.doc('doc5'); // update w/ mergeFields + DocumentReference> doc1 = collection.doc( + 'doc1', + ); // delete + DocumentReference> doc2 = collection.doc( + 'doc2', + ); // set + DocumentReference> doc3 = collection.doc( + 'doc3', + ); // update + DocumentReference> doc4 = collection.doc( + 'doc4', + ); // update w/ merge + DocumentReference> doc5 = collection.doc( + 'doc5', + ); // update w/ mergeFields await Future.wait([ doc1.set({'foo': 'bar'}), @@ -209,11 +203,9 @@ void runWriteBatchTests() { batch.update(doc3, {'bar': 'ben'}); batch.set(doc4, {'bar': 'ben'}, SetOptions(merge: true)); - batch.set( - doc5, - {'bar': 'ben'}, - SetOptions(mergeFields: ['bar']), - ); + batch.set(doc5, { + 'bar': 'ben', + }, SetOptions(mergeFields: ['bar'])); await batch.commit(); @@ -285,10 +277,7 @@ class _WriteBatchProfile { } class _WriteBatchAddress { - _WriteBatchAddress({ - required this.city, - required this.postcode, - }); + _WriteBatchAddress({required this.city, required this.postcode}); factory _WriteBatchAddress.fromFirestore(Map data) { return _WriteBatchAddress( @@ -301,9 +290,6 @@ class _WriteBatchAddress { final String postcode; Map toFirestore() { - return { - 'city': city, - 'postcode': postcode, - }; + return {'city': city, 'postcode': postcode}; } } diff --git a/packages/cloud_firestore/cloud_firestore/example/lib/firebase_options.dart b/packages/cloud_firestore/cloud_firestore/example/lib/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/cloud_firestore/cloud_firestore/example/lib/firebase_options.dart +++ b/packages/cloud_firestore/cloud_firestore/example/lib/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/cloud_firestore/cloud_firestore/example/lib/main.dart b/packages/cloud_firestore/cloud_firestore/example/lib/main.dart index df1d30dfd6dc..7c1a7c4cf82d 100755 --- a/packages/cloud_firestore/cloud_firestore/example/lib/main.dart +++ b/packages/cloud_firestore/cloud_firestore/example/lib/main.dart @@ -19,8 +19,10 @@ bool shouldUseFirestoreEmulator = true; Future loadBundleSetup(int number) async { // endpoint serves a bundle with 3 documents each containing // a 'number' property that increments in value 1-3. - final url = - Uri.https('api.rnfirebase.io', '/firestore/e2e-tests/bundle-$number'); + final url = Uri.https( + 'api.rnfirebase.io', + '/firestore/e2e-tests/bundle-$number', + ); final response = await http.get(url); String string = response.body; return Uint8List.fromList(string.codeUnits); @@ -50,14 +52,7 @@ final moviesRef = FirebaseFirestore.instance ); /// The different ways that we can filter/sort movies. -enum MovieQuery { - year, - likesAsc, - likesDesc, - rated, - sciFi, - fantasy, -} +enum MovieQuery { year, likesAsc, likesDesc, rated, sciFi, fantasy } extension on Query { /// Create a firebase query from a [MovieQuery] @@ -65,11 +60,12 @@ extension on Query { return switch (query) { MovieQuery.fantasy => where('genre', arrayContainsAny: ['fantasy']), MovieQuery.sciFi => where('genre', arrayContainsAny: ['sci-fi']), - MovieQuery.likesAsc || - MovieQuery.likesDesc => - orderBy('likes', descending: query == MovieQuery.likesDesc), + MovieQuery.likesAsc || MovieQuery.likesDesc => orderBy( + 'likes', + descending: query == MovieQuery.likesDesc, + ), MovieQuery.year => orderBy('year', descending: true), - MovieQuery.rated => orderBy('rated', descending: true) + MovieQuery.rated => orderBy('rated', descending: true), }; } } @@ -83,9 +79,7 @@ class FirestoreExampleApp extends StatelessWidget { return MaterialApp( title: 'Firestore Example App', theme: ThemeData.dark(), - home: const Scaffold( - body: Center(child: FilmList()), - ), + home: const Scaffold(body: Center(child: FilmList())), ); } } @@ -190,47 +184,34 @@ class _FilmListState extends State { // In one query final _all = await FirebaseFirestore.instance .collection('firestore-example-app') - .aggregate( - average('likes'), - sum('likes'), - count(), - ) + .aggregate(average('likes'), sum('likes'), count()) .get(); - print('Average: ${_all.getAverage('likes')} ' - 'Sum: ${_all.getSum('likes')} ' - 'Count: ${_all.count}'); + print( + 'Average: ${_all.getAverage('likes')} ' + 'Sum: ${_all.getSum('likes')} ' + 'Count: ${_all.count}', + ); return; case 'load_bundle': Uint8List buffer = await loadBundleSetup(2); - LoadBundleTask task = - FirebaseFirestore.instance.loadBundle(buffer); + LoadBundleTask task = FirebaseFirestore.instance.loadBundle( + buffer, + ); final list = await task.stream.toList(); - print( - list.map((e) => e.totalDocuments), - ); - print( - list.map((e) => e.bytesLoaded), - ); - print( - list.map((e) => e.documentsLoaded), - ); - print( - list.map((e) => e.totalBytes), - ); - print( - list, - ); + print(list.map((e) => e.totalDocuments)); + print(list.map((e) => e.bytesLoaded)); + print(list.map((e) => e.documentsLoaded)); + print(list.map((e) => e.totalBytes)); + print(list); LoadBundleTaskSnapshot lastSnapshot = list.removeLast(); print(lastSnapshot.taskState); - print( - list.map((e) => e.taskState), - ); + print(list.map((e) => e.taskState)); return; case 'vectorValue': const vectorValue = VectorValue([1.0, 2.0, 3.0]); @@ -272,9 +253,7 @@ class _FilmListState extends State { stream: moviesRef.queryBy(query).snapshots(), builder: (context, snapshot) { if (snapshot.hasError) { - return Center( - child: Text(snapshot.error.toString()), - ); + return Center(child: Text(snapshot.error.toString())); } if (!snapshot.hasData) { @@ -322,10 +301,7 @@ class _MovieItem extends StatelessWidget { /// Returns the movie poster. Widget get poster { - return SizedBox( - width: 100, - child: Image.network(movie.poster), - ); + return SizedBox(width: 100, child: Image.network(movie.poster)); } /// Returns movie details. @@ -338,10 +314,7 @@ class _MovieItem extends StatelessWidget { title, metadata, genres, - Likes( - reference: reference, - currentLikes: movie.likes, - ), + Likes(reference: reference, currentLikes: movie.likes), ], ), ); @@ -380,10 +353,7 @@ class _MovieItem extends StatelessWidget { padding: const EdgeInsets.only(right: 2), child: Chip( backgroundColor: Colors.lightBlue, - label: Text( - genre, - style: const TextStyle(color: Colors.white), - ), + label: Text(genre, style: const TextStyle(color: Colors.white)), ), ), ]; @@ -393,9 +363,7 @@ class _MovieItem extends StatelessWidget { Widget get genres { return Padding( padding: const EdgeInsets.only(top: 8), - child: Wrap( - children: genreItems, - ), + child: Wrap(children: genreItems), ); } @@ -418,11 +386,8 @@ class _MovieItem extends StatelessWidget { class Likes extends StatefulWidget { /// Constructs a new [Likes] instance with a given [DocumentReference] and /// current like count. - Likes({ - Key? key, - required this.reference, - required this.currentLikes, - }) : super(key: key); + Likes({Key? key, required this.reference, required this.currentLikes}) + : super(key: key); /// The reference relating to the counter. final DocumentReference reference; @@ -452,10 +417,12 @@ class _LikesState extends State { // We use a transaction because multiple users could update the likes count // simultaneously. As such, our likes count may be different from the likes // count on the server. - int newLikes = await FirebaseFirestore.instance - .runTransaction((transaction) async { - DocumentSnapshot movie = - await transaction.get(widget.reference); + int newLikes = await FirebaseFirestore.instance.runTransaction(( + transaction, + ) async { + DocumentSnapshot movie = await transaction.get( + widget.reference, + ); if (!movie.exists) { throw Exception('Document does not exist!'); @@ -516,15 +483,15 @@ class Movie { }); Movie.fromJson(Map json) - : this( - genre: (json['genre']! as List).cast(), - likes: json['likes']! as int, - poster: json['poster']! as String, - rated: json['rated']! as String, - runtime: json['runtime']! as String, - title: json['title']! as String, - year: json['year']! as int, - ); + : this( + genre: (json['genre']! as List).cast(), + likes: json['likes']! as int, + poster: json['poster']! as String, + rated: json['rated']! as String, + runtime: json['runtime']! as String, + title: json['title']! as String, + year: json['year']! as int, + ); final String poster; final int likes; diff --git a/packages/cloud_firestore/cloud_firestore/example/pubspec.yaml b/packages/cloud_firestore/cloud_firestore/example/pubspec.yaml index a32c2dd15014..a917d1ebefe9 100755 --- a/packages/cloud_firestore/cloud_firestore/example/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the firestore plugin. resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: cloud_firestore: ^6.9.0 diff --git a/packages/cloud_firestore/cloud_firestore/example/test_driver/integration_test.dart b/packages/cloud_firestore/cloud_firestore/example/test_driver/integration_test.dart index 691723cbbfe1..9ccbcc26ab97 100644 --- a/packages/cloud_firestore/cloud_firestore/example/test_driver/integration_test.dart +++ b/packages/cloud_firestore/cloud_firestore/example/test_driver/integration_test.dart @@ -7,28 +7,32 @@ import 'dart:io'; import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver( - writeResponseOnFailure: true, - responseDataCallback: (Map? data) async { - final results = - (data?['testResults'] as Map?)?.cast() ?? - const {}; - var passed = 0; - var failed = 0; - for (final entry in results.entries) { - final ok = entry.value == 'success'; - ok ? passed++ : failed++; - // ignore: avoid_print - print('${ok ? '✅' : '❌'} ${entry.key}'); - } - // ignore: avoid_print - print('Web e2e summary: $passed passed, $failed failed, ' - '${results.length} total'); - if (results.isEmpty) { - // ignore: avoid_print - print('[E] No tests reported by the app - treating as ' - 'infrastructure failure.'); - exit(1); - } - await writeResponseData(data); - }, + writeResponseOnFailure: true, + responseDataCallback: (Map? data) async { + final results = + (data?['testResults'] as Map?)?.cast() ?? + const {}; + var passed = 0; + var failed = 0; + for (final entry in results.entries) { + final ok = entry.value == 'success'; + ok ? passed++ : failed++; + // ignore: avoid_print + print('${ok ? '✅' : '❌'} ${entry.key}'); + } + // ignore: avoid_print + print( + 'Web e2e summary: $passed passed, $failed failed, ' + '${results.length} total', ); + if (results.isEmpty) { + // ignore: avoid_print + print( + '[E] No tests reported by the app - treating as ' + 'infrastructure failure.', + ); + exit(1); + } + await writeResponseData(data); + }, +); diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart index 12f30fb58fbd..7b1e83219197 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart @@ -124,11 +124,7 @@ class _JsonCollectionReference extends _JsonQuery required FromFirestore fromFirestore, required ToFirestore toFirestore, }) { - return _WithConverterCollectionReference( - this, - fromFirestore, - toFirestore, - ); + return _WithConverterCollectionReference(this, fromFirestore, toFirestore); } @override @@ -150,7 +146,8 @@ class _JsonCollectionReference extends _JsonQuery /// inherited from [Query]). @immutable class _WithConverterCollectionReference - extends _WithConverterQuery implements CollectionReference { + extends _WithConverterQuery + implements CollectionReference { _WithConverterCollectionReference( CollectionReference> collectionReference, FromFirestore fromFirestore, @@ -158,7 +155,7 @@ class _WithConverterCollectionReference ) : super(collectionReference, fromFirestore, toFirestore); CollectionReference> - get _originalCollectionReferenceQuery { + get _originalCollectionReferenceQuery { return super._originalQuery as CollectionReference>; } @@ -218,11 +215,11 @@ class _WithConverterCollectionReference @override int get hashCode => Object.hash( - runtimeType, - _originalCollectionReferenceQuery, - _fromFirestore, - _toFirestore, - ); + runtimeType, + _originalCollectionReferenceQuery, + _fromFirestore, + _toFirestore, + ); @override String toString() => 'CollectionReference<$T>($path)'; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart index d3cf3a67ce95..1eb51ed250e0 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart @@ -145,9 +145,7 @@ class _JsonDocumentReference ]) async { return _JsonDocumentSnapshot( firestore, - await _delegate.get( - options ?? const GetOptions(), - ), + await _delegate.get(options ?? const GetOptions()), ); } @@ -184,8 +182,9 @@ class _JsonDocumentReference @override Future update(Map data) { - return _delegate - .update(_CodecUtility.replaceValueWithDelegatesInMapFieldPath(data)!); + return _delegate.update( + _CodecUtility.replaceValueWithDelegatesInMapFieldPath(data)!, + ); } @override @@ -273,10 +272,7 @@ class _WithConverterDocumentReference @override Future set(T data, [SetOptions? options]) { - return _originalDocumentReference.set( - _toFirestore(data, options), - options, - ); + return _originalDocumentReference.set(_toFirestore(data, options), options); } @override @@ -286,16 +282,16 @@ class _WithConverterDocumentReference }) { return _originalDocumentReference .snapshots( - includeMetadataChanges: includeMetadataChanges, - source: source, - ) + includeMetadataChanges: includeMetadataChanges, + source: source, + ) .map((snapshot) { - return _WithConverterDocumentSnapshot( - snapshot, - _fromFirestore, - _toFirestore, - ); - }); + return _WithConverterDocumentSnapshot( + snapshot, + _fromFirestore, + _toFirestore, + ); + }); } @override @@ -325,11 +321,11 @@ class _WithConverterDocumentReference @override int get hashCode => Object.hash( - runtimeType, - _originalDocumentReference, - _fromFirestore, - _toFirestore, - ); + runtimeType, + _originalDocumentReference, + _fromFirestore, + _toFirestore, + ); @override String toString() => 'DocumentReference<$T>($path)'; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart index ed86458516e3..521b753f70a0 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart @@ -4,14 +4,13 @@ part of '../cloud_firestore.dart'; -typedef FromFirestore = T Function( - DocumentSnapshot> snapshot, - SnapshotOptions? options, -); -typedef ToFirestore = Map Function( - T value, - SetOptions? options, -); +typedef FromFirestore = + T Function( + DocumentSnapshot> snapshot, + SnapshotOptions? options, + ); +typedef ToFirestore = + Map Function(T value, SetOptions? options); /// Options that configure how data is retrieved from a DocumentSnapshot /// (e.g. the desired behavior for server timestamps that have not yet been set to their final value). @@ -69,8 +68,9 @@ class _JsonDocumentSnapshot implements DocumentSnapshot> { String get id => _delegate.id; @override - late final DocumentReference> reference = - _firestore.doc(_delegate.reference.path); + late final DocumentReference> reference = _firestore.doc( + _delegate.reference.path, + ); @override late final SnapshotMetadata metadata = SnapshotMetadata._(_delegate.metadata); @@ -130,10 +130,10 @@ class _WithConverterDocumentSnapshot implements DocumentSnapshot { @override DocumentReference get reference => _WithConverterDocumentReference( - _originalDocumentSnapshot.reference, - _fromFirestore, - _toFirestore, - ); + _originalDocumentSnapshot.reference, + _fromFirestore, + _toFirestore, + ); @override dynamic get(Object field) => _originalDocumentSnapshot.get(field); diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/filters.dart b/packages/cloud_firestore/cloud_firestore/lib/src/filters.dart index 83ee35b1e9af..aa6a451f0885 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/filters.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/filters.dart @@ -12,7 +12,7 @@ class _FilterObject { class _FilterQuery extends _FilterObject { _FilterQuery(this._field, this._operator, this._value) - : assert(_field is FieldPathType || _field is FieldPath); + : assert(_field is FieldPathType || _field is FieldPath); final Object _field; final String _operator; @@ -50,11 +50,11 @@ class Filter extends FilterPlatformInterface { late final _FilterOperator? _filterOperator; Filter._(this._filterQuery, this._filterOperator) - : assert( - (_filterQuery != null && _filterOperator == null) || - (_filterQuery == null && _filterOperator != null), - 'Exactly one operator must be specified', - ); + : assert( + (_filterQuery != null && _filterOperator == null) || + (_filterQuery == null && _filterOperator != null), + 'Exactly one operator must be specified', + ); /// A [Filter] represents a restriction on one or more field values and can be used to refine /// the results of a [Query]. @@ -63,6 +63,7 @@ class Filter extends FilterPlatformInterface { Filter( /// The field or [FieldPath] to filter on. Object field, { + /// Creates a new filter for checking that the given field is equal to the given value. Object? isEqualTo, @@ -95,29 +96,24 @@ class Filter extends FilterPlatformInterface { /// Creates a new filter for checking that the given field is null. bool? isNull, - }) : assert( - () { - final operators = [ - isEqualTo, - isNotEqualTo, - isLessThan, - isLessThanOrEqualTo, - isGreaterThan, - isGreaterThanOrEqualTo, - arrayContains, - arrayContainsAny, - whereIn, - whereNotIn, - isNull, - ]; - final operatorsUsed = operators.where((e) => e != null).length; - return operatorsUsed == 1; - }(), - 'Exactly one operator must be specified', - ), - assert( - field is String || field is FieldPath || field is FieldPathType, - ) { + }) : assert(() { + final operators = [ + isEqualTo, + isNotEqualTo, + isLessThan, + isLessThanOrEqualTo, + isGreaterThan, + isGreaterThanOrEqualTo, + arrayContains, + arrayContainsAny, + whereIn, + whereNotIn, + isNull, + ]; + final operatorsUsed = operators.where((e) => e != null).length; + return operatorsUsed == 1; + }(), 'Exactly one operator must be specified'), + assert(field is String || field is FieldPath || field is FieldPathType) { final _field = (field is String ? FieldPath.fromString(field) : field); _filterQuery = _FilterQuery( @@ -225,10 +221,9 @@ class Filter extends FilterPlatformInterface { /// A disjunction filter includes a document if it satisfies any of the given filters. static Filter or( Filter filter1, - Filter filter2, + Filter filter2, [ // Number of OR operation is limited on the server side // We let here 30 as a limit - [ Filter? filter3, Filter? filter4, Filter? filter5, @@ -258,41 +253,38 @@ class Filter extends FilterPlatformInterface { Filter? filter29, Filter? filter30, ]) { - return _generateFilter( - 'OR', - [ - filter1, - filter2, - filter3, - filter4, - filter5, - filter6, - filter7, - filter8, - filter9, - filter10, - filter11, - filter12, - filter13, - filter14, - filter15, - filter16, - filter17, - filter18, - filter19, - filter20, - filter21, - filter22, - filter23, - filter24, - filter25, - filter26, - filter27, - filter28, - filter29, - filter30, - ], - ); + return _generateFilter('OR', [ + filter1, + filter2, + filter3, + filter4, + filter5, + filter6, + filter7, + filter8, + filter9, + filter10, + filter11, + filter12, + filter13, + filter14, + filter15, + filter16, + filter17, + filter18, + filter19, + filter20, + filter21, + filter22, + filter23, + filter24, + filter25, + filter26, + filter27, + filter28, + filter29, + filter30, + ]); } /// Creates a new filter that is a conjunction of the given filters. @@ -330,66 +322,54 @@ class Filter extends FilterPlatformInterface { Filter? filter29, Filter? filter30, ]) { - return _generateFilter( - 'AND', - [ - filter1, - filter2, - filter3, - filter4, - filter5, - filter6, - filter7, - filter8, - filter9, - filter10, - filter11, - filter12, - filter13, - filter14, - filter15, - filter16, - filter17, - filter18, - filter19, - filter20, - filter21, - filter22, - filter23, - filter24, - filter25, - filter26, - filter27, - filter28, - filter29, - filter30, - ], - ); + return _generateFilter('AND', [ + filter1, + filter2, + filter3, + filter4, + filter5, + filter6, + filter7, + filter8, + filter9, + filter10, + filter11, + filter12, + filter13, + filter14, + filter15, + filter16, + filter17, + filter18, + filter19, + filter20, + filter21, + filter22, + filter23, + filter24, + filter25, + filter26, + filter27, + filter28, + filter29, + filter30, + ]); } - static Filter _generateFilter( - String operator, - List filters, - ) { - assert( - () { - final filtersUsed = filters.where((e) => e != null).length; - return filtersUsed >= 2; - }(), - 'At least two filters must be specified', - ); + static Filter _generateFilter(String operator, List filters) { + assert(() { + final filtersUsed = filters.where((e) => e != null).length; + return filtersUsed >= 2; + }(), 'At least two filters must be specified'); return Filter._( null, - _FilterOperator( - operator, - [ - for (final filter in filters) - if (filter != null && filter._filterQuery != null) - filter._filterQuery - else if (filter != null && filter._filterOperator != null) - filter._filterOperator, - ], - ), + _FilterOperator(operator, [ + for (final filter in filters) + if (filter != null && filter._filterQuery != null) + filter._filterQuery + else if (filter != null && filter._filterOperator != null) + filter._filterOperator, + ]), ); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index 3c51c65d55c3..1ed0af8df597 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -16,18 +16,14 @@ part of '../cloud_firestore.dart'; /// FirebaseFirestore firestore = FirebaseFirestore.instanceFor(app: secondaryApp); /// ``` class FirebaseFirestore extends FirebasePlugin { - FirebaseFirestore._({ - required this.app, - required this.databaseId, - }) : super(app.name, 'plugins.flutter.io/firebase_firestore'); + FirebaseFirestore._({required this.app, required this.databaseId}) + : super(app.name, 'plugins.flutter.io/firebase_firestore'); static final Map _cachedInstances = {}; /// Returns an instance using the default [FirebaseApp]. static FirebaseFirestore get instance { - return FirebaseFirestore.instanceFor( - app: Firebase.app(), - ); + return FirebaseFirestore.instanceFor(app: Firebase.app()); } /// Returns an instance using a specified [FirebaseApp]. @@ -175,8 +171,10 @@ class FirebaseFirestore extends FirebasePlugin { String name, { GetOptions options = const GetOptions(), }) async { - QuerySnapshotPlatform snapshotDelegate = - await _delegate.namedQueryGet(name, options: options); + QuerySnapshotPlatform snapshotDelegate = await _delegate.namedQueryGet( + name, + options: options, + ); return _JsonQuerySnapshot(FirebaseFirestore.instance, snapshotDelegate); } @@ -330,12 +328,10 @@ class FirebaseFirestore extends FirebasePlugin { ); } - PersistentCacheIndexManagerPlatform? indexManager = - _delegate.persistentCacheIndexManager(); + PersistentCacheIndexManagerPlatform? indexManager = _delegate + .persistentCacheIndexManager(); if (indexManager != null) { - return PersistentCacheIndexManager._( - indexManager, - ); + return PersistentCacheIndexManager._(indexManager); } return null; } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/pipeline.dart b/packages/cloud_firestore/cloud_firestore/lib/src/pipeline.dart index 55ca21d79f47..bb0685d7d13e 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/pipeline.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/pipeline.dart @@ -65,9 +65,7 @@ class Pipeline { /// ``` Future execute({ExecuteOptions? options}) async { final optionsMap = options != null - ? { - 'indexMode': options.indexMode.name, - } + ? {'indexMode': options.indexMode.name} : null; final platformSnapshot = await _delegate.execute(options: optionsMap); return _convertPlatformSnapshot(platformSnapshot); @@ -172,10 +170,7 @@ class Pipeline { if (selectable29 != null) selectables.add(selectable29); if (selectable30 != null) selectables.add(selectable30); final stage = _AddFieldsStage(selectables); - return Pipeline._( - _firestore, - _delegate.addStage(stage.toMap()), - ); + return Pipeline._(_firestore, _delegate.addStage(stage.toMap())); } /// Performs aggregation operations on the documents from previous stages. @@ -258,10 +253,7 @@ class Pipeline { if (aggregateFunction30 != null) functions.add(aggregateFunction30); final stage = _AggregateStage(functions); - return Pipeline._( - _firestore, - _delegate.addStage(stage.toMap()), - ); + return Pipeline._(_firestore, _delegate.addStage(stage.toMap())); } /// Performs optionally grouped aggregation operations on the documents from previous stages. @@ -310,10 +302,7 @@ class Pipeline { aggregateStage, options ?? AggregateOptions(), ); - return Pipeline._( - _firestore, - _delegate.addStage(stage.toMap()), - ); + return Pipeline._(_firestore, _delegate.addStage(stage.toMap())); } /// Returns a set of distinct values from the inputs to this stage. @@ -392,10 +381,7 @@ class Pipeline { if (expression30 != null) expressions.add(expression30); final stage = _DistinctStage(expressions); - return Pipeline._( - _firestore, - _delegate.addStage(stage.toMap()), - ); + return Pipeline._(_firestore, _delegate.addStage(stage.toMap())); } /// Performs a vector similarity search. @@ -427,10 +413,7 @@ class Pipeline { distanceMeasure, limit: limit, ); - return Pipeline._( - _firestore, - _delegate.addStage(stage.toMap()), - ); + return Pipeline._(_firestore, _delegate.addStage(stage.toMap())); } /// Adds a search stage to this pipeline. @@ -452,10 +435,7 @@ class Pipeline { } final stage = _SearchStage(searchStage); - return Pipeline._( - _firestore, - _delegate.addStage(stage.toMap()), - ); + return Pipeline._(_firestore, _delegate.addStage(stage.toMap())); } /// Limits the maximum number of documents returned by previous stages to @@ -472,10 +452,7 @@ class Pipeline { /// ``` Pipeline limit(int limit) { final stage = _LimitStage(limit); - return Pipeline._( - _firestore, - _delegate.addStage(stage.toMap()), - ); + return Pipeline._(_firestore, _delegate.addStage(stage.toMap())); } /// Skips the first [offset] documents from the results of previous stages. @@ -492,10 +469,7 @@ class Pipeline { /// ``` Pipeline offset(int offset) { final stage = _OffsetStage(offset); - return Pipeline._( - _firestore, - _delegate.addStage(stage.toMap()), - ); + return Pipeline._(_firestore, _delegate.addStage(stage.toMap())); } /// Removes fields from outputs of previous stages. @@ -569,10 +543,7 @@ class Pipeline { if (fieldPath30 != null) fieldPaths.add(fieldPath30); final stage = _RemoveFieldsStage(fieldPaths); - return Pipeline._( - _firestore, - _delegate.addStage(stage.toMap()), - ); + return Pipeline._(_firestore, _delegate.addStage(stage.toMap())); } /// Fully overwrites each document with the value of the given expression. @@ -589,10 +560,7 @@ class Pipeline { /// ``` Pipeline replaceWith(Expression expression) { final stage = _ReplaceWithStage(expression); - return Pipeline._( - _firestore, - _delegate.addStage(stage.toMap()), - ); + return Pipeline._(_firestore, _delegate.addStage(stage.toMap())); } /// Performs a pseudo-random sampling of the input documents. @@ -609,10 +577,7 @@ class Pipeline { /// ``` Pipeline sample(PipelineSample sample) { final stage = _SampleStage(sample); - return Pipeline._( - _firestore, - _delegate.addStage(stage.toMap()), - ); + return Pipeline._(_firestore, _delegate.addStage(stage.toMap())); } /// Selects or creates a set of fields from the outputs of previous stages. @@ -692,10 +657,7 @@ class Pipeline { if (expression30 != null) expressions.add(expression30); final stage = _SelectStage(expressions); - return Pipeline._( - _firestore, - _delegate.addStage(stage.toMap()), - ); + return Pipeline._(_firestore, _delegate.addStage(stage.toMap())); } /// Sorts the documents from previous stages based on one or more orderings. @@ -776,10 +738,7 @@ class Pipeline { if (order30 != null) orderings.add(order30); final stage = _SortStage(orderings); - return Pipeline._( - _firestore, - _delegate.addStage(stage.toMap()), - ); + return Pipeline._(_firestore, _delegate.addStage(stage.toMap())); } /// Takes a specified array from the input documents and outputs a document @@ -799,10 +758,7 @@ class Pipeline { /// ``` Pipeline unnest(Selectable expression, [String? indexField]) { final stage = _UnnestStage(expression, indexField); - return Pipeline._( - _firestore, - _delegate.addStage(stage.toMap()), - ); + return Pipeline._(_firestore, _delegate.addStage(stage.toMap())); } /// Performs a union of all documents from this pipeline and [pipeline], @@ -819,10 +775,7 @@ class Pipeline { /// ``` Pipeline union(Pipeline pipeline) { final stage = _UnionStage(pipeline); - return Pipeline._( - _firestore, - _delegate.addStage(stage.toMap()), - ); + return Pipeline._(_firestore, _delegate.addStage(stage.toMap())); } /// Filters the documents from previous stages to only include those matching @@ -844,9 +797,6 @@ class Pipeline { /// ``` Pipeline where(BooleanExpression expression) { final stage = _WhereStage(expression); - return Pipeline._( - _firestore, - _delegate.addStage(stage.toMap()), - ); + return Pipeline._(_firestore, _delegate.addStage(stage.toMap())); } } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_aggregate.dart b/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_aggregate.dart index 7598f42a947a..19430073bba9 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_aggregate.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_aggregate.dart @@ -8,19 +8,14 @@ part of '../cloud_firestore.dart'; abstract class PipelineAggregateFunction implements PipelineSerializable { /// Assigns an alias to this aggregate function AliasedAggregateFunction as(String alias) { - return AliasedAggregateFunction( - alias: alias, - aggregateFunction: this, - ); + return AliasedAggregateFunction(alias: alias, aggregateFunction: this); } String get name; @override Map toMap() { - return { - 'name': name, - }; + return {'name': name}; } } @@ -68,9 +63,7 @@ class Count extends PipelineAggregateFunction { @override Map toMap() { final map = super.toMap(); - map['args'] = { - 'expression': expression.toMap(), - }; + map['args'] = {'expression': expression.toMap()}; return map; } } @@ -87,9 +80,7 @@ class Sum extends PipelineAggregateFunction { @override Map toMap() { final map = super.toMap(); - map['args'] = { - 'expression': expression.toMap(), - }; + map['args'] = {'expression': expression.toMap()}; return map; } } @@ -106,9 +97,7 @@ class Average extends PipelineAggregateFunction { @override Map toMap() { final map = super.toMap(); - map['args'] = { - 'expression': expression.toMap(), - }; + map['args'] = {'expression': expression.toMap()}; return map; } } @@ -125,9 +114,7 @@ class CountDistinct extends PipelineAggregateFunction { @override Map toMap() { final map = super.toMap(); - map['args'] = { - 'expression': expression.toMap(), - }; + map['args'] = {'expression': expression.toMap()}; return map; } } @@ -144,9 +131,7 @@ class Minimum extends PipelineAggregateFunction { @override Map toMap() { final map = super.toMap(); - map['args'] = { - 'expression': expression.toMap(), - }; + map['args'] = {'expression': expression.toMap()}; return map; } } @@ -163,9 +148,7 @@ class Maximum extends PipelineAggregateFunction { @override Map toMap() { final map = super.toMap(); - map['args'] = { - 'expression': expression.toMap(), - }; + map['args'] = {'expression': expression.toMap()}; return map; } } @@ -185,9 +168,7 @@ class First extends PipelineAggregateFunction { @override Map toMap() { final map = super.toMap(); - map['args'] = { - 'expression': expression.toMap(), - }; + map['args'] = {'expression': expression.toMap()}; return map; } } @@ -207,9 +188,7 @@ class Last extends PipelineAggregateFunction { @override Map toMap() { final map = super.toMap(); - map['args'] = { - 'expression': expression.toMap(), - }; + map['args'] = {'expression': expression.toMap()}; return map; } } @@ -229,9 +208,7 @@ class ArrayAgg extends PipelineAggregateFunction { @override Map toMap() { final map = super.toMap(); - map['args'] = { - 'expression': expression.toMap(), - }; + map['args'] = {'expression': expression.toMap()}; return map; } } @@ -251,9 +228,7 @@ class ArrayAggDistinct extends PipelineAggregateFunction { @override Map toMap() { final map = super.toMap(); - map['args'] = { - 'expression': expression.toMap(), - }; + map['args'] = {'expression': expression.toMap()}; return map; } } @@ -263,10 +238,7 @@ class AggregateStageOptions implements PipelineSerializable { final List accumulators; final List? groups; - AggregateStageOptions({ - required this.accumulators, - this.groups, - }); + AggregateStageOptions({required this.accumulators, this.groups}); @override Map toMap() { diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_execute_options.dart b/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_execute_options.dart index ee8b8e2eb42d..191545f1651e 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_execute_options.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_execute_options.dart @@ -14,7 +14,5 @@ enum IndexMode { class ExecuteOptions { final IndexMode indexMode; - const ExecuteOptions({ - this.indexMode = IndexMode.recommended, - }); + const ExecuteOptions({this.indexMode = IndexMode.recommended}); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_expression.dart b/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_expression.dart index c6de9cc82c21..8b2ed0d9059b 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_expression.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_expression.dart @@ -168,10 +168,7 @@ enum Type { abstract class Expression implements PipelineSerializable { /// Creates an aliased expression AliasedExpression as(String alias) { - return AliasedExpression( - alias: alias, - expression: this, - ); + return AliasedExpression(alias: alias, expression: this); } /// Creates a descending ordering for this expression @@ -828,12 +825,7 @@ abstract class Expression implements PipelineSerializable { String indexAlias, Expression transform, ) { - return _ArrayTransformExpression( - this, - elementAlias, - indexAlias, - transform, - ); + return _ArrayTransformExpression(this, elementAlias, indexAlias, transform); } // ============================================================================ @@ -904,9 +896,7 @@ abstract class Expression implements PipelineSerializable { @override Map toMap() { - return { - 'name': name, - }; + return {'name': name}; } // ============================================================================ @@ -1011,9 +1001,7 @@ abstract class Expression implements PipelineSerializable { /// Creates an array expression from elements static Expression array(List elements) { - return _ArrayExpression( - elements.map(_toExpression).toList(), - ); + return _ArrayExpression(elements.map(_toExpression).toList()); } /// Creates a map expression from key-value pairs @@ -1082,10 +1070,7 @@ abstract class Expression implements PipelineSerializable { /// /// [unit] must be one of: `microsecond`, `millisecond`, `second`, `minute`, /// `hour`, `day`. - static Expression timestampTruncate( - Expression timestamp, - String unit, - ) { + static Expression timestampTruncate(Expression timestamp, String unit) { _validateTimestampUnit(unit); return _TimestampTruncateExpression(timestamp, unit); } @@ -1247,18 +1232,12 @@ abstract class Expression implements PipelineSerializable { } /// Checks if a value is in a list (IN operator) - static BooleanExpression equalAny( - Expression value, - List values, - ) { + static BooleanExpression equalAny(Expression value, List values) { return _EqualAnyExpression(value, values.map(_toExpression).toList()); } /// Checks if a value is not in a list (NOT IN operator) - static BooleanExpression notEqualAny( - Expression value, - List values, - ) { + static BooleanExpression notEqualAny(Expression value, List values) { return _NotEqualAnyExpression(value, values.map(_toExpression).toList()); } @@ -1268,18 +1247,12 @@ abstract class Expression implements PipelineSerializable { } /// Returns an expression if another is absent - static Expression ifAbsentStatic( - Expression ifExpr, - Expression elseExpr, - ) { + static Expression ifAbsentStatic(Expression ifExpr, Expression elseExpr) { return _IfAbsentExpression(ifExpr, elseExpr); } /// Returns a value if an expression is absent - static Expression ifAbsentValueStatic( - Expression ifExpr, - Object? elseValue, - ) { + static Expression ifAbsentValueStatic(Expression ifExpr, Object? elseValue) { return _IfAbsentExpression(ifExpr, _toExpression(elseValue)); } @@ -1294,10 +1267,7 @@ abstract class Expression implements PipelineSerializable { } /// Returns an expression if another errors - static Expression ifErrorStatic( - Expression tryExpr, - Expression catchExpr, - ) { + static Expression ifErrorStatic(Expression tryExpr, Expression catchExpr) { return _IfErrorExpression(tryExpr, catchExpr); } @@ -1592,10 +1562,7 @@ abstract class Expression implements PipelineSerializable { } /// Joins a field's array with a delimiter - static Expression joinField( - String arrayFieldName, - String delimiter, - ) { + static Expression joinField(String arrayFieldName, String delimiter) { return _JoinExpression(Field(arrayFieldName), Constant(delimiter)); } @@ -1635,42 +1602,27 @@ abstract class Expression implements PipelineSerializable { } /// Adds two expressions - static Expression addStatic( - Expression first, - Expression second, - ) { + static Expression addStatic(Expression first, Expression second) { return _AddExpression(first, second); } /// Adds an expression and a number - static Expression addStaticNumber( - Expression first, - num second, - ) { + static Expression addStaticNumber(Expression first, num second) { return _AddExpression(first, Constant(second)); } /// Adds a field and an expression - static Expression addField( - String numericFieldName, - Expression second, - ) { + static Expression addField(String numericFieldName, Expression second) { return _AddExpression(Field(numericFieldName), second); } /// Adds a field and a number - static Expression addFieldNumber( - String numericFieldName, - num second, - ) { + static Expression addFieldNumber(String numericFieldName, num second) { return _AddExpression(Field(numericFieldName), Constant(second)); } /// Subtracts two expressions - static Expression subtractStatic( - Expression minuend, - Expression subtrahend, - ) { + static Expression subtractStatic(Expression minuend, Expression subtrahend) { return _SubtractExpression(minuend, subtrahend); } @@ -1683,58 +1635,37 @@ abstract class Expression implements PipelineSerializable { } /// Divides two expressions - static Expression divideStatic( - Expression dividend, - Expression divisor, - ) { + static Expression divideStatic(Expression dividend, Expression divisor) { return _DivideExpression(dividend, divisor); } /// Returns modulo of two expressions - static Expression moduloStatic( - Expression dividend, - Expression divisor, - ) { + static Expression moduloStatic(Expression dividend, Expression divisor) { return _ModuloExpression(dividend, divisor); } /// Compares two expressions for equality - static BooleanExpression equalStatic( - Expression left, - Expression right, - ) { + static BooleanExpression equalStatic(Expression left, Expression right) { return _EqualExpression(left, right); } /// Compares expression with value for equality - static BooleanExpression equalStaticValue( - Expression left, - Object? right, - ) { + static BooleanExpression equalStaticValue(Expression left, Object? right) { return _EqualExpression(left, _toExpression(right)); } /// Compares field with value for equality - static BooleanExpression equalField( - String fieldName, - Object? value, - ) { + static BooleanExpression equalField(String fieldName, Object? value) { return _EqualExpression(Field(fieldName), _toExpression(value)); } /// Compares two expressions for inequality - static BooleanExpression notEqualStatic( - Expression left, - Expression right, - ) { + static BooleanExpression notEqualStatic(Expression left, Expression right) { return _NotEqualExpression(left, right); } /// Compares expression with value for inequality - static BooleanExpression notEqualStaticValue( - Expression left, - Object? right, - ) { + static BooleanExpression notEqualStaticValue(Expression left, Object? right) { return _NotEqualExpression(left, _toExpression(right)); } @@ -1755,10 +1686,7 @@ abstract class Expression implements PipelineSerializable { } /// Greater than comparison for field - static BooleanExpression greaterThanField( - String fieldName, - Object? value, - ) { + static BooleanExpression greaterThanField(String fieldName, Object? value) { return _GreaterThanExpression(Field(fieldName), _toExpression(value)); } @@ -1771,26 +1699,17 @@ abstract class Expression implements PipelineSerializable { } /// Less than comparison - static BooleanExpression lessThanStatic( - Expression left, - Expression right, - ) { + static BooleanExpression lessThanStatic(Expression left, Expression right) { return _LessThanExpression(left, right); } /// Less than comparison with value - static BooleanExpression lessThanStaticValue( - Expression left, - Object? right, - ) { + static BooleanExpression lessThanStaticValue(Expression left, Object? right) { return _LessThanExpression(left, _toExpression(right)); } /// Less than comparison for field - static BooleanExpression lessThanField( - String fieldName, - Object? value, - ) { + static BooleanExpression lessThanField(String fieldName, Object? value) { return _LessThanExpression(Field(fieldName), _toExpression(value)); } @@ -1866,10 +1785,7 @@ abstract class Expression implements PipelineSerializable { } /// Splits string - static Expression splitStatic( - Expression stringExpr, - Expression delimiter, - ) { + static Expression splitStatic(Expression stringExpr, Expression delimiter) { return _SplitExpression(stringExpr, delimiter); } @@ -2001,10 +1917,7 @@ abstract class Expression implements PipelineSerializable { } /// Creates a raw/custom function expression - static Expression rawFunction( - String name, - List args, - ) { + static Expression rawFunction(String name, List args) { return _RawFunctionExpression(name, args); } @@ -2015,10 +1928,7 @@ abstract class Expression implements PipelineSerializable { } /// Same as [Expression.isType] but usable as a static helper for any [expression]. - static BooleanExpression isTypeStatic( - Expression expression, - Type valueType, - ) { + static BooleanExpression isTypeStatic(Expression expression, Type valueType) { return _IsTypeExpression(expression, valueType); } } @@ -2042,10 +1952,8 @@ class AliasedExpression extends Selectable { @override final Expression expression; - AliasedExpression({ - required String alias, - required this.expression, - }) : _alias = alias; + AliasedExpression({required String alias, required this.expression}) + : _alias = alias; @override String get name => 'alias'; @@ -2054,10 +1962,7 @@ class AliasedExpression extends Selectable { Map toMap() { return { 'name': name, - 'args': { - 'alias': _alias, - 'expression': expression.toMap(), - }, + 'args': {'alias': _alias, 'expression': expression.toMap()}, }; } } @@ -2081,9 +1986,7 @@ class Field extends Selectable { Map toMap() { return { 'name': name, - 'args': { - 'field': fieldName, - }, + 'args': {'field': fieldName}, }; } } @@ -2099,9 +2002,7 @@ class _NullExpression extends Expression { Map toMap() { return { 'name': name, - 'args': { - 'value': null, - }, + 'args': {'value': null}, }; } } @@ -2164,9 +2065,7 @@ class Concat extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expressions': expressions.map((expr) => expr.toMap()).toList(), - }, + 'args': {'expressions': expressions.map((expr) => expr.toMap()).toList()}, }; } } @@ -2184,9 +2083,7 @@ class _ConcatExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expressions': expressions.map((expr) => expr.toMap()).toList(), - }, + 'args': {'expressions': expressions.map((expr) => expr.toMap()).toList()}, }; } } @@ -2204,9 +2101,7 @@ class _LengthExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -2224,9 +2119,7 @@ class _ToLowerCaseExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -2244,9 +2137,7 @@ class _ToUpperCaseExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -2356,9 +2247,7 @@ class _TrimExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -2379,9 +2268,7 @@ class _DocumentMatchesExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'query': query, - }, + 'args': {'query': query}, }; } } @@ -2404,10 +2291,7 @@ class _AddExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'left': left.toMap(), - 'right': right.toMap(), - }, + 'args': {'left': left.toMap(), 'right': right.toMap()}, }; } } @@ -2426,10 +2310,7 @@ class _SubtractExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'left': left.toMap(), - 'right': right.toMap(), - }, + 'args': {'left': left.toMap(), 'right': right.toMap()}, }; } } @@ -2448,10 +2329,7 @@ class _EqualExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'left': left.toMap(), - 'right': right.toMap(), - }, + 'args': {'left': left.toMap(), 'right': right.toMap()}, }; } } @@ -2470,10 +2348,7 @@ class _GreaterThanExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'left': left.toMap(), - 'right': right.toMap(), - }, + 'args': {'left': left.toMap(), 'right': right.toMap()}, }; } } @@ -2492,10 +2367,7 @@ class _MultiplyExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'left': left.toMap(), - 'right': right.toMap(), - }, + 'args': {'left': left.toMap(), 'right': right.toMap()}, }; } } @@ -2514,10 +2386,7 @@ class _DivideExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'left': left.toMap(), - 'right': right.toMap(), - }, + 'args': {'left': left.toMap(), 'right': right.toMap()}, }; } } @@ -2536,10 +2405,7 @@ class _ModuloExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'left': left.toMap(), - 'right': right.toMap(), - }, + 'args': {'left': left.toMap(), 'right': right.toMap()}, }; } } @@ -2557,9 +2423,7 @@ class _AbsExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -2579,10 +2443,7 @@ class _NotEqualExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'left': left.toMap(), - 'right': right.toMap(), - }, + 'args': {'left': left.toMap(), 'right': right.toMap()}, }; } } @@ -2601,10 +2462,7 @@ class _GreaterThanOrEqualExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'left': left.toMap(), - 'right': right.toMap(), - }, + 'args': {'left': left.toMap(), 'right': right.toMap()}, }; } } @@ -2623,10 +2481,7 @@ class _LessThanExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'left': left.toMap(), - 'right': right.toMap(), - }, + 'args': {'left': left.toMap(), 'right': right.toMap()}, }; } } @@ -2645,10 +2500,7 @@ class _LessThanOrEqualExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'left': left.toMap(), - 'right': right.toMap(), - }, + 'args': {'left': left.toMap(), 'right': right.toMap()}, }; } } @@ -2671,10 +2523,7 @@ class _ArrayConcatExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'first': firstArray.toMap(), - 'second': secondArray.toMap(), - }, + 'args': {'first': firstArray.toMap(), 'second': secondArray.toMap()}, }; } } @@ -2692,9 +2541,7 @@ class _ArrayConcatMultipleExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'arrays': arrays.map((expr) => expr.toMap()).toList(), - }, + 'args': {'arrays': arrays.map((expr) => expr.toMap()).toList()}, }; } } @@ -2713,10 +2560,7 @@ class _ArrayContainsExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'array': array.toMap(), - 'element': element.toMap(), - }, + 'args': {'array': array.toMap(), 'element': element.toMap()}, }; } } @@ -2800,9 +2644,7 @@ class _ArrayLengthExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -2820,9 +2662,7 @@ class _ArrayReverseExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -2840,9 +2680,7 @@ class _ArraySumExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -2867,10 +2705,7 @@ class _ArraySliceExpression extends FunctionExpression { if (sliceLength != null) { args['length'] = sliceLength!.toMap(); } - return { - 'name': name, - 'args': args, - }; + return {'name': name, 'args': args}; } } @@ -2926,10 +2761,7 @@ class _ArrayTransformExpression extends FunctionExpression { if (indexAlias != null) { args['index_alias'] = indexAlias; } - return { - 'name': name, - 'args': args, - }; + return {'name': name, 'args': args}; } } @@ -2951,10 +2783,7 @@ class _IfAbsentExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - 'else': elseExpr.toMap(), - }, + 'args': {'expression': expression.toMap(), 'else': elseExpr.toMap()}, }; } } @@ -2973,10 +2802,7 @@ class _IfErrorExpression extends Expression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - 'catch': catchExpr.toMap(), - }, + 'args': {'expression': expression.toMap(), 'catch': catchExpr.toMap()}, }; } } @@ -2994,9 +2820,7 @@ class _IsAbsentExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -3014,9 +2838,7 @@ class _IsErrorExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -3034,9 +2856,7 @@ class _ExistsExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -3054,9 +2874,7 @@ class _NotExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -3073,9 +2891,7 @@ class _XorExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'expressions': expressions.map((e) => e.toMap()).toList(), - }, + 'args': {'expressions': expressions.map((e) => e.toMap()).toList()}, }; } } @@ -3092,9 +2908,7 @@ class _AndExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'expressions': expressions.map((e) => e.toMap()).toList(), - }, + 'args': {'expressions': expressions.map((e) => e.toMap()).toList()}, }; } } @@ -3111,9 +2925,7 @@ class _OrExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'expressions': expressions.map((e) => e.toMap()).toList(), - }, + 'args': {'expressions': expressions.map((e) => e.toMap()).toList()}, }; } } @@ -3159,9 +2971,7 @@ class _AsBooleanExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -3184,10 +2994,7 @@ class _BitAndExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'left': left.toMap(), - 'right': right.toMap(), - }, + 'args': {'left': left.toMap(), 'right': right.toMap()}, }; } } @@ -3206,10 +3013,7 @@ class _BitOrExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'left': left.toMap(), - 'right': right.toMap(), - }, + 'args': {'left': left.toMap(), 'right': right.toMap()}, }; } } @@ -3228,10 +3032,7 @@ class _BitXorExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'left': left.toMap(), - 'right': right.toMap(), - }, + 'args': {'left': left.toMap(), 'right': right.toMap()}, }; } } @@ -3249,9 +3050,7 @@ class _BitNotExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -3270,10 +3069,7 @@ class _BitLeftShiftExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - 'amount': amount.toMap(), - }, + 'args': {'expression': expression.toMap(), 'amount': amount.toMap()}, }; } } @@ -3292,10 +3088,7 @@ class _BitRightShiftExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - 'amount': amount.toMap(), - }, + 'args': {'expression': expression.toMap(), 'amount': amount.toMap()}, }; } } @@ -3317,9 +3110,7 @@ class _DocumentIdExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -3337,9 +3128,7 @@ class _CollectionIdExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -3357,9 +3146,7 @@ class _DocumentIdFromRefExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'doc_ref': docRef.path, - }, + 'args': {'doc_ref': docRef.path}, }; } } @@ -3382,10 +3169,7 @@ class _MapGetExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'map': map.toMap(), - 'key': key.toMap(), - }, + 'args': {'map': map.toMap(), 'key': key.toMap()}, }; } } @@ -3403,9 +3187,7 @@ class _CurrentTimestampExpression extends FunctionExpression { @override Map toMap() { - return { - 'name': name, - }; + return {'name': name}; } } @@ -3474,10 +3256,7 @@ class _TimestampTruncateExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'timestamp': timestamp.toMap(), - 'unit': unit, - }, + 'args': {'timestamp': timestamp.toMap(), 'unit': unit}, }; } } @@ -3543,9 +3322,7 @@ class _ArrayExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'elements': elements.map((expr) => expr.toMap()).toList(), - }, + 'args': {'elements': elements.map((expr) => expr.toMap()).toList()}, }; } } @@ -3563,9 +3340,7 @@ class _MapExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'data': data.map((k, v) => MapEntry(k, v.toMap())), - }, + 'args': {'data': data.map((k, v) => MapEntry(k, v.toMap()))}, }; } } @@ -3609,9 +3384,7 @@ class _MapEntriesExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -3629,9 +3402,7 @@ class _MapKeysExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -3649,9 +3420,7 @@ class _MapValuesExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -3669,9 +3438,7 @@ class _ParentExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -3689,9 +3456,7 @@ class _ParentFromDocumentRefExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'doc_ref': docRef.path, - }, + 'args': {'doc_ref': docRef.path}, }; } } @@ -3741,10 +3506,7 @@ class _TimestampExtractExpression extends FunctionExpression { if (tz != null) { args['timezone'] = tz.toMap(); } - return { - 'name': name, - 'args': args, - }; + return {'name': name, 'args': args}; } } @@ -3782,9 +3544,7 @@ class _NorExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'expressions': expressions.map((e) => e.toMap()).toList(), - }, + 'args': {'expressions': expressions.map((e) => e.toMap()).toList()}, }; } } @@ -3822,9 +3582,7 @@ class _CoalesceExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expressions': expressions.map((e) => e.toMap()).toList(), - }, + 'args': {'expressions': expressions.map((e) => e.toMap()).toList()}, }; } } @@ -3843,10 +3601,7 @@ class _RegexFindExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - 'pattern': pattern.toMap(), - }, + 'args': {'expression': expression.toMap(), 'pattern': pattern.toMap()}, }; } } @@ -3865,10 +3620,7 @@ class _RegexFindAllExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - 'pattern': pattern.toMap(), - }, + 'args': {'expression': expression.toMap(), 'pattern': pattern.toMap()}, }; } } @@ -3911,10 +3663,7 @@ class _StringIndexOfExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - 'search': search.toMap(), - }, + 'args': {'expression': expression.toMap(), 'search': search.toMap()}, }; } } @@ -3953,16 +3702,11 @@ class _LtrimExpression extends FunctionExpression { @override Map toMap() { - final args = { - 'expression': expression.toMap(), - }; + final args = {'expression': expression.toMap()}; if (value != null) { args['value'] = value!.toMap(); } - return { - 'name': name, - 'args': args, - }; + return {'name': name, 'args': args}; } } @@ -3978,16 +3722,11 @@ class _RtrimExpression extends FunctionExpression { @override Map toMap() { - final args = { - 'expression': expression.toMap(), - }; + final args = {'expression': expression.toMap()}; if (value != null) { args['value'] = value!.toMap(); } - return { - 'name': name, - 'args': args, - }; + return {'name': name, 'args': args}; } } @@ -4004,9 +3743,7 @@ class _TypeExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -4025,10 +3762,7 @@ class _IsTypeExpression extends BooleanExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - 'type': valueType.typeValue, - }, + 'args': {'expression': expression.toMap(), 'type': valueType.typeValue}, }; } } @@ -4045,16 +3779,11 @@ class _TruncExpression extends FunctionExpression { @override Map toMap() { - final args = { - 'expression': expression.toMap(), - }; + final args = {'expression': expression.toMap()}; if (decimals != null) { args['decimals'] = decimals!.toMap(); } - return { - 'name': name, - 'args': args, - }; + return {'name': name, 'args': args}; } } @@ -4067,10 +3796,7 @@ class _RandExpression extends FunctionExpression { @override Map toMap() { - return { - 'name': name, - 'args': {}, - }; + return {'name': name, 'args': {}}; } } @@ -4087,9 +3813,7 @@ class _ArrayFirstExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -4108,10 +3832,7 @@ class _ArrayFirstNExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - 'n': n.toMap(), - }, + 'args': {'expression': expression.toMap(), 'n': n.toMap()}, }; } } @@ -4129,9 +3850,7 @@ class _ArrayLastExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -4150,10 +3869,7 @@ class _ArrayLastNExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - 'n': n.toMap(), - }, + 'args': {'expression': expression.toMap(), 'n': n.toMap()}, }; } } @@ -4171,9 +3887,7 @@ class _ArrayMaximumExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -4192,10 +3906,7 @@ class _ArrayMaximumNExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - 'n': n.toMap(), - }, + 'args': {'expression': expression.toMap(), 'n': n.toMap()}, }; } } @@ -4213,9 +3924,7 @@ class _ArrayMinimumExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -4234,10 +3943,7 @@ class _ArrayMinimumNExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - 'n': n.toMap(), - }, + 'args': {'expression': expression.toMap(), 'n': n.toMap()}, }; } } @@ -4284,10 +3990,7 @@ class _ArrayIndexOfAllExpression extends FunctionExpression { Map toMap() { return { 'name': name, - 'args': { - 'expression': expression.toMap(), - 'element': element.toMap(), - }, + 'args': {'expression': expression.toMap(), 'element': element.toMap()}, }; } } @@ -4304,9 +4007,6 @@ class _RawFunctionExpression extends FunctionExpression { @override Map toMap() { - return { - 'name': name, - 'args': args.map((expr) => expr.toMap()).toList(), - }; + return {'name': name, 'args': args.map((expr) => expr.toMap()).toList()}; } } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_sample.dart b/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_sample.dart index 4136c9922872..44e843351731 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_sample.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_sample.dart @@ -23,10 +23,7 @@ class _PipelineSampleSize extends PipelineSample { const _PipelineSampleSize(this.size); @override - Map toMap() => { - 'type': 'size', - 'value': size, - }; + Map toMap() => {'type': 'size', 'value': size}; } /// Sample stage with a percentage @@ -36,8 +33,5 @@ class _PipelineSamplePercentage extends PipelineSample { const _PipelineSamplePercentage(this.percentage); @override - Map toMap() => { - 'type': 'percentage', - 'value': percentage, - }; + Map toMap() => {'type': 'percentage', 'value': percentage}; } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_search.dart b/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_search.dart index fc5994a74d1b..4a1f2e700c30 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_search.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_search.dart @@ -4,10 +4,7 @@ part of '../cloud_firestore.dart'; -enum _SearchQueryType { - string, - expression, -} +enum _SearchQueryType { string, expression } /// Specifies how a pipeline search stage is performed. /// @@ -31,14 +28,14 @@ final class SearchStage implements PipelineSerializable { int? limit, int? offset, int? retrievalDepth, - }) : _queryType = queryType, - _query = query, - _sort = sort, - _addFields = addFields, - _languageCode = languageCode, - _limit = limit, - _offset = offset, - _retrievalDepth = retrievalDepth; + }) : _queryType = queryType, + _query = query, + _sort = sort, + _addFields = addFields, + _languageCode = languageCode, + _limit = limit, + _offset = offset, + _retrievalDepth = retrievalDepth; /// Creates a search stage from a raw query string. SearchStage.withQuery( @@ -50,15 +47,15 @@ final class SearchStage implements PipelineSerializable { int? offset, int? retrievalDepth, }) : this._( - queryType: _SearchQueryType.string, - query: query, - sort: sort, - addFields: addFields, - languageCode: languageCode, - limit: limit, - offset: offset, - retrievalDepth: retrievalDepth, - ); + queryType: _SearchQueryType.string, + query: query, + sort: sort, + addFields: addFields, + languageCode: languageCode, + limit: limit, + offset: offset, + retrievalDepth: retrievalDepth, + ); /// Creates a search stage from a search query expression. SearchStage.withQueryExpression( @@ -70,15 +67,15 @@ final class SearchStage implements PipelineSerializable { int? offset, int? retrievalDepth, }) : this._( - queryType: _SearchQueryType.expression, - query: query, - sort: sort, - addFields: addFields, - languageCode: languageCode, - limit: limit, - offset: offset, - retrievalDepth: retrievalDepth, - ); + queryType: _SearchQueryType.expression, + query: query, + sort: sort, + addFields: addFields, + languageCode: languageCode, + limit: limit, + offset: offset, + retrievalDepth: retrievalDepth, + ); @override Map toMap() { diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_stage.dart b/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_stage.dart index e6eaf8df20f5..651b56fb9e96 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_stage.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/pipeline_stage.dart @@ -22,9 +22,7 @@ final class _CollectionPipelineStage extends PipelineStage { Map toMap() { return { 'stage': name, - 'args': { - 'path': collectionPath, - }, + 'args': {'path': collectionPath}, }; } } @@ -42,13 +40,7 @@ final class _DocumentsPipelineStage extends PipelineStage { Map toMap() { return { 'stage': name, - 'args': documents - .map( - (doc) => { - 'path': doc.path, - }, - ) - .toList(), + 'args': documents.map((doc) => {'path': doc.path}).toList(), }; } } @@ -62,9 +54,7 @@ final class _DatabasePipelineStage extends PipelineStage { @override Map toMap() { - return { - 'stage': name, - }; + return {'stage': name}; } } @@ -81,9 +71,7 @@ final class _CollectionGroupPipelineStage extends PipelineStage { Map toMap() { return { 'stage': name, - 'args': { - 'path': collectionPath, - }, + 'args': {'path': collectionPath}, }; } } @@ -101,9 +89,7 @@ final class _AddFieldsStage extends PipelineStage { Map toMap() { return { 'stage': name, - 'args': { - 'expressions': expressions.map((expr) => expr.toMap()).toList(), - }, + 'args': {'expressions': expressions.map((expr) => expr.toMap()).toList()}, }; } } @@ -122,8 +108,9 @@ final class _AggregateStage extends PipelineStage { return { 'stage': name, 'args': { - 'aggregate_functions': - aggregateFunctions.map((func) => func.toMap()).toList(), + 'aggregate_functions': aggregateFunctions + .map((func) => func.toMap()) + .toList(), }, }; } @@ -145,10 +132,7 @@ final class _AggregateStageWithOptions extends PipelineStage { final optionsMap = options?.toMap(); return { 'stage': name, - 'args': { - 'aggregate_stage': map, - 'options': optionsMap, - }, + 'args': {'aggregate_stage': map, 'options': optionsMap}, }; } } @@ -166,9 +150,7 @@ final class _DistinctStage extends PipelineStage { Map toMap() { return { 'stage': name, - 'args': { - 'expressions': expressions.map((expr) => expr.toMap()).toList(), - }, + 'args': {'expressions': expressions.map((expr) => expr.toMap()).toList()}, }; } } @@ -218,10 +200,7 @@ final class _SearchStage extends PipelineStage { @override Map toMap() { - return { - 'stage': name, - 'args': searchStage.toMap(), - }; + return {'stage': name, 'args': searchStage.toMap()}; } } @@ -238,9 +217,7 @@ final class _LimitStage extends PipelineStage { Map toMap() { return { 'stage': name, - 'args': { - 'limit': limit, - }, + 'args': {'limit': limit}, }; } } @@ -258,9 +235,7 @@ final class _OffsetStage extends PipelineStage { Map toMap() { return { 'stage': name, - 'args': { - 'offset': offset, - }, + 'args': {'offset': offset}, }; } } @@ -278,9 +253,7 @@ final class _RemoveFieldsStage extends PipelineStage { Map toMap() { return { 'stage': name, - 'args': { - 'field_paths': fieldPaths, - }, + 'args': {'field_paths': fieldPaths}, }; } } @@ -298,9 +271,7 @@ final class _ReplaceWithStage extends PipelineStage { Map toMap() { return { 'stage': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } @@ -316,10 +287,7 @@ final class _SampleStage extends PipelineStage { @override Map toMap() { - return { - 'stage': name, - 'args': sample.toMap(), - }; + return {'stage': name, 'args': sample.toMap()}; } } @@ -336,9 +304,7 @@ final class _SelectStage extends PipelineStage { Map toMap() { return { 'stage': name, - 'args': { - 'expressions': expressions.map((expr) => expr.toMap()).toList(), - }, + 'args': {'expressions': expressions.map((expr) => expr.toMap()).toList()}, }; } } @@ -361,8 +327,9 @@ final class _SortStage extends PipelineStage { .map( (o) => { 'expression': o.expression.toMap(), - 'order_direction': - o.direction == OrderDirection.asc ? 'asc' : 'desc', + 'order_direction': o.direction == OrderDirection.asc + ? 'asc' + : 'desc', }, ) .toList(), @@ -385,9 +352,7 @@ final class _UnnestStage extends PipelineStage { Map toMap() { final map = { 'stage': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; if (indexField != null) { map['args']['index_field'] = indexField; @@ -409,9 +374,7 @@ final class _UnionStage extends PipelineStage { Map toMap() { return { 'stage': name, - 'args': { - 'pipeline': pipeline.stages, - }, + 'args': {'pipeline': pipeline.stages}, }; } } @@ -429,9 +392,7 @@ final class _WhereStage extends PipelineStage { Map toMap() { return { 'stage': name, - 'args': { - 'expression': expression.toMap(), - }, + 'args': {'expression': expression.toMap()}, }; } } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart index 8d52e8b00283..b38d9bdb4003 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart @@ -232,10 +232,7 @@ abstract class Query { /// /// Can construct refined [Query] objects by adding filters and ordering. class _JsonQuery implements Query> { - _JsonQuery( - this.firestore, - this._delegate, - ) { + _JsonQuery(this.firestore, this._delegate) { QueryPlatform.verify(_delegate); } @@ -291,8 +288,9 @@ class _JsonQuery implements Query> { // All order by fields must exist within the snapshot if (field != FieldPath.documentId) { try { - final codecValue = - _CodecUtility.valueEncode(documentSnapshot.get(field)); + final codecValue = _CodecUtility.valueEncode( + documentSnapshot.get(field), + ); values.add(codecValue); } on StateError { throw "You are trying to start or end a query using a document for which the field '$field' (used as the orderBy) does not exist."; @@ -319,10 +317,7 @@ class _JsonQuery implements Query> { values.add(documentSnapshot.id); } - return { - 'orders': orders, - 'values': values, - }; + return {'orders': orders, 'values': values}; } /// Common handler for all non-document based cursor queries. @@ -410,10 +405,7 @@ class _JsonQuery implements Query> { @override Query> endBefore(Iterable values) { _assertQueryCursorValues(values); - return _JsonQuery( - firestore, - _delegate.endBefore(values.toList()), - ); + return _JsonQuery(firestore, _delegate.endBefore(values.toList())); } /// Fetch the documents for this query. @@ -422,8 +414,9 @@ class _JsonQuery implements Query> { /// with a [GetOptions] instance. @override Future>> get([GetOptions? options]) async { - QuerySnapshotPlatform snapshotDelegate = - await _delegate.get(options ?? const GetOptions()); + QuerySnapshotPlatform snapshotDelegate = await _delegate.get( + options ?? const GetOptions(), + ); return _JsonQuerySnapshot(firestore, snapshotDelegate); } @@ -483,10 +476,7 @@ class _JsonQuery implements Query> { /// or [endAtDocument] because the order by clause on the document id /// is added by these methods implicitly. @override - Query> orderBy( - Object field, { - bool descending = false, - }) { + Query> orderBy(Object field, {bool descending = false}) { _assertValidFieldType(field); assert( !_hasStartCursor(), @@ -501,8 +491,9 @@ class _JsonQuery implements Query> { 'endBefore() or endBeforeDocument() before calling orderBy()', ); - final List> orders = - List>.from(parameters['orderBy']); + final List> orders = List>.from( + parameters['orderBy'], + ); assert( orders.where((List item) => field == item[0]).isEmpty, @@ -512,8 +503,9 @@ class _JsonQuery implements Query> { if (field == FieldPath.documentId) { orders.add([field, descending]); } else { - FieldPath fieldPath = - field is String ? FieldPath.fromString(field) : field as FieldPath; + FieldPath fieldPath = field is String + ? FieldPath.fromString(field) + : field as FieldPath; orders.add([fieldPath, descending]); } @@ -630,8 +622,9 @@ class _JsonQuery implements Query> { final field = fieldOrFilter; const ListEquality equality = ListEquality(); - final List> conditions = - List>.from(parameters['where']); + final List> conditions = List>.from( + parameters['where'], + ); // Conditions can be chained from other [Query] instances void addCondition(dynamic field, String operator, dynamic value) { @@ -641,8 +634,9 @@ class _JsonQuery implements Query> { if (field == FieldPath.documentId) { condition = [field, operator, codecValue]; } else { - FieldPath fieldPath = - field is String ? FieldPath.fromString(field) : field as FieldPath; + FieldPath fieldPath = field is String + ? FieldPath.fromString(field) + : field as FieldPath; condition = [fieldPath, operator, codecValue]; } @@ -757,18 +751,12 @@ class _JsonQuery implements Query> { !hasNotEqualTo, "You cannot use 'not-in' filters with '!=' filters.", ); - assert( - !hasIn, - "You cannot use 'not-in' filters with 'in' filters.", - ); + assert(!hasIn, "You cannot use 'not-in' filters with 'in' filters."); hasNotIn = true; } if (operator == 'in') { - assert( - !hasNotIn, - "You cannot use 'in' filters with 'not-in' filters.", - ); + assert(!hasNotIn, "You cannot use 'in' filters with 'not-in' filters."); hasIn = true; } @@ -804,11 +792,7 @@ class _JsonQuery implements Query> { required FromFirestore fromFirestore, required ToFirestore toFirestore, }) { - return _WithConverterQuery( - this, - fromFirestore, - toFirestore, - ); + return _WithConverterQuery(this, fromFirestore, toFirestore); } @override @@ -1049,11 +1033,7 @@ class _WithConverterQuery implements Query { required FromFirestore fromFirestore, required ToFirestore toFirestore, }) { - return _WithConverterQuery( - _originalQuery, - fromFirestore, - toFirestore, - ); + return _WithConverterQuery(_originalQuery, fromFirestore, toFirestore); } @override diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query_document_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query_document_snapshot.dart index 506b50ebb98e..559043250e76 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query_document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query_document_snapshot.dart @@ -20,7 +20,7 @@ abstract class QueryDocumentSnapshot class _JsonQueryDocumentSnapshot extends _JsonDocumentSnapshot implements QueryDocumentSnapshot> { _JsonQueryDocumentSnapshot(_firestore, _delegate) - : super(_firestore, _delegate); + : super(_firestore, _delegate); @override bool get exists => true; @@ -42,11 +42,7 @@ class _WithConverterQueryDocumentSnapshot QueryDocumentSnapshot> originalQueryDocumentSnapshot, FromFirestore fromFirestore, ToFirestore toFirestore, - ) : super( - originalQueryDocumentSnapshot, - fromFirestore, - toFirestore, - ); + ) : super(originalQueryDocumentSnapshot, fromFirestore, toFirestore); @override bool get exists => true; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart index b9885ea3bf40..926b0198f579 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart @@ -83,11 +83,7 @@ class _WithConverterQuerySnapshot List> get docChanges { return [ for (final change in _originalQuerySnapshot.docChanges) - _WithConverterDocumentChange( - change, - _fromFirestore, - _toFirestore, - ), + _WithConverterDocumentChange(change, _fromFirestore, _toFirestore), ]; } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart index 7a33ba17f394..c989c3848e7b 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart @@ -24,11 +24,14 @@ class Transaction { Future> get( DocumentReference documentReference, ) async { - DocumentSnapshotPlatform documentSnapshotPlatform = - await _delegate.get(documentReference.path); + DocumentSnapshotPlatform documentSnapshotPlatform = await _delegate.get( + documentReference.path, + ); - final snapshot = - _JsonDocumentSnapshot(_firestore, documentSnapshotPlatform); + final snapshot = _JsonDocumentSnapshot( + _firestore, + documentSnapshotPlatform, + ); if (snapshot is DocumentSnapshot) { return snapshot as DocumentSnapshot; @@ -51,10 +54,7 @@ class Transaction { 'the document provided is from a different Firestore instance', ); - return Transaction._( - _firestore, - _delegate.delete(documentReference.path), - ); + return Transaction._(_firestore, _delegate.delete(documentReference.path)); } /// Updates fields in the document referred to by [documentReference]. diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart index 2e305ce16393..10c39bd2c725 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart @@ -4,8 +4,9 @@ part of '../../cloud_firestore.dart'; -// ignore: do_not_use_environment -const kIsWasm = bool.fromEnvironment('dart.library.js_interop') && +const kIsWasm = + // ignore: do_not_use_environment + bool.fromEnvironment('dart.library.js_interop') && // html package is not available in wasm // ignore: do_not_use_environment !bool.fromEnvironment('dart.library.html'); @@ -74,9 +75,9 @@ class _CodecUtility { if (data == null) { return null; } - return List.from(data) - .map((value) => valueDecode(value, firestore)) - .toList(); + return List.from( + data, + ).map((value) => valueDecode(value, firestore)).toList(); } static dynamic valueEncode(dynamic value) { diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart index c8a60f3ee5fd..d3a5c14cac4d 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart @@ -38,11 +38,7 @@ class WriteBatch { /// /// If [SetOptions] are provided, the data will be merged into an existing /// document instead of overwriting. - void set( - DocumentReference document, - T data, [ - SetOptions? options, - ]) { + void set(DocumentReference document, T data, [SetOptions? options]) { assert( document.firestore == _firestore, 'the document provided is from a different Firestore instance', diff --git a/packages/cloud_firestore/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/cloud_firestore/pubspec.yaml index eb2088ef200f..25be1cbc553d 100755 --- a/packages/cloud_firestore/cloud_firestore/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore/pubspec.yaml @@ -17,8 +17,8 @@ false_secrets: - dartpad/** environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: cloud_firestore_platform_interface: ^8.0.7 diff --git a/packages/cloud_firestore/cloud_firestore/test/cloud_firestore_test.dart b/packages/cloud_firestore/cloud_firestore/test/cloud_firestore_test.dart index ed8ea0e8c108..9eb24a351c8a 100644 --- a/packages/cloud_firestore/cloud_firestore/test/cloud_firestore_test.dart +++ b/packages/cloud_firestore/cloud_firestore/test/cloud_firestore_test.dart @@ -48,8 +48,10 @@ void main() { expect(firestore.databaseId, equals('foo')); - final firestore2 = - FirebaseFirestore.instanceFor(app: Firebase.app(), databaseId: 'bar'); + final firestore2 = FirebaseFirestore.instanceFor( + app: Firebase.app(), + databaseId: 'bar', + ); expect(firestore2.databaseId, equals('bar')); diff --git a/packages/cloud_firestore/cloud_firestore/test/collection_reference_test.dart b/packages/cloud_firestore/cloud_firestore/test/collection_reference_test.dart index 36b39af2e9e8..1de341f34a6e 100644 --- a/packages/cloud_firestore/cloud_firestore/test/collection_reference_test.dart +++ b/packages/cloud_firestore/cloud_firestore/test/collection_reference_test.dart @@ -55,8 +55,9 @@ void main() { expect(ref3 == ref, isFalse); DocumentReference docRef = firestore.collection('foo').doc('bar'); - DocumentReference docRef2 = - firestoreSecondary.collection('foo').doc('bar'); + DocumentReference docRef2 = firestoreSecondary + .collection('foo') + .doc('bar'); expect(docRef, firestore.collection('foo').doc('bar')); expect(docRef2, firestoreSecondary.collection('foo').doc('bar')); @@ -146,10 +147,7 @@ void main() { throwsArgumentError, ); expect(() => docRef.collection('foo/bar'), throwsArgumentError); - expect( - () => docRef.collection('foo/bar/baz/quu'), - throwsArgumentError, - ); + expect(() => docRef.collection('foo/bar/baz/quu'), throwsArgumentError); }); test('must not have empty segments', () { @@ -176,8 +174,7 @@ void main() { int fromFirestore( DocumentSnapshot snapshot, SnapshotOptions? options, - ) => - 42; + ) => 42; Map toFirestore(Object value, SetOptions? options) => {}; @@ -282,8 +279,10 @@ void main() { }); test('path', () { - final subCollection = - firestore.collection('foo').doc('42').collection('bar'); + final subCollection = firestore + .collection('foo') + .doc('42') + .collection('bar'); expect( subCollection @@ -297,8 +296,10 @@ void main() { }); test('parent', () { - final subCollection = - firestore.collection('foo').doc('42').collection('bar'); + final subCollection = firestore + .collection('foo') + .doc('42') + .collection('bar'); expect( subCollection @@ -317,8 +318,7 @@ void main() { int fromFirestore( DocumentSnapshot snapshot, SnapshotOptions? options, - ) => - 42; + ) => 42; Map toFirestore(Object value, SetOptions? options) => {}; @@ -329,7 +329,9 @@ void main() { toFirestore: toFirestore, ) .doc('42'), - foo.doc('42').withConverter( + foo + .doc('42') + .withConverter( fromFirestore: fromFirestore, toFirestore: toFirestore, ), diff --git a/packages/cloud_firestore/cloud_firestore/test/pipeline_expression_test.dart b/packages/cloud_firestore/cloud_firestore/test/pipeline_expression_test.dart index 1de268874b54..04b58175321b 100644 --- a/packages/cloud_firestore/cloud_firestore/test/pipeline_expression_test.dart +++ b/packages/cloud_firestore/cloud_firestore/test/pipeline_expression_test.dart @@ -106,29 +106,21 @@ void main() { test('toMap for List (bytes)', () { final bytes = [1, 2, 3]; final expr = Constant(bytes); - expect( - expr.toMap(), - { - 'name': 'constant', - 'args': { - 'value': [1, 2, 3], - }, + expect(expr.toMap(), { + 'name': 'constant', + 'args': { + 'value': [1, 2, 3], }, - ); + }); }); test('toMap for Blob', () { final blob = Blob(Uint8List.fromList([1, 2, 3])); final expr = Constant(blob); - expect( - expr.toMap(), - { - 'name': 'constant', - 'args': { - 'value': blob, - }, - }, - ); + expect(expr.toMap(), { + 'name': 'constant', + 'args': {'value': blob}, + }); }); test('toMap for DocumentReference serializes path', () { @@ -137,9 +129,7 @@ void main() { expect(expr.toMap(), { 'name': 'constant', 'args': { - 'value': { - 'path': 'users/alice', - }, + 'value': {'path': 'users/alice'}, }, }); }); @@ -319,10 +309,7 @@ void main() { group('Expression static boolean helpers', () { test('Expression.equalStatic produces equal expression', () { - final expr = Expression.equalStatic( - Field('a'), - Constant(1), - ); + final expr = Expression.equalStatic(Field('a'), Constant(1)); expect(expr.toMap()['name'], 'equal'); }); @@ -400,10 +387,7 @@ void main() { final expr = base.ifAbsent(fallback); expect(expr.toMap(), { 'name': 'if_absent', - 'args': { - 'expression': base.toMap(), - 'else': fallback.toMap(), - }, + 'args': {'expression': base.toMap(), 'else': fallback.toMap()}, }); }); @@ -418,10 +402,7 @@ void main() { final expr = base.ifError(catchExpr); expect(expr.toMap(), { 'name': 'if_error', - 'args': { - 'expression': base.toMap(), - 'catch': catchExpr.toMap(), - }, + 'args': {'expression': base.toMap(), 'catch': catchExpr.toMap()}, }); }); }); @@ -504,8 +485,9 @@ void main() { }); test('stringReplaceAll serializes correctly', () { - final expr = - Field('s').stringReplaceAll(Constant('old'), Constant('new')); + final expr = Field( + 's', + ).stringReplaceAll(Constant('old'), Constant('new')); expect(expr.toMap(), { 'name': 'string_replace_all', 'args': { @@ -528,10 +510,7 @@ void main() { final expr = arr.join(Constant('-')); expect(expr.toMap(), { 'name': 'join', - 'args': { - 'expression': arr.toMap(), - 'delimiter': Constant('-').toMap(), - }, + 'args': {'expression': arr.toMap(), 'delimiter': Constant('-').toMap()}, }); }); }); @@ -563,8 +542,9 @@ void main() { }); test('arrayContainsAny serializes correctly', () { - final expr = - Field('tags').arrayContainsAny([Constant('a'), Constant('b')]); + final expr = Field( + 'tags', + ).arrayContainsAny([Constant('a'), Constant('b')]); expect(expr.toMap()['name'], 'array_contains_any'); expect(expr.toMap()['args']['array']['args']['field'], 'tags'); expect(expr.toMap()['args']['values'], hasLength(2)); @@ -576,10 +556,7 @@ void main() { 'name': 'array_contains_all', 'args': { 'array': Field('tags').toMap(), - 'values': [ - Constant('a').toMap(), - Constant('b').toMap(), - ], + 'values': [Constant('a').toMap(), Constant('b').toMap()], }, }); }); @@ -597,32 +574,37 @@ void main() { }); test( - 'Expression.arrayContainsAllWithExpression(array, arrayExpression) serializes correctly', - () { - final arrayExpr = - Expression.array([Field('required'), Constant('admin')]); - final expr = Expression.arrayContainsAllWithExpression( - Field('permissions'), - arrayExpr, - ); - expect(expr.toMap(), { - 'name': 'array_contains_all', - 'args': { - 'array': Field('permissions').toMap(), - 'array_expression': arrayExpr.toMap(), - }, - }); - }); + 'Expression.arrayContainsAllWithExpression(array, arrayExpression) serializes correctly', + () { + final arrayExpr = Expression.array([ + Field('required'), + Constant('admin'), + ]); + final expr = Expression.arrayContainsAllWithExpression( + Field('permissions'), + arrayExpr, + ); + expect(expr.toMap(), { + 'name': 'array_contains_all', + 'args': { + 'array': Field('permissions').toMap(), + 'array_expression': arrayExpr.toMap(), + }, + }); + }, + ); - test('Expression.arrayContainsAllValues(array, list) serializes correctly', - () { - final expr = Expression.arrayContainsAllValues( - Field('tags'), - [Constant('flutter'), Constant('dart')], - ); - expect(expr.toMap()['name'], 'array_contains_all'); - expect(expr.toMap()['args']['values'], hasLength(2)); - }); + test( + 'Expression.arrayContainsAllValues(array, list) serializes correctly', + () { + final expr = Expression.arrayContainsAllValues(Field('tags'), [ + Constant('flutter'), + Constant('dart'), + ]); + expect(expr.toMap()['name'], 'array_contains_all'); + expect(expr.toMap()['args']['values'], hasLength(2)); + }, + ); test('Expression.arrayContainsAllField serializes correctly', () { final required = Expression.array([Field('requiredPermissions')]); @@ -650,10 +632,7 @@ void main() { final expr = a.arrayConcat(b); expect(expr.toMap(), { 'name': 'array_concat', - 'args': { - 'first': a.toMap(), - 'second': b.toMap(), - }, + 'args': {'first': a.toMap(), 'second': b.toMap()}, }); }); @@ -693,10 +672,9 @@ void main() { }); test('arrayFilter serializes correctly', () { - final expr = Field('scores').arrayFilter( - 'item', - Field('item').greaterThanValue(10), - ); + final expr = Field( + 'scores', + ).arrayFilter('item', Field('item').greaterThanValue(10)); expect(expr.toMap(), { 'name': 'array_filter', 'args': { @@ -708,10 +686,9 @@ void main() { }); test('arrayTransform serializes correctly', () { - final expr = Field('scores').arrayTransform( - 'score', - Field('score').multiplyNumber(10), - ); + final expr = Field( + 'scores', + ).arrayTransform('score', Field('score').multiplyNumber(10)); expect(expr.toMap(), { 'name': 'array_transform', 'args': { @@ -723,11 +700,9 @@ void main() { }); test('arrayTransformWithIndex serializes correctly', () { - final expr = Field('scores').arrayTransformWithIndex( - 'score', - 'i', - Field('score').add(Field('i')), - ); + final expr = Field( + 'scores', + ).arrayTransformWithIndex('score', 'i', Field('score').add(Field('i'))); expect(expr.toMap(), { 'name': 'array_transform_with_index', 'args': { @@ -745,10 +720,7 @@ void main() { final expr = Field('a').add(Field('b')); expect(expr.toMap(), { 'name': 'add', - 'args': { - 'left': Field('a').toMap(), - 'right': Field('b').toMap(), - }, + 'args': {'left': Field('a').toMap(), 'right': Field('b').toMap()}, }); }); @@ -790,17 +762,11 @@ void main() { }); test('Expression.map serializes correctly', () { - final expr = Expression.map({ - 'k1': Constant(1), - 'k2': Field('v'), - }); + final expr = Expression.map({'k1': Constant(1), 'k2': Field('v')}); expect(expr.toMap(), { 'name': 'map', 'args': { - 'data': { - 'k1': Constant(1).toMap(), - 'k2': Field('v').toMap(), - }, + 'data': {'k1': Constant(1).toMap(), 'k2': Field('v').toMap()}, }, }); }); @@ -830,10 +796,7 @@ void main() { final expr = Expression.timestampTruncate(Field('ts'), 'day'); expect(expr.toMap(), { 'name': 'timestamp_truncate', - 'args': { - 'timestamp': Field('ts').toMap(), - 'unit': 'day', - }, + 'args': {'timestamp': Field('ts').toMap(), 'unit': 'day'}, }); }); }); @@ -991,10 +954,7 @@ void main() { final expr = Field('n').isType(Type.int64); expect(expr.toMap(), { 'name': 'is_type', - 'args': { - 'expression': Field('n').toMap(), - 'type': 'int64', - }, + 'args': {'expression': Field('n').toMap(), 'type': 'int64'}, }); }); @@ -1035,10 +995,7 @@ void main() { final expr = Field('tags').arrayFirstN(2); expect(expr.toMap(), { 'name': 'array_first_n', - 'args': { - 'expression': Field('tags').toMap(), - 'n': Constant(2).toMap(), - }, + 'args': {'expression': Field('tags').toMap(), 'n': Constant(2).toMap()}, }); }); @@ -1166,11 +1123,7 @@ void main() { test('switchOn rejects invalid default', () { expect( - () => Expression.switchOn( - Field('x').equalValue(0), - Constant('a'), - 42, - ), + () => Expression.switchOn(Field('x').equalValue(0), Constant('a'), 42), throwsA(isA()), ); }); diff --git a/packages/cloud_firestore/cloud_firestore/test/pipeline_snapshot_test.dart b/packages/cloud_firestore/cloud_firestore/test/pipeline_snapshot_test.dart index 5d727129ab44..262d6ae017a9 100644 --- a/packages/cloud_firestore/cloud_firestore/test/pipeline_snapshot_test.dart +++ b/packages/cloud_firestore/cloud_firestore/test/pipeline_snapshot_test.dart @@ -37,19 +37,14 @@ void main() { }); test('document is null for aggregate-only result', () { - final result = PipelineResult( - data: {'count': 42}, - ); + final result = PipelineResult(data: {'count': 42}); expect(result.document, isNull); }); test('stores createTime and updateTime', () { final create = DateTime(2026); final update = DateTime(2026, 1, 2); - final result = PipelineResult( - createTime: create, - updateTime: update, - ); + final result = PipelineResult(createTime: create, updateTime: update); expect(result.createTime, create); expect(result.updateTime, update); }); diff --git a/packages/cloud_firestore/cloud_firestore/test/pipeline_source_test.dart b/packages/cloud_firestore/cloud_firestore/test/pipeline_source_test.dart index a7279c1b1896..e5c64f11b5ab 100644 --- a/packages/cloud_firestore/cloud_firestore/test/pipeline_source_test.dart +++ b/packages/cloud_firestore/cloud_firestore/test/pipeline_source_test.dart @@ -40,10 +40,7 @@ void main() { }); test('throws on empty path', () { - expect( - () => firestore.pipeline().collection(''), - throwsArgumentError, - ); + expect(() => firestore.pipeline().collection(''), throwsArgumentError); }); test('throws on path containing double slash', () { @@ -66,12 +63,12 @@ void main() { }); test('uses path from nested collection reference', () { - final colRef = - firestore.collection('users').doc('u1').collection('posts'); + final colRef = firestore + .collection('users') + .doc('u1') + .collection('posts'); final pipeline = firestore.pipeline().collectionReference(colRef); - expect(pipeline.stages.first['args'], { - 'path': 'users/u1/posts', - }); + expect(pipeline.stages.first['args'], {'path': 'users/u1/posts'}); }); }); @@ -106,10 +103,9 @@ void main() { final pipeline = firestore.pipeline().documents([docRef]); expect(pipeline.stages, hasLength(1)); expect(pipeline.stages.first['stage'], 'documents'); - expect( - (pipeline.stages.first['args'] as List).first, - {'path': 'users/123'}, - ); + expect((pipeline.stages.first['args'] as List).first, { + 'path': 'users/123', + }); }); test('supports multiple document references', () { @@ -123,10 +119,7 @@ void main() { }); test('throws on empty list', () { - expect( - () => firestore.pipeline().documents([]), - throwsArgumentError, - ); + expect(() => firestore.pipeline().documents([]), throwsArgumentError); }); }); diff --git a/packages/cloud_firestore/cloud_firestore/test/pipeline_stage_test.dart b/packages/cloud_firestore/cloud_firestore/test/pipeline_stage_test.dart index 41a6fba094db..ceecd570e324 100644 --- a/packages/cloud_firestore/cloud_firestore/test/pipeline_stage_test.dart +++ b/packages/cloud_firestore/cloud_firestore/test/pipeline_stage_test.dart @@ -37,10 +37,7 @@ void main() { }); test('throws on empty collection path', () { - expect( - () => firestore.pipeline().collection(''), - throwsArgumentError, - ); + expect(() => firestore.pipeline().collection(''), throwsArgumentError); }); test('throws on collection path with double slashes', () { @@ -101,10 +98,7 @@ void main() { }); test('throws on empty documents list', () { - expect( - () => firestore.pipeline().documents([]), - throwsArgumentError, - ); + expect(() => firestore.pipeline().documents([]), throwsArgumentError); }); }); @@ -155,7 +149,10 @@ void main() { }); test('serializes addFields with multiple fields', () { - final pipeline = firestore.pipeline().collection('users').addFields( + final pipeline = firestore + .pipeline() + .collection('users') + .addFields( Field('a').as('x'), Field('b').as('y'), Field('c').as('z'), @@ -212,15 +209,15 @@ void main() { }); test('serializes multiple orderings', () { - final pipeline = firestore.pipeline().collection('users').sort( + final pipeline = firestore + .pipeline() + .collection('users') + .sort( Ordering(Field('lastName'), OrderDirection.asc), Ordering(Field('firstName'), OrderDirection.asc), ); final stage = pipeline.stages.last; - expect( - stage['args']['orderings'] as List, - hasLength(2), - ); + expect(stage['args']['orderings'] as List, hasLength(2)); }); }); @@ -232,33 +229,30 @@ void main() { .aggregate(CountAll().as('totalCount')); final stage = pipeline.stages.last; expect(stage['stage'], 'aggregate'); - expect( - stage['args']['aggregate_functions'], - hasLength(1), - ); + expect(stage['args']['aggregate_functions'], hasLength(1)); }); test('serializes multiple aggregate functions', () { - final pipeline = firestore.pipeline().collection('orders').aggregate( + final pipeline = firestore + .pipeline() + .collection('orders') + .aggregate( CountAll().as('count'), Sum(Field('amount')).as('total'), ); final stage = pipeline.stages.last; - expect( - stage['args']['aggregate_functions'] as List, - hasLength(2), - ); + expect(stage['args']['aggregate_functions'] as List, hasLength(2)); }); }); group('_AggregateStageWithOptions', () { test('serializes aggregate stage with accumulators only', () { - final pipeline = - firestore.pipeline().collection('orders').aggregateWithOptions( - AggregateStageOptions( - accumulators: [CountAll().as('count')], - ), - ); + final pipeline = firestore + .pipeline() + .collection('orders') + .aggregateWithOptions( + AggregateStageOptions(accumulators: [CountAll().as('count')]), + ); final stage = pipeline.stages.last; expect(stage['stage'], 'aggregate_with_options'); final aggregateStage = @@ -268,16 +262,18 @@ void main() { }); test('serializes aggregate stage with accumulators and groups', () { - final pipeline = - firestore.pipeline().collection('orders').aggregateWithOptions( - AggregateStageOptions( - accumulators: [ - Sum(Field('amount')).as('total'), - CountAll().as('count'), - ], - groups: [Field('category')], - ), - ); + final pipeline = firestore + .pipeline() + .collection('orders') + .aggregateWithOptions( + AggregateStageOptions( + accumulators: [ + Sum(Field('amount')).as('total'), + CountAll().as('count'), + ], + groups: [Field('category')], + ), + ); final stage = pipeline.stages.last; expect(stage['stage'], 'aggregate_with_options'); final aggregateStage = @@ -287,12 +283,12 @@ void main() { }); test('includes options map in args', () { - final pipeline = - firestore.pipeline().collection('orders').aggregateWithOptions( - AggregateStageOptions( - accumulators: [CountAll().as('count')], - ), - ); + final pipeline = firestore + .pipeline() + .collection('orders') + .aggregateWithOptions( + AggregateStageOptions(accumulators: [CountAll().as('count')]), + ); final stage = pipeline.stages.last; expect(stage['args'].containsKey('options'), isTrue); }); @@ -300,8 +296,10 @@ void main() { group('_DistinctStage', () { test('serializes distinct stage', () { - final pipeline = - firestore.pipeline().collection('users').distinct(Field('country')); + final pipeline = firestore + .pipeline() + .collection('users') + .distinct(Field('country')); final stage = pipeline.stages.last; expect(stage['stage'], 'distinct'); expect(stage['args']['expressions'], hasLength(1)); @@ -363,10 +361,10 @@ void main() { group('_FindNearestStage', () { test('serializes findNearest without limit', () { final pipeline = firestore.pipeline().collection('items').findNearest( - Field('embedding'), - [0.1, 0.2, 0.3], - DistanceMeasure.cosine, - ); + Field('embedding'), + [0.1, 0.2, 0.3], + DistanceMeasure.cosine, + ); final stage = pipeline.stages.last; expect(stage['stage'], 'find_nearest'); expect(stage['args']['vector_field'], 'embedding'); @@ -376,7 +374,10 @@ void main() { }); test('serializes findNearest with limit', () { - final pipeline = firestore.pipeline().collection('items').findNearest( + final pipeline = firestore + .pipeline() + .collection('items') + .findNearest( Field('embedding'), [0.1, 0.2, 0.3], DistanceMeasure.euclidean, @@ -389,10 +390,10 @@ void main() { test('serializes findNearest with dotProduct distance', () { final pipeline = firestore.pipeline().collection('items').findNearest( - Field('embedding'), - [1.0, 0.0], - DistanceMeasure.dotProduct, - ); + Field('embedding'), + [1.0, 0.0], + DistanceMeasure.dotProduct, + ); final stage = pipeline.stages.last; expect(stage['args']['distance_measure'], 'dotProduct'); }); @@ -400,7 +401,10 @@ void main() { group('_SearchStage', () { test('serializes search with string query', () { - final pipeline = firestore.pipeline().collection('restaurants').search( + final pipeline = firestore + .pipeline() + .collection('restaurants') + .search( SearchStage.withQuery( 'breakfast -diner', limit: 10, @@ -420,7 +424,10 @@ void main() { }); test('serializes search with query expression', () { - final pipeline = firestore.pipeline().collection('restaurants').search( + final pipeline = firestore + .pipeline() + .collection('restaurants') + .search( SearchStage.withQueryExpression( Expression.documentMatches('waffles OR pancakes'), ), @@ -435,7 +442,10 @@ void main() { }); test('serializes search sort and add fields', () { - final pipeline = firestore.pipeline().collection('restaurants').search( + final pipeline = firestore + .pipeline() + .collection('restaurants') + .search( SearchStage.withQuery( 'breakfast', sort: [Field('rating').descending()], @@ -475,15 +485,14 @@ void main() { group('_UnionStage', () { test('serializes union stage with nested pipeline stages', () { final innerPipeline = firestore.pipeline().collection('archived_users'); - final pipeline = - firestore.pipeline().collection('users').union(innerPipeline); + final pipeline = firestore + .pipeline() + .collection('users') + .union(innerPipeline); final stage = pipeline.stages.last; expect(stage['stage'], 'union'); expect(stage['args']['pipeline'], isA()); - expect( - stage['args']['pipeline'] as List, - hasLength(1), - ); + expect(stage['args']['pipeline'] as List, hasLength(1)); }); }); diff --git a/packages/cloud_firestore/cloud_firestore/test/query_test.dart b/packages/cloud_firestore/cloud_firestore/test/query_test.dart index 44a5db00553b..67f88035dea4 100644 --- a/packages/cloud_firestore/cloud_firestore/test/query_test.dart +++ b/packages/cloud_firestore/cloud_firestore/test/query_test.dart @@ -57,29 +57,29 @@ void main() { .where('foo.bar', isGreaterThan: 1234); }); - test('throw an exception when making query combining `in` & `not-in`', - () { - expect( - () => query!.where('number', whereIn: [1, 2], whereNotIn: [3, 4]), - throwsAssertionError, - ); + test( + 'throw an exception when making query combining `in` & `not-in`', + () { + expect( + () => query!.where('number', whereIn: [1, 2], whereNotIn: [3, 4]), + throwsAssertionError, + ); - expect( - () => query!.where('number', whereIn: [1, 2]).where( - 'number', - whereNotIn: [3, 4], - ), - throwsAssertionError, - ); + expect( + () => query! + .where('number', whereIn: [1, 2]) + .where('number', whereNotIn: [3, 4]), + throwsAssertionError, + ); - expect( - () => query!.where('number', whereNotIn: [3, 4]).where( - 'number', - whereIn: [1, 2], - ), - throwsAssertionError, - ); - }); + expect( + () => query! + .where('number', whereNotIn: [3, 4]) + .where('number', whereIn: [1, 2]), + throwsAssertionError, + ); + }, + ); test('allows inequality different to first orderBy', () { query!.where('foo', isGreaterThan: 123).orderBy('bar'); @@ -105,10 +105,7 @@ void main() { test('throws if arrayContainsAny query length is greater than 30', () { List numbers = List.generate(31, (i) => i + 1); expect( - () => query!.where( - 'foo', - arrayContainsAny: numbers, - ), + () => query!.where('foo', arrayContainsAny: numbers), throwsAssertionError, ); }); @@ -148,20 +145,18 @@ void main() { throwsAssertionError, ); expect( - () => query!.where( - 'foo.bar', - arrayContainsAny: [1, 2], - ).where('foo.bar', arrayContains: 3), + () => query! + .where('foo.bar', arrayContainsAny: [1, 2]) + .where('foo.bar', arrayContains: 3), throwsAssertionError, ); }); test('throws if multiple disjunctive filters in query', () { expect( - () => query!.where('foo', arrayContainsAny: [1]).where( - 'foo', - arrayContainsAny: [2, 3], - ), + () => query! + .where('foo', arrayContainsAny: [1]) + .where('foo', arrayContainsAny: [2, 3]), throwsAssertionError, ); expect( @@ -172,40 +167,42 @@ void main() { throwsAssertionError, ); expect( - () => query!.where('foo', arrayContains: 1).where( - 'foo', - whereIn: [2, 3], - ).where('foo', arrayContainsAny: [2]), + () => query! + .where('foo', arrayContains: 1) + .where('foo', whereIn: [2, 3]) + .where('foo', arrayContainsAny: [2]), throwsAssertionError, ); }); test( - 'throws if FieldPath.documentId field is used in conjunction with isNotEqualTo filter', - () { - expect( - () => query! - .where(FieldPath.documentId, isEqualTo: 'fake-id') - .where('foo', isNotEqualTo: 'bar'), - throwsAssertionError, - ); + 'throws if FieldPath.documentId field is used in conjunction with isNotEqualTo filter', + () { + expect( + () => query! + .where(FieldPath.documentId, isEqualTo: 'fake-id') + .where('foo', isNotEqualTo: 'bar'), + throwsAssertionError, + ); - expect( - () => query! - .where('foo', isNotEqualTo: 'bar') - .where(FieldPath.documentId, whereIn: [2, 3]), - throwsAssertionError, - ); - }); + expect( + () => query! + .where('foo', isNotEqualTo: 'bar') + .where(FieldPath.documentId, whereIn: [2, 3]), + throwsAssertionError, + ); + }, + ); test( - 'allow isNotEqualTo filter on FieldPath.documentId field & a different field on a separate filter', - () { - query! - .where(FieldPath.documentId, isNotEqualTo: 'fake-id') - .where(FieldPath.documentId, isEqualTo: 'another-fake-id') - .where('foo', isNull: true); - }); + 'allow isNotEqualTo filter on FieldPath.documentId field & a different field on a separate filter', + () { + query! + .where(FieldPath.documentId, isNotEqualTo: 'fake-id') + .where(FieldPath.documentId, isEqualTo: 'another-fake-id') + .where('foo', isNull: true); + }, + ); test('allows arrayContains with whereIn filter', () { query!.where('foo', arrayContains: 1).where('foo', whereIn: [2, 3]); @@ -369,34 +366,39 @@ void main() { }); group('Settings()', () { - test('Test the assert for setting `cacheSizeBytes` minimum and maximum', - () { - void configureCache(int? cacheSizeBytes) { - assert( - cacheSizeBytes == null || - cacheSizeBytes == Settings.CACHE_SIZE_UNLIMITED || - (cacheSizeBytes >= 1048576 && cacheSizeBytes <= 104857600), - 'Cache size, if specified, must be either CACHE_SIZE_UNLIMITED or between 1048576 bytes (inclusive) and 104857600 bytes (inclusive).', + test( + 'Test the assert for setting `cacheSizeBytes` minimum and maximum', + () { + void configureCache(int? cacheSizeBytes) { + assert( + cacheSizeBytes == null || + cacheSizeBytes == Settings.CACHE_SIZE_UNLIMITED || + (cacheSizeBytes >= 1048576 && cacheSizeBytes <= 104857600), + 'Cache size, if specified, must be either CACHE_SIZE_UNLIMITED or between 1048576 bytes (inclusive) and 104857600 bytes (inclusive).', + ); + } + + // Happy paths + expect(() => configureCache(null), returnsNormally); + expect( + () => configureCache(Settings.CACHE_SIZE_UNLIMITED), + returnsNormally, ); - } - - // Happy paths - expect(() => configureCache(null), returnsNormally); - expect( - () => configureCache(Settings.CACHE_SIZE_UNLIMITED), - returnsNormally, - ); - expect(() => configureCache(5000000), returnsNormally); - expect(() => configureCache(1048577), returnsNormally); - expect(() => configureCache(104857600), returnsNormally); - expect(() => configureCache(104857500), returnsNormally); - - // Assertion triggers - expect(() => configureCache(1), throwsA(isA())); - expect(() => configureCache(1000), throwsA(isA())); - expect(() => configureCache(200000000), throwsA(isA())); - expect(() => configureCache(500000), throwsA(isA())); - }); + expect(() => configureCache(5000000), returnsNormally); + expect(() => configureCache(1048577), returnsNormally); + expect(() => configureCache(104857600), returnsNormally); + expect(() => configureCache(104857500), returnsNormally); + + // Assertion triggers + expect(() => configureCache(1), throwsA(isA())); + expect(() => configureCache(1000), throwsA(isA())); + expect( + () => configureCache(200000000), + throwsA(isA()), + ); + expect(() => configureCache(500000), throwsA(isA())); + }, + ); }); }); } diff --git a/packages/cloud_firestore/cloud_firestore/test/test_firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore/test/test_firestore_message_codec.dart index c7ad874ffd2e..7077b82aa6d9 100644 --- a/packages/cloud_firestore/cloud_firestore/test/test_firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore/test/test_firestore_message_codec.dart @@ -63,10 +63,7 @@ class TestFirestoreMessageCodec extends FirestoreMessageCodec { String databaseId = readValue(buffer)! as String; readValue(buffer); final FirebaseApp app = Firebase.app(appName); - return MethodChannelFirebaseFirestore( - app: app, - databaseId: databaseId, - ); + return MethodChannelFirebaseFirestore(app: app, databaseId: databaseId); case _kFirestoreQuery: String appName = readValue(buffer)! as String; Map values = diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart index a6332c48ea7a..ff55d6e989fb 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart @@ -20,11 +20,11 @@ class FieldPath { /// Creates a new [FieldPath]. FieldPath(this.components) - : assert(components.isNotEmpty), - assert( - components.where((component) => component.isEmpty).isEmpty, - 'Expected all FieldPath components to be non-null or non-empty strings.', - ); + : assert(components.isNotEmpty), + assert( + components.where((component) => component.isEmpty).isEmpty, + 'Expected all FieldPath components to be non-null or non-empty strings.', + ); /// Returns a special sentinel `FieldPath` to refer to the ID of a document. /// @@ -40,16 +40,16 @@ class FieldPath { /// field contains a '.', construct a new [FieldPath] instance and provide /// the field as a [List] element. FieldPath.fromString(String path) - : components = path.split('.'), - assert(path.isNotEmpty), - assert(!path.startsWith('.')), - assert(!path.endsWith('.')), - assert(!path.contains('..')), - assert(!path.contains('~'), _reserved), - assert(!path.contains('*'), _reserved), - assert(!path.contains('/'), _reserved), - assert(!path.contains('['), _reserved), - assert(!path.contains(']'), _reserved); + : components = path.split('.'), + assert(path.isNotEmpty), + assert(!path.startsWith('.')), + assert(!path.endsWith('.')), + assert(!path.contains('..')), + assert(!path.contains('~'), _reserved), + assert(!path.contains('*'), _reserved), + assert(!path.contains('/'), _reserved), + assert(!path.contains('['), _reserved), + assert(!path.contains(']'), _reserved); @override bool operator ==(Object other) => diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart index 3c9308773f2e..885ede3e21d0 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart @@ -10,8 +10,8 @@ import 'package:meta/meta.dart'; class GeoPoint { /// Create [GeoPoint] instance. const GeoPoint(this.latitude, this.longitude) - : assert(latitude >= -90 && latitude <= 90), - assert(longitude >= -180 && longitude <= 180); + : assert(latitude >= -90 && latitude <= 90), + assert(longitude >= -180 && longitude <= 180); final double latitude; // ignore: public_member_api_docs final double longitude; // ignore: public_member_api_docs diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/internal/pointer.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/internal/pointer.dart index 3ec4e3077aa2..69a1ec4ee288 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/internal/pointer.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/internal/pointer.dart @@ -14,8 +14,10 @@ import 'package:meta/meta.dart'; class Pointer { /// Create instance of [Pointer] Pointer(String path) - : components = - path.split('/').where((element) => element.isNotEmpty).toList(); + : components = path + .split('/') + .where((element) => element.isNotEmpty) + .toList(); /// The Firestore normalized path of the [Pointer]. String get path { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_aggregate_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_aggregate_query.dart index ac3193875c3d..01aee8ea10f7 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_aggregate_query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_aggregate_query.dart @@ -27,15 +27,15 @@ class MethodChannelAggregateQuery extends AggregateQueryPlatform { Future get({ required AggregateSource source, }) async { - final data = - await MethodChannelFirebaseFirestore.pigeonChannel.aggregateQuery( - _pigeonApp, - _path, - _pigeonParameters, - source, - _aggregateQueries, - _isCollectionGroupQuery, - ); + final data = await MethodChannelFirebaseFirestore.pigeonChannel + .aggregateQuery( + _pigeonApp, + _path, + _pigeonParameters, + source, + _aggregateQueries, + _isCollectionGroupQuery, + ); int? count; List sum = []; @@ -69,10 +69,7 @@ class MethodChannelAggregateQuery extends AggregateQueryPlatform { _pigeonParameters, _path, _pigeonApp, - [ - ..._aggregateQueries, - AggregateQuery(type: AggregateType.count), - ], + [..._aggregateQueries, AggregateQuery(type: AggregateType.count)], _isCollectionGroupQuery, ); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart index baae7aea9cbb..aee9d3b12049 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart @@ -21,15 +21,15 @@ import 'utils/auto_id_generator.dart'; /// errors, now you know why. class MethodChannelCollectionReference extends MethodChannelQuery implements -// ignore: avoid_implementing_value_types + // ignore: avoid_implementing_value_types CollectionReferencePlatform { /// Create a [MethodChannelCollectionReference] instance. MethodChannelCollectionReference( FirebaseFirestorePlatform firestore, String path, FirestorePigeonFirebaseApp pigeonApp, - ) : _pointer = Pointer(path), - super(firestore, path, pigeonApp); + ) : _pointer = Pointer(path), + super(firestore, path, pigeonApp); final Pointer _pointer; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart index 0469941a7a35..dfc23c56bd16 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart @@ -9,16 +9,18 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte /// communicate with Firebase plugins. class MethodChannelDocumentChange extends DocumentChangePlatform { /// Creates a [MethodChannelDocumentChange] from the given [data] - MethodChannelDocumentChange(FirebaseFirestorePlatform firestore, - InternalDocumentChange documentChange) - : super( - documentChange.type, - documentChange.oldIndex, - documentChange.newIndex, - DocumentSnapshotPlatform( - firestore, - documentChange.document.path, - documentChange.document.data, - documentChange.document.metadata, - )); + MethodChannelDocumentChange( + FirebaseFirestorePlatform firestore, + InternalDocumentChange documentChange, + ) : super( + documentChange.type, + documentChange.oldIndex, + documentChange.newIndex, + DocumentSnapshotPlatform( + firestore, + documentChange.document.path, + documentChange.document.data, + documentChange.document.metadata, + ), + ); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart index e957d4c63fbb..a9077caa43c3 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart @@ -39,8 +39,9 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { data: data, option: InternalDocumentOption( merge: options?.merge, - mergeFields: - options?.mergeFields?.map((e) => e.components).toList(), + mergeFields: options?.mergeFields + ?.map((e) => e.components) + .toList(), ), ), ); @@ -54,30 +55,28 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { try { await MethodChannelFirebaseFirestore.pigeonChannel .documentReferenceUpdate( - pigeonApp, - DocumentReferenceRequest( - path: _pointer.path, - data: data, - ), - ); + pigeonApp, + DocumentReferenceRequest(path: _pointer.path, data: data), + ); } catch (e, stack) { convertPlatformException(e, stack); } } @override - Future get( - [GetOptions options = const GetOptions()]) async { + Future get([ + GetOptions options = const GetOptions(), + ]) async { try { final result = await MethodChannelFirebaseFirestore.pigeonChannel .documentReferenceGet( - pigeonApp, - DocumentReferenceRequest( - path: _pointer.path, - source: options.source, - serverTimestampBehavior: options.serverTimestampBehavior, - ), - ); + pigeonApp, + DocumentReferenceRequest( + path: _pointer.path, + source: options.source, + serverTimestampBehavior: options.serverTimestampBehavior, + ), + ); return DocumentSnapshotPlatform( firestore, @@ -95,11 +94,9 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { try { await MethodChannelFirebaseFirestore.pigeonChannel .documentReferenceDelete( - pigeonApp, - DocumentReferenceRequest( - path: _pointer.path, - ), - ); + pigeonApp, + DocumentReferenceRequest(path: _pointer.path), + ); } catch (e, stack) { convertPlatformException(e, stack); } @@ -115,43 +112,40 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { // It's fine to let the StreamController be garbage collected once all the // subscribers have cancelled; this analyzer warning is safe to ignore. late StreamController - controller; // ignore: close_sinks + controller; // ignore: close_sinks StreamSubscription? snapshotStreamSubscription; controller = StreamController.broadcast( onListen: () async { final observerId = await MethodChannelFirebaseFirestore.pigeonChannel .documentReferenceSnapshot( - pigeonApp, - DocumentReferenceRequest( - path: _pointer.path, - serverTimestampBehavior: serverTimestampBehavior, - ), - includeMetadataChanges, - listenSource, - ); - snapshotStreamSubscription = - MethodChannelFirebaseFirestore.documentSnapshotChannel(observerId) - .receiveGuardedBroadcastStream( - onError: convertPlatformException, - ) - .listen( - (snapshot) { - // With Pigeon 26, the native side emits the generated Pigeon class - // directly through the Pigeon-aware codec, so we receive a fully - // decoded `InternalDocumentSnapshot` here (no manual decode required). - final result = snapshot as InternalDocumentSnapshot; - controller.add( - DocumentSnapshotPlatform( - firestore, - result.path, - result.data, - result.metadata, + pigeonApp, + DocumentReferenceRequest( + path: _pointer.path, + serverTimestampBehavior: serverTimestampBehavior, ), + includeMetadataChanges, + listenSource, ); - }, - onError: controller.addError, - ); + snapshotStreamSubscription = + MethodChannelFirebaseFirestore.documentSnapshotChannel( + observerId, + ).receiveGuardedBroadcastStream(onError: convertPlatformException).listen(( + snapshot, + ) { + // With Pigeon 26, the native side emits the generated Pigeon class + // directly through the Pigeon-aware codec, so we receive a fully + // decoded `InternalDocumentSnapshot` here (no manual decode required). + final result = snapshot as InternalDocumentSnapshot; + controller.add( + DocumentSnapshotPlatform( + firestore, + result.path, + result.data, + result.metadata, + ), + ); + }, onError: controller.addError); }, onCancel: () { snapshotStreamSubscription?.cancel(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart index 7145fedd0545..ddc65349bb0e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart @@ -37,7 +37,8 @@ class MethodChannelFieldValueFactory extends FieldValueFactoryPlatform { } throw StateError( - 'MethodChannelFieldValue().increment() expects a "num" value'); + 'MethodChannelFieldValue().increment() expects a "num" value', + ); } @override diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart index a29d7bdb725b..fe3b91a1a68c 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart @@ -28,7 +28,7 @@ import 'utils/exception.dart'; class MethodChannelFirebaseFirestore extends FirebaseFirestorePlatform { /// Create an instance of [MethodChannelFirebaseFirestore] with optional [FirebaseApp] MethodChannelFirebaseFirestore({FirebaseApp? app, String? databaseId}) - : super(appInstance: app, databaseChoice: databaseId); + : super(appInstance: app, databaseChoice: databaseId); /// The [FirebaseApp] instance to which this [FirebaseDatabase] belongs. /// @@ -122,7 +122,8 @@ class MethodChannelFirebaseFirestore extends FirebaseFirestorePlatform { FirebaseException( plugin: 'cloud_firestore', code: 'non-existent-named-query', - message: 'Named query has not been found. ' + message: + 'Named query has not been found. ' 'Please check it has been loaded properly via loadBundle().', ), stack, @@ -195,12 +196,13 @@ class MethodChannelFirebaseFirestore extends FirebaseFirestorePlatform { snapshotStreamSubscription = MethodChannelFirebaseFirestore.snapshotsInSyncChannel(observerId) .receiveGuardedBroadcastStream( - arguments: {'firestore': this}, - onError: convertPlatformException, - ).listen( - (event) => controller.add(null), - onError: controller.addError, - ); + arguments: {'firestore': this}, + onError: convertPlatformException, + ) + .listen( + (event) => controller.add(null), + onError: controller.addError, + ); }, onCancel: () { snapshotStreamSubscription?.cancel(); @@ -216,8 +218,10 @@ class MethodChannelFirebaseFirestore extends FirebaseFirestorePlatform { Duration timeout = const Duration(seconds: 30), int maxAttempts = 5, }) async { - assert(timeout.inMilliseconds > 0, - 'Transaction timeout must be more than 0 milliseconds'); + assert( + timeout.inMilliseconds > 0, + 'Transaction timeout must be more than 0 milliseconds', + ); final String transactionId = await pigeonChannel.transactionCreate( pigeonApp, @@ -235,81 +239,80 @@ class MethodChannelFirebaseFirestore extends FirebaseFirestorePlatform { const StandardMethodCodec(PigeonCodec()), ); - final snapshotStreamSubscription = - eventChannel.receiveGuardedBroadcastStream( - arguments: { - 'firestore': this, - 'timeout': timeout.inMilliseconds, - 'maxAttempts': maxAttempts, - }, - onError: convertPlatformException, - ).listen( - (event) async { - if (event['error'] != null) { - if (!completer.isCompleted) { - completer.completeError( - FirebaseException( - plugin: 'cloud_firestore', - code: event['error']['code'], - message: event['error']['message'], - ), - ); - } - return; - } else if (event['complete'] == true) { - if (!completer.isCompleted) { - completer.complete(result); - } - return; - } - - final TransactionPlatform transaction = MethodChannelTransaction( - transactionId, - event['appName'], - pigeonApp, - databaseId, - ); - - // If the transaction fails on Dart side, then forward the error - // right away and only inform native side of the error. - try { - result = await transactionHandler(transaction) as T; - } catch (error, stack) { - if (completer.isCompleted) { + final snapshotStreamSubscription = eventChannel + .receiveGuardedBroadcastStream( + arguments: { + 'firestore': this, + 'timeout': timeout.inMilliseconds, + 'maxAttempts': maxAttempts, + }, + onError: convertPlatformException, + ) + .listen((event) async { + if (event['error'] != null) { + if (!completer.isCompleted) { + completer.completeError( + FirebaseException( + plugin: 'cloud_firestore', + code: event['error']['code'], + message: event['error']['message'], + ), + ); + } + return; + } else if (event['complete'] == true) { + if (!completer.isCompleted) { + completer.complete(result); + } return; } - // Signal native that a user error occurred, and finish the - // transaction - await pigeonChannel.transactionStoreResult( + final TransactionPlatform transaction = MethodChannelTransaction( transactionId, - InternalTransactionResult.failure, - null, + event['appName'], + pigeonApp, + databaseId, ); - // Native may report an error while the result is being stored. - if (completer.isCompleted) { - return; - } + // If the transaction fails on Dart side, then forward the error + // right away and only inform native side of the error. + try { + result = await transactionHandler(transaction) as T; + } catch (error, stack) { + if (completer.isCompleted) { + return; + } + + // Signal native that a user error occurred, and finish the + // transaction + await pigeonChannel.transactionStoreResult( + transactionId, + InternalTransactionResult.failure, + null, + ); + + // Native may report an error while the result is being stored. + if (completer.isCompleted) { + return; + } - // Allow the [runTransaction] method to listen to an error. - completer.completeError(error, stack); + // Allow the [runTransaction] method to listen to an error. + completer.completeError(error, stack); - return; - } + return; + } - if (completer.isCompleted) { - return; - } + if (completer.isCompleted) { + return; + } - // Send the transaction commands to Dart. - await pigeonChannel.transactionStoreResult( - transactionId, - InternalTransactionResult.success, - transaction.commands, - ); - }, - ); + // Send the transaction commands to Dart. + await pigeonChannel.transactionStoreResult( + transactionId, + InternalTransactionResult.success, + transaction.commands, + ); + }); return completer.future.whenComplete(snapshotStreamSubscription.cancel); } @@ -338,10 +341,7 @@ class MethodChannelFirebaseFirestore extends FirebaseFirestorePlatform { @override Future setIndexConfiguration(String indexConfiguration) async { try { - await pigeonChannel.setIndexConfiguration( - pigeonApp, - indexConfiguration, - ); + await pigeonChannel.setIndexConfiguration(pigeonApp, indexConfiguration); } catch (e, stack) { convertPlatformException(e, stack); } @@ -351,18 +351,13 @@ class MethodChannelFirebaseFirestore extends FirebaseFirestorePlatform { PersistentCacheIndexManagerPlatform? persistentCacheIndexManager() { // Persistence is enabled by default, if the user has disabled it, return null. if (settings.persistenceEnabled == false) return null; - return MethodChannelPersistentCacheIndexManager( - pigeonChannel, - pigeonApp, - ); + return MethodChannelPersistentCacheIndexManager(pigeonChannel, pigeonApp); } @override Future setLoggingEnabled(bool enabled) async { try { - await pigeonChannel.setLoggingEnabled( - enabled, - ); + await pigeonChannel.setLoggingEnabled(enabled); } catch (e, stack) { convertPlatformException(e, stack); } @@ -389,12 +384,8 @@ class MethodChannelFirebaseFirestore extends FirebaseFirestorePlatform { MapEntry.new, ); - final InternalPipelineSnapshot result = - await pigeonChannel.executePipeline( - pigeonApp, - pigeonStages, - pigeonOptions, - ); + final InternalPipelineSnapshot result = await pigeonChannel + .executePipeline(pigeonApp, pigeonStages, pigeonOptions); return MethodChannelPipelineSnapshot(this, pigeonApp, result); } catch (e, stack) { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_load_bundle_task.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_load_bundle_task.dart index c3a0d5922aac..2ff14f6a37bd 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_load_bundle_task.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_load_bundle_task.dart @@ -12,21 +12,22 @@ import 'package:flutter/services.dart'; import 'method_channel_firestore.dart'; class MethodChannelLoadBundleTask extends LoadBundleTaskPlatform { - MethodChannelLoadBundleTask({ - required Future task, - }) : super() { + MethodChannelLoadBundleTask({required Future task}) : super() { Stream mapNativeStream() async* { final observerId = await task; final nativePlatformStream = - MethodChannelFirebaseFirestore.loadBundleChannel(observerId!) - .receiveBroadcastStream(); + MethodChannelFirebaseFirestore.loadBundleChannel( + observerId!, + ).receiveBroadcastStream(); try { await for (final snapshot in nativePlatformStream) { final taskState = convertToTaskState(snapshot['taskState']); yield LoadBundleTaskSnapshotPlatform( - taskState, Map.from(snapshot)); + taskState, + Map.from(snapshot), + ); if (taskState == LoadBundleTaskState.success) { // this will close the stream and stop listening to nativePlatformStream @@ -45,14 +46,17 @@ class MethodChannelLoadBundleTask extends LoadBundleTaskPlatform { : null; throw FirebaseException( - plugin: 'cloud_firestore', - code: 'load-bundle-error', - message: details?['message'] ?? ''); + plugin: 'cloud_firestore', + code: 'load-bundle-error', + message: details?['message'] ?? '', + ); } } stream = mapNativeStream().asBroadcastStream( - onListen: (sub) => sub.resume(), onCancel: (sub) => sub.pause()); + onListen: (sub) => sub.resume(), + onCancel: (sub) => sub.pause(), + ); } @override diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_persistent_cache_index_manager.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_persistent_cache_index_manager.dart index c164eb521f71..5113743e5365 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_persistent_cache_index_manager.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_persistent_cache_index_manager.dart @@ -6,10 +6,7 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte class MethodChannelPersistentCacheIndexManager extends PersistentCacheIndexManagerPlatform { - MethodChannelPersistentCacheIndexManager( - this.api, - this.app, - ) : super(); + MethodChannelPersistentCacheIndexManager(this.api, this.app) : super(); final FirebaseFirestoreHostApi api; final FirestorePigeonFirebaseApp app; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_pipeline.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_pipeline.dart index 7e0b65e43c7d..99cd7b6ff093 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_pipeline.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_pipeline.dart @@ -30,10 +30,7 @@ class MethodChannelPipeline extends pipeline.PipelinePlatform { return MethodChannelPipeline( firestore, pigeonApp, - stages: List.unmodifiable([ - ...stages, - ...newStages, - ]), + stages: List.unmodifiable([...stages, ...newStages]), ); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_pipeline_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_pipeline_snapshot.dart index a0b3a73d5bb3..2a3d49032120 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_pipeline_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_pipeline_snapshot.dart @@ -17,25 +17,27 @@ class MethodChannelPipelineSnapshot extends PipelineSnapshotPlatform { FirebaseFirestorePlatform firestore, FirestorePigeonFirebaseApp pigeonApp, InternalPipelineSnapshot pigeonSnapshot, - ) : _results = pigeonSnapshot.results - .whereType() - .map((result) => MethodChannelPipelineResult( - firestore, - pigeonApp, - result.documentPath, - result.createTime != null - ? DateTime.fromMillisecondsSinceEpoch(result.createTime!) - : null, - result.updateTime != null - ? DateTime.fromMillisecondsSinceEpoch(result.updateTime!) - : null, - result.data?.cast(), - )) - .toList(), - _executionTime = DateTime.fromMillisecondsSinceEpoch( - pigeonSnapshot.executionTime, - ), - super(); + ) : _results = pigeonSnapshot.results + .whereType() + .map( + (result) => MethodChannelPipelineResult( + firestore, + pigeonApp, + result.documentPath, + result.createTime != null + ? DateTime.fromMillisecondsSinceEpoch(result.createTime!) + : null, + result.updateTime != null + ? DateTime.fromMillisecondsSinceEpoch(result.updateTime!) + : null, + result.data?.cast(), + ), + ) + .toList(), + _executionTime = DateTime.fromMillisecondsSinceEpoch( + pigeonSnapshot.executionTime, + ), + super(); @override List get results => _results; @@ -59,15 +61,11 @@ class MethodChannelPipelineResult extends PipelineResultPlatform { this._createTime, this._updateTime, Map? data, - ) : _document = (documentPath != null && documentPath.isNotEmpty) - ? MethodChannelDocumentReference( - firestore, - documentPath, - pigeonApp, - ) - : null, - _data = data, - super(); + ) : _document = (documentPath != null && documentPath.isNotEmpty) + ? MethodChannelDocumentReference(firestore, documentPath, pigeonApp) + : null, + _data = data, + super(); @override DocumentReferencePlatform? get document => _document; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart index 12604b472d7c..f2da381fad4f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart @@ -28,8 +28,8 @@ class MethodChannelQuery extends QueryPlatform { this.pigeonApp, { Map? parameters, this.isCollectionGroupQuery = false, - }) : _pointer = Pointer(path), - super(_firestore, parameters); + }) : _pointer = Pointer(path), + super(_firestore, parameters); /// Flags whether the current query is for a collection group. @override @@ -93,7 +93,9 @@ class MethodChannelQuery extends QueryPlatform { @override QueryPlatform endBeforeDocument( - Iterable orders, Iterable values) { + Iterable orders, + Iterable values, + ) { return _copyWithParameters({ 'orderBy': orders, 'endAt': null, @@ -111,20 +113,22 @@ class MethodChannelQuery extends QueryPlatform { /// Fetch the documents for this query @override - Future get( - [GetOptions options = const GetOptions()]) async { + Future get([ + GetOptions options = const GetOptions(), + ]) async { try { - final InternalQuerySnapshot result = - await MethodChannelFirebaseFirestore.pigeonChannel.queryGet( - pigeonApp, - _pointer.path, - isCollectionGroupQuery, - _pigeonParameters, - InternalGetOptions( - source: options.source, - serverTimestampBehavior: options.serverTimestampBehavior, - ), - ); + final InternalQuerySnapshot result = await MethodChannelFirebaseFirestore + .pigeonChannel + .queryGet( + pigeonApp, + _pointer.path, + isCollectionGroupQuery, + _pigeonParameters, + InternalGetOptions( + source: options.source, + serverTimestampBehavior: options.serverTimestampBehavior, + ), + ); return MethodChannelQuerySnapshot(firestore, result); } catch (e, stack) { @@ -158,41 +162,38 @@ class MethodChannelQuery extends QueryPlatform { // It's fine to let the StreamController be garbage collected once all the // subscribers have cancelled; this analyzer warning is safe to ignore. late StreamController - controller; // ignore: close_sinks + controller; // ignore: close_sinks StreamSubscription? snapshotStreamSubscription; controller = StreamController.broadcast( onListen: () async { - final observerId = - await MethodChannelFirebaseFirestore.pigeonChannel.querySnapshot( - pigeonApp, - _pointer.path, - isCollectionGroupQuery, - _pigeonParameters, - InternalGetOptions( - source: Source.serverAndCache, - serverTimestampBehavior: serverTimestampBehavior, - ), - includeMetadataChanges, - listenSource, - ); + final observerId = await MethodChannelFirebaseFirestore.pigeonChannel + .querySnapshot( + pigeonApp, + _pointer.path, + isCollectionGroupQuery, + _pigeonParameters, + InternalGetOptions( + source: Source.serverAndCache, + serverTimestampBehavior: serverTimestampBehavior, + ), + includeMetadataChanges, + listenSource, + ); snapshotStreamSubscription = - MethodChannelFirebaseFirestore.querySnapshotChannel(observerId) - .receiveGuardedBroadcastStream( - onError: convertPlatformException, - ) - .listen( - (snapshot) { - // With Pigeon 26, the native side emits the generated Pigeon class - // directly through the Pigeon-aware codec, so we receive a fully - // decoded `InternalQuerySnapshot` here (no manual decode required). - final result = snapshot as InternalQuerySnapshot; - controller.add(MethodChannelQuerySnapshot(firestore, result)); - }, - onError: controller.addError, - ); + MethodChannelFirebaseFirestore.querySnapshotChannel( + observerId, + ).receiveGuardedBroadcastStream(onError: convertPlatformException).listen(( + snapshot, + ) { + // With Pigeon 26, the native side emits the generated Pigeon class + // directly through the Pigeon-aware codec, so we receive a fully + // decoded `InternalQuerySnapshot` here (no manual decode required). + final result = snapshot as InternalQuerySnapshot; + controller.add(MethodChannelQuerySnapshot(firestore, result)); + }, onError: controller.addError); }, onCancel: () { snapshotStreamSubscription?.cancel(); @@ -204,9 +205,7 @@ class MethodChannelQuery extends QueryPlatform { @override QueryPlatform orderBy(Iterable> orders) { - return _copyWithParameters({ - 'orderBy': orders, - }); + return _copyWithParameters({'orderBy': orders}); } @override @@ -228,7 +227,9 @@ class MethodChannelQuery extends QueryPlatform { @override QueryPlatform startAtDocument( - Iterable orders, Iterable values) { + Iterable orders, + Iterable values, + ) { return _copyWithParameters({ 'orderBy': orders, 'startAt': values, @@ -246,16 +247,12 @@ class MethodChannelQuery extends QueryPlatform { @override QueryPlatform where(Iterable> conditions) { - return _copyWithParameters({ - 'where': conditions, - }); + return _copyWithParameters({'where': conditions}); } @override QueryPlatform whereFilter(FilterPlatformInterface filter) { - return _copyWithParameters({ - 'filters': filter.toJson(), - }); + return _copyWithParameters({'filters': filter.toJson()}); } @override @@ -265,11 +262,7 @@ class MethodChannelQuery extends QueryPlatform { _pigeonParameters, _pointer.path, pigeonApp, - [ - AggregateQuery( - type: AggregateType.count, - ) - ], + [AggregateQuery(type: AggregateType.count)], isCollectionGroupQuery, ); } @@ -344,28 +337,17 @@ class MethodChannelQuery extends QueryPlatform { _pigeonParameters, _pointer.path, pigeonApp, - fields.map( - (e) { - if (e is query.count) { - return AggregateQuery( - type: AggregateType.count, - ); - } else if (e is query.sum) { - return AggregateQuery( - type: AggregateType.sum, - field: e.field, - ); - } else if (e is query.average) { - return AggregateQuery( - type: AggregateType.average, - field: e.field, - ); - } else { - throw ArgumentError( - 'Unsupported aggregate method ${e.runtimeType}'); - } - }, - ).toList(), + fields.map((e) { + if (e is query.count) { + return AggregateQuery(type: AggregateType.count); + } else if (e is query.sum) { + return AggregateQuery(type: AggregateType.sum, field: e.field); + } else if (e is query.average) { + return AggregateQuery(type: AggregateType.average, field: e.field); + } else { + throw ArgumentError('Unsupported aggregate method ${e.runtimeType}'); + } + }).toList(), isCollectionGroupQuery, ); } @@ -378,12 +360,7 @@ class MethodChannelQuery extends QueryPlatform { _pigeonParameters, _pointer.path, pigeonApp, - [ - AggregateQuery( - type: AggregateType.sum, - field: field, - ) - ], + [AggregateQuery(type: AggregateType.sum, field: field)], isCollectionGroupQuery, ); } @@ -396,12 +373,7 @@ class MethodChannelQuery extends QueryPlatform { _pigeonParameters, _pointer.path, pigeonApp, - [ - AggregateQuery( - type: AggregateType.average, - field: field, - ) - ], + [AggregateQuery(type: AggregateType.average, field: field)], isCollectionGroupQuery, ); } @@ -418,10 +390,10 @@ class MethodChannelQuery extends QueryPlatform { @override int get hashCode => Object.hash( - runtimeType, - firestore, - _pointer, - isCollectionGroupQuery, - const DeepCollectionEquality().hash(parameters), - ); + runtimeType, + firestore, + _pointer, + isCollectionGroupQuery, + const DeepCollectionEquality().hash(parameters), + ); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart index 72c61bd9e0db..06cfbdc1c02c 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart @@ -12,36 +12,35 @@ import 'method_channel_document_change.dart'; class MethodChannelQuerySnapshot extends QuerySnapshotPlatform { /// Creates a [MethodChannelQuerySnapshot] from the given [data] MethodChannelQuerySnapshot( - FirebaseFirestorePlatform firestore, InternalQuerySnapshot data) - : super( - data.documents - .map((document) { - if (document == null) { - return null; - } - return DocumentSnapshotPlatform( - firestore, - document.path, - document.data, - document.metadata, - ); - }) - .nonNulls - .toList(), - data.documentChanges - .map((documentChange) { - if (documentChange == null) { - return null; - } - return MethodChannelDocumentChange( - firestore, - documentChange, - ); - }) - .nonNulls - .toList(), - SnapshotMetadataPlatform( - data.metadata.hasPendingWrites, - data.metadata.isFromCache, - )); + FirebaseFirestorePlatform firestore, + InternalQuerySnapshot data, + ) : super( + data.documents + .map((document) { + if (document == null) { + return null; + } + return DocumentSnapshotPlatform( + firestore, + document.path, + document.data, + document.metadata, + ); + }) + .nonNulls + .toList(), + data.documentChanges + .map((documentChange) { + if (documentChange == null) { + return null; + } + return MethodChannelDocumentChange(firestore, documentChange); + }) + .nonNulls + .toList(), + SnapshotMetadataPlatform( + data.metadata.hasPendingWrites, + data.metadata.isFromCache, + ), + ); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart index a4e75ad3d377..35bbdf4d25e6 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart @@ -24,11 +24,16 @@ class MethodChannelTransaction extends TransactionPlatform { /// Constructor. MethodChannelTransaction( - String transactionId, this.appName, this.pigeonApp, this.databaseId) - : _transactionId = transactionId, - super() { + String transactionId, + this.appName, + this.pigeonApp, + this.databaseId, + ) : _transactionId = transactionId, + super() { _firestore = FirebaseFirestorePlatform.instanceFor( - app: Firebase.app(appName), databaseId: databaseId); + app: Firebase.app(appName), + databaseId: databaseId, + ); } List _commands = []; @@ -44,8 +49,10 @@ class MethodChannelTransaction extends TransactionPlatform { /// Requires all reads to be executed before all writes, otherwise an [AssertionError] will be thrown @override Future get(String documentPath) async { - assert(_commands.isEmpty, - 'Transactions require all reads to be executed before all writes.'); + assert( + _commands.isEmpty, + 'Transactions require all reads to be executed before all writes.', + ); try { final result = await MethodChannelFirebaseFirestore.pigeonChannel .transactionGet(pigeonApp, _transactionId, documentPath); @@ -63,10 +70,12 @@ class MethodChannelTransaction extends TransactionPlatform { @override MethodChannelTransaction delete(String documentPath) { - _commands.add(InternalTransactionCommand( - type: InternalTransactionType.deleteType, - path: documentPath, - )); + _commands.add( + InternalTransactionCommand( + type: InternalTransactionType.deleteType, + path: documentPath, + ), + ); return this; } @@ -76,26 +85,34 @@ class MethodChannelTransaction extends TransactionPlatform { String documentPath, Map data, ) { - _commands.add(InternalTransactionCommand( - type: InternalTransactionType.update, - path: documentPath, - data: data, - )); + _commands.add( + InternalTransactionCommand( + type: InternalTransactionType.update, + path: documentPath, + data: data, + ), + ); return this; } @override - MethodChannelTransaction set(String documentPath, Map data, - [SetOptions? options]) { - _commands.add(InternalTransactionCommand( + MethodChannelTransaction set( + String documentPath, + Map data, [ + SetOptions? options, + ]) { + _commands.add( + InternalTransactionCommand( type: InternalTransactionType.set, path: documentPath, data: data, option: InternalDocumentOption( merge: options?.merge, mergeFields: options?.mergeFields?.map((e) => e.components).toList(), - ))); + ), + ), + ); return this; } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart index efd1de89fe6e..8ce393d98cab 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart @@ -42,8 +42,10 @@ class MethodChannelWriteBatch extends WriteBatchPlatform { } try { - await MethodChannelFirebaseFirestore.pigeonChannel - .writeBatchCommit(pigeonApp, _writes); + await MethodChannelFirebaseFirestore.pigeonChannel.writeBatchCommit( + pigeonApp, + _writes, + ); } catch (e, stack) { convertPlatformException(e, stack); } @@ -52,45 +54,52 @@ class MethodChannelWriteBatch extends WriteBatchPlatform { @override void delete(String documentPath) { _assertNotCommitted(); - _writes.add(InternalTransactionCommand( - path: documentPath, - type: InternalTransactionType.deleteType, - )); + _writes.add( + InternalTransactionCommand( + path: documentPath, + type: InternalTransactionType.deleteType, + ), + ); } @override - void set(String documentPath, Map data, - [SetOptions? options]) { + void set( + String documentPath, + Map data, [ + SetOptions? options, + ]) { _assertNotCommitted(); - _writes.add(InternalTransactionCommand( - path: documentPath, - type: InternalTransactionType.set, - data: data, - option: InternalDocumentOption( - merge: options?.merge, - mergeFields: options?.mergeFields?.map((e) => e.components).toList(), + _writes.add( + InternalTransactionCommand( + path: documentPath, + type: InternalTransactionType.set, + data: data, + option: InternalDocumentOption( + merge: options?.merge, + mergeFields: options?.mergeFields?.map((e) => e.components).toList(), + ), ), - )); + ); } @override - void update( - String documentPath, - Map data, - ) { + void update(String documentPath, Map data) { _assertNotCommitted(); - _writes.add(InternalTransactionCommand( - path: documentPath, - type: InternalTransactionType.update, - data: data, - )); + _writes.add( + InternalTransactionCommand( + path: documentPath, + type: InternalTransactionType.update, + data: data, + ), + ); } /// Ensures that once a batch has been committed, it can not be modified again. void _assertNotCommitted() { if (_committed) { throw StateError( - 'This batch has already been committed and can no longer be changed.'); + 'This batch has already been committed and can no longer be changed.', + ); } } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart index 5644e75333df..86e472db2dc1 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart @@ -47,13 +47,13 @@ class FirestoreMessageCodec extends StandardMessageCodec { static const Map _kFieldValueCodes = { - FieldValueType.arrayUnion: _kArrayUnion, - FieldValueType.arrayRemove: _kArrayRemove, - FieldValueType.delete: _kDelete, - FieldValueType.serverTimestamp: _kServerTimestamp, - FieldValueType.incrementDouble: _kIncrementDouble, - FieldValueType.incrementInteger: _kIncrementInteger, - }; + FieldValueType.arrayUnion: _kArrayUnion, + FieldValueType.arrayRemove: _kArrayRemove, + FieldValueType.delete: _kDelete, + FieldValueType.serverTimestamp: _kServerTimestamp, + FieldValueType.incrementDouble: _kIncrementDouble, + FieldValueType.incrementInteger: _kIncrementInteger, + }; static const Map _kFieldPathCodes = { FieldPathType.documentId: _kDocumentId, @@ -152,7 +152,9 @@ class FirestoreMessageCodec extends StandardMessageCodec { final FirebaseApp app = Firebase.app(appName); final FirebaseFirestorePlatform firestore = FirebaseFirestorePlatform.instanceFor( - app: app, databaseId: databaseId); + app: app, + databaseId: databaseId, + ); return firestore.doc(path); case _kVectorValue: final List vector = (readValue(buffer)!) as List; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/source.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/source.dart index 027c74cfd36c..9df21cf6c72e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/source.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/source.dart @@ -9,7 +9,7 @@ String getSourceString(Source source) { return switch (source) { Source.server => 'server', Source.cache => 'cache', - _ => 'default' + _ => 'default', }; } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/persistence_settings.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/persistence_settings.dart index 4cb38b126776..c7e3c80a8bf0 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/persistence_settings.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/persistence_settings.dart @@ -14,7 +14,5 @@ class PersistenceSettings { final bool synchronizeTabs; /// Creates a [PersistenceSettings] instance. - const PersistenceSettings({ - required this.synchronizeTabs, - }); + const PersistenceSettings({required this.synchronizeTabs}); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/pigeon/messages.pigeon.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/pigeon/messages.pigeon.dart index 352fbf28fbed..45440ef3dba4 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/pigeon/messages.pigeon.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/pigeon/messages.pigeon.dart @@ -38,8 +38,11 @@ Object? _extractReplyValueOrThrow( return replyList.firstOrNull; } -List wrapResponse( - {Object? result, PlatformException? error, bool empty = false}) { +List wrapResponse({ + Object? result, + PlatformException? error, + bool empty = false, +}) { if (empty) { return []; } @@ -61,8 +64,9 @@ bool _deepEquals(Object? a, Object? b) { } if (a is List && b is List) { return a.length == b.length && - a.indexed - .every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1])); + a.indexed.every( + ((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]), + ); } if (a is Map && b is Map) { if (a.length != b.length) { @@ -185,23 +189,11 @@ enum PersistenceCacheIndexManagerRequest { deleteAllIndexes, } -enum InternalTransactionResult { - success, - failure, -} +enum InternalTransactionResult { success, failure } -enum InternalTransactionType { - get, - update, - set, - deleteType, -} +enum InternalTransactionType { get, update, set, deleteType } -enum AggregateType { - count, - sum, - average, -} +enum AggregateType { count, sum, average } class InternalFirebaseSettings { InternalFirebaseSettings({ @@ -283,11 +275,7 @@ class FirestorePigeonFirebaseApp { String databaseURL; List _toList() { - return [ - appName, - settings, - databaseURL, - ]; + return [appName, settings, databaseURL]; } Object encode() { @@ -334,10 +322,7 @@ class InternalSnapshotMetadata { bool isFromCache; List _toList() { - return [ - hasPendingWrites, - isFromCache, - ]; + return [hasPendingWrites, isFromCache]; } Object encode() { @@ -385,11 +370,7 @@ class InternalDocumentSnapshot { InternalSnapshotMetadata metadata; List _toList() { - return [ - path, - data, - metadata, - ]; + return [path, data, metadata]; } Object encode() { @@ -442,12 +423,7 @@ class InternalDocumentChange { int newIndex; List _toList() { - return [ - type, - document, - oldIndex, - newIndex, - ]; + return [type, document, oldIndex, newIndex]; } Object encode() { @@ -498,11 +474,7 @@ class InternalQuerySnapshot { InternalSnapshotMetadata metadata; List _toList() { - return [ - documents, - documentChanges, - metadata, - ]; + return [documents, documentChanges, metadata]; } Object encode() { @@ -512,10 +484,10 @@ class InternalQuerySnapshot { static InternalQuerySnapshot decode(Object result) { result as List; return InternalQuerySnapshot( - documents: - (result[0]! as List).cast(), - documentChanges: - (result[1]! as List).cast(), + documents: (result[0]! as List) + .cast(), + documentChanges: (result[1]! as List) + .cast(), metadata: result[2]! as InternalSnapshotMetadata, ); } @@ -557,12 +529,7 @@ class InternalPipelineResult { Map? data; List _toList() { - return [ - documentPath, - createTime, - updateTime, - data, - ]; + return [documentPath, createTime, updateTime, data]; } Object encode() { @@ -610,10 +577,7 @@ class InternalPipelineSnapshot { int executionTime; List _toList() { - return [ - results, - executionTime, - ]; + return [results, executionTime]; } Object encode() { @@ -658,10 +622,7 @@ class InternalGetOptions { ServerTimestampBehavior serverTimestampBehavior; List _toList() { - return [ - source, - serverTimestampBehavior, - ]; + return [source, serverTimestampBehavior]; } Object encode() { @@ -695,20 +656,14 @@ class InternalGetOptions { } class InternalDocumentOption { - InternalDocumentOption({ - this.merge, - this.mergeFields, - }); + InternalDocumentOption({this.merge, this.mergeFields}); bool? merge; List?>? mergeFields; List _toList() { - return [ - merge, - mergeFields, - ]; + return [merge, mergeFields]; } Object encode() { @@ -758,12 +713,7 @@ class InternalTransactionCommand { InternalDocumentOption? option; List _toList() { - return [ - type, - path, - data, - option, - ]; + return [type, path, data, option]; } Object encode() { @@ -821,13 +771,7 @@ class DocumentReferenceRequest { ServerTimestampBehavior? serverTimestampBehavior; List _toList() { - return [ - path, - data, - option, - source, - serverTimestampBehavior, - ]; + return [path, data, option, source, serverTimestampBehavior]; } Object encode() { @@ -957,20 +901,14 @@ class InternalQueryParameters { } class AggregateQuery { - AggregateQuery({ - required this.type, - this.field, - }); + AggregateQuery({required this.type, this.field}); AggregateType type; String? field; List _toList() { - return [ - type, - field, - ]; + return [type, field]; } Object encode() { @@ -1003,11 +941,7 @@ class AggregateQuery { } class AggregateQueryResponse { - AggregateQueryResponse({ - required this.type, - this.field, - this.value, - }); + AggregateQueryResponse({required this.type, this.field, this.value}); AggregateType type; @@ -1016,11 +950,7 @@ class AggregateQueryResponse { double? value; List _toList() { - return [ - type, - field, - value, - ]; + return [type, field, value]; } Object encode() { @@ -1211,11 +1141,13 @@ class FirebaseFirestoreHostApi { /// Constructor for [FirebaseFirestoreHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - FirebaseFirestoreHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + FirebaseFirestoreHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = PigeonCodec(); @@ -1223,7 +1155,9 @@ class FirebaseFirestoreHostApi { final String pigeonVar_messageChannelSuffix; Future loadBundle( - FirestorePigeonFirebaseApp app, Uint8List bundle) async { + FirestorePigeonFirebaseApp app, + Uint8List bundle, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.loadBundle$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1231,8 +1165,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, bundle]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, bundle], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1243,8 +1178,11 @@ class FirebaseFirestoreHostApi { return pigeonVar_replyValue! as String; } - Future namedQueryGet(FirestorePigeonFirebaseApp app, - String name, InternalGetOptions options) async { + Future namedQueryGet( + FirestorePigeonFirebaseApp app, + String name, + InternalGetOptions options, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.namedQueryGet$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1252,8 +1190,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, name, options]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, name, options], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1272,8 +1211,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1291,8 +1231,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1310,8 +1251,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1329,8 +1271,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1348,8 +1291,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1360,7 +1304,9 @@ class FirebaseFirestoreHostApi { } Future setIndexConfiguration( - FirestorePigeonFirebaseApp app, String indexConfiguration) async { + FirestorePigeonFirebaseApp app, + String indexConfiguration, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.setIndexConfiguration$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1368,8 +1314,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, indexConfiguration]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, indexConfiguration], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1387,8 +1334,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([loggingEnabled]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [loggingEnabled], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1406,8 +1354,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1419,7 +1368,10 @@ class FirebaseFirestoreHostApi { } Future transactionCreate( - FirestorePigeonFirebaseApp app, int timeout, int maxAttempts) async { + FirestorePigeonFirebaseApp app, + int timeout, + int maxAttempts, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.transactionCreate$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1427,8 +1379,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, timeout, maxAttempts]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, timeout, maxAttempts], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1440,9 +1393,10 @@ class FirebaseFirestoreHostApi { } Future transactionStoreResult( - String transactionId, - InternalTransactionResult resultType, - List? commands) async { + String transactionId, + InternalTransactionResult resultType, + List? commands, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.transactionStoreResult$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1450,8 +1404,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([transactionId, resultType, commands]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [transactionId, resultType, commands], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1462,7 +1417,10 @@ class FirebaseFirestoreHostApi { } Future transactionGet( - FirestorePigeonFirebaseApp app, String transactionId, String path) async { + FirestorePigeonFirebaseApp app, + String transactionId, + String path, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.transactionGet$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1470,8 +1428,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, transactionId, path]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, transactionId, path], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1483,7 +1442,9 @@ class FirebaseFirestoreHostApi { } Future documentReferenceSet( - FirestorePigeonFirebaseApp app, DocumentReferenceRequest request) async { + FirestorePigeonFirebaseApp app, + DocumentReferenceRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.documentReferenceSet$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1491,8 +1452,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1503,7 +1465,9 @@ class FirebaseFirestoreHostApi { } Future documentReferenceUpdate( - FirestorePigeonFirebaseApp app, DocumentReferenceRequest request) async { + FirestorePigeonFirebaseApp app, + DocumentReferenceRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.documentReferenceUpdate$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1511,8 +1475,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1523,7 +1488,9 @@ class FirebaseFirestoreHostApi { } Future documentReferenceGet( - FirestorePigeonFirebaseApp app, DocumentReferenceRequest request) async { + FirestorePigeonFirebaseApp app, + DocumentReferenceRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.documentReferenceGet$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1531,8 +1498,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1544,7 +1512,9 @@ class FirebaseFirestoreHostApi { } Future documentReferenceDelete( - FirestorePigeonFirebaseApp app, DocumentReferenceRequest request) async { + FirestorePigeonFirebaseApp app, + DocumentReferenceRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.documentReferenceDelete$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1552,8 +1522,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1564,11 +1535,12 @@ class FirebaseFirestoreHostApi { } Future queryGet( - FirestorePigeonFirebaseApp app, - String path, - bool isCollectionGroup, - InternalQueryParameters parameters, - InternalGetOptions options) async { + FirestorePigeonFirebaseApp app, + String path, + bool isCollectionGroup, + InternalQueryParameters parameters, + InternalGetOptions options, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.queryGet$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1576,8 +1548,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel - .send([app, path, isCollectionGroup, parameters, options]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, path, isCollectionGroup, parameters, options], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1589,12 +1562,13 @@ class FirebaseFirestoreHostApi { } Future> aggregateQuery( - FirestorePigeonFirebaseApp app, - String path, - InternalQueryParameters parameters, - AggregateSource source, - List queries, - bool isCollectionGroup) async { + FirestorePigeonFirebaseApp app, + String path, + InternalQueryParameters parameters, + AggregateSource source, + List queries, + bool isCollectionGroup, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.aggregateQuery$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1603,7 +1577,8 @@ class FirebaseFirestoreHostApi { binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [app, path, parameters, source, queries, isCollectionGroup]); + [app, path, parameters, source, queries, isCollectionGroup], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1615,8 +1590,10 @@ class FirebaseFirestoreHostApi { .cast(); } - Future writeBatchCommit(FirestorePigeonFirebaseApp app, - List writes) async { + Future writeBatchCommit( + FirestorePigeonFirebaseApp app, + List writes, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.writeBatchCommit$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1624,8 +1601,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, writes]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, writes], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1636,13 +1614,14 @@ class FirebaseFirestoreHostApi { } Future querySnapshot( - FirestorePigeonFirebaseApp app, - String path, - bool isCollectionGroup, - InternalQueryParameters parameters, - InternalGetOptions options, - bool includeMetadataChanges, - ListenSource source) async { + FirestorePigeonFirebaseApp app, + String path, + bool isCollectionGroup, + InternalQueryParameters parameters, + InternalGetOptions options, + bool includeMetadataChanges, + ListenSource source, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.querySnapshot$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1650,16 +1629,16 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([ - app, - path, - isCollectionGroup, - parameters, - options, - includeMetadataChanges, - source - ]); + final Future pigeonVar_sendFuture = pigeonVar_channel + .send([ + app, + path, + isCollectionGroup, + parameters, + options, + includeMetadataChanges, + source, + ]); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1671,10 +1650,11 @@ class FirebaseFirestoreHostApi { } Future documentReferenceSnapshot( - FirestorePigeonFirebaseApp app, - DocumentReferenceRequest parameters, - bool includeMetadataChanges, - ListenSource source) async { + FirestorePigeonFirebaseApp app, + DocumentReferenceRequest parameters, + bool includeMetadataChanges, + ListenSource source, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.documentReferenceSnapshot$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1682,8 +1662,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel - .send([app, parameters, includeMetadataChanges, source]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, parameters, includeMetadataChanges, source], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1695,8 +1676,9 @@ class FirebaseFirestoreHostApi { } Future persistenceCacheIndexManagerRequest( - FirestorePigeonFirebaseApp app, - PersistenceCacheIndexManagerRequest request) async { + FirestorePigeonFirebaseApp app, + PersistenceCacheIndexManagerRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.persistenceCacheIndexManagerRequest$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1704,8 +1686,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1716,9 +1699,10 @@ class FirebaseFirestoreHostApi { } Future executePipeline( - FirestorePigeonFirebaseApp app, - List?> stages, - Map? options) async { + FirestorePigeonFirebaseApp app, + List?> stages, + Map? options, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.executePipeline$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1726,8 +1710,9 @@ class FirebaseFirestoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, stages, options]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, stages, options], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_aggregate_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_aggregate_query.dart index b42e55710666..084cc23aa689 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_aggregate_query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_aggregate_query.dart @@ -39,9 +39,7 @@ abstract class AggregateQueryPlatform extends PlatformInterface { } /// Returns an [AggregateQuerySnapshotPlatform] with the sum of the values of the documents that match the query. - AggregateQueryPlatform sum( - String field, - ) { + AggregateQueryPlatform sum(String field) { throw UnimplementedError('sum() is not implemented'); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_aggregate_query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_aggregate_query_snapshot.dart index 7d4f938773e3..aaa4564bc41d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_aggregate_query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_aggregate_query_snapshot.dart @@ -12,10 +12,10 @@ class AggregateQuerySnapshotPlatform extends PlatformInterface { required int? count, required List sum, required List average, - }) : _count = count, - _sum = sum, - _average = average, - super(token: _token); + }) : _count = count, + _sum = sum, + _average = average, + super(token: _token); static final Object _token = Object(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_collection_reference.dart index 33912dcd5ca9..f117a62c5687 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_collection_reference.dart @@ -14,11 +14,9 @@ abstract class CollectionReferencePlatform extends QueryPlatform { final Pointer _pointer; /// Create a [CollectionReferencePlatform] from a [path] - CollectionReferencePlatform( - FirebaseFirestorePlatform firestore, - String path, - ) : _pointer = Pointer(path), - super(firestore, {}); + CollectionReferencePlatform(FirebaseFirestorePlatform firestore, String path) + : _pointer = Pointer(path), + super(firestore, {}); /// Identifier of the referenced collection. String get id => _pointer.id; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_document_change.dart index 635eca3568ce..f10fbfec66e6 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_document_change.dart @@ -12,12 +12,8 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; /// (added, modified, or removed). class DocumentChangePlatform extends PlatformInterface { /// Create a [DocumentChangePlatform] - DocumentChangePlatform( - this.type, - this.oldIndex, - this.newIndex, - this.document, - ) : super(token: _token); + DocumentChangePlatform(this.type, this.oldIndex, this.newIndex, this.document) + : super(token: _token); static final Object _token = Object(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_document_reference.dart index 88e356702249..c09898910691 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_document_reference.dart @@ -17,11 +17,9 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; /// [CollectionReferencePlatform] to a subcollection. abstract class DocumentReferencePlatform extends PlatformInterface { /// Create instance of [DocumentReferencePlatform] - DocumentReferencePlatform( - this.firestore, - String path, - ) : _pointer = Pointer(path), - super(token: _token); + DocumentReferencePlatform(this.firestore, String path) + : _pointer = Pointer(path), + super(token: _token); static final Object _token = Object(); @@ -65,8 +63,9 @@ abstract class DocumentReferencePlatform extends PlatformInterface { /// Reads the document referenced by this [DocumentReferencePlatform]. /// /// If no document exists, the read will return null. - Future get( - [GetOptions options = const GetOptions()]) async { + Future get([ + GetOptions options = const GetOptions(), + ]) async { throw UnimplementedError('get() is not implemented'); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_document_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_document_snapshot.dart index 3fce79a77f10..21b6aba330d6 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_document_snapshot.dart @@ -15,9 +15,12 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; class DocumentSnapshotPlatform extends PlatformInterface { /// Constructs a [DocumentSnapshotPlatform] using the provided [FirebaseFirestorePlatform]. DocumentSnapshotPlatform( - this._firestore, String path, this._data, this._metadata) - : _pointer = Pointer(path), - super(token: _token); + this._firestore, + String path, + this._data, + this._metadata, + ) : _pointer = Pointer(path), + super(token: _token); static final Object _token = Object(); @@ -115,7 +118,9 @@ class DocumentSnapshotPlatform extends PlatformInterface { if (value is Map) { return _findComponent( - componentIndex + 1, Map.from(value)); + componentIndex + 1, + Map.from(value), + ); } else { throw StateError( 'field "$value" does not exist within the $DocumentSnapshotPlatform', diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_firestore.dart index ee9cd3a32478..25262951f05d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_firestore.dart @@ -20,7 +20,7 @@ abstract class FirebaseFirestorePlatform extends PlatformInterface { /// Create an instance using [app] FirebaseFirestorePlatform({this.appInstance, this.databaseChoice}) - : super(token: _token); + : super(token: _token); /// Returns the [FirebaseApp] for the current instance. FirebaseApp get app { @@ -41,8 +41,10 @@ abstract class FirebaseFirestorePlatform extends PlatformInterface { required FirebaseApp app, required String databaseId, }) { - return FirebaseFirestorePlatform.instance - .delegateFor(app: app, databaseId: databaseId); + return FirebaseFirestorePlatform.instance.delegateFor( + app: app, + databaseId: databaseId, + ); } /// The current default [FirebaseFirestorePlatform] instance. @@ -51,7 +53,9 @@ abstract class FirebaseFirestorePlatform extends PlatformInterface { /// if no other implementation was provided. static FirebaseFirestorePlatform get instance { return _instance ??= MethodChannelFirebaseFirestore( - app: Firebase.app(), databaseId: '(default)'); + app: Firebase.app(), + databaseId: '(default)', + ); } static FirebaseFirestorePlatform? _instance; @@ -65,8 +69,10 @@ abstract class FirebaseFirestorePlatform extends PlatformInterface { /// Enables delegates to create new instances of themselves if a none default /// [FirebaseApp] instance is required by the user. @protected - FirebaseFirestorePlatform delegateFor( - {required FirebaseApp app, required String databaseId}) { + FirebaseFirestorePlatform delegateFor({ + required FirebaseApp app, + required String databaseId, + }) { throw UnimplementedError('delegateFor() is not implemented'); } @@ -172,8 +178,11 @@ abstract class FirebaseFirestorePlatform extends PlatformInterface { /// /// By default transactions will retry 5 times. You can change the number of attempts /// with [maxAttempts]. Attempts should be at least 1. - Future runTransaction(TransactionHandler transactionHandler, - {Duration timeout = const Duration(seconds: 30), int maxAttempts = 5}) { + Future runTransaction( + TransactionHandler transactionHandler, { + Duration timeout = const Duration(seconds: 30), + int maxAttempts = 5, + }) { throw UnimplementedError('runTransaction() is not implemented'); } @@ -235,7 +244,8 @@ abstract class FirebaseFirestorePlatform extends PlatformInterface { /// Gets the PersistentCacheIndexManager instance used by this firestore instance. PersistentCacheIndexManagerPlatform? persistentCacheIndexManager() { throw UnimplementedError( - 'persistentCacheIndexManager() is not implemented'); + 'persistentCacheIndexManager() is not implemented', + ); } /// Globally enables / disables Cloud Firestore logging for the SDK. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_index_definitions.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_index_definitions.dart index ed79f6dda7ca..74376579997f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_index_definitions.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_index_definitions.dart @@ -58,8 +58,9 @@ class FieldOverrides { return { 'collectionGroup': collectionGroup, 'fieldPath': fieldPath, - 'indexes': - indexes.map((FieldOverrideIndex index) => index.toMap()).toList(), + 'indexes': indexes + .map((FieldOverrideIndex index) => index.toMap()) + .toList(), }; } } @@ -81,16 +82,8 @@ class FieldOverrideIndex { } } -enum Order { - ascending, - descending, -} +enum Order { ascending, descending } -enum ArrayConfig { - contains, -} +enum ArrayConfig { contains } -enum QueryScope { - collection, - collectionGroup, -} +enum QueryScope { collection, collectionGroup } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_load_bundle_task_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_load_bundle_task_snapshot.dart index 65c36143cb00..177d1f4ae8bf 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_load_bundle_task_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_load_bundle_task_snapshot.dart @@ -11,11 +11,11 @@ import '../../cloud_firestore_platform_interface.dart'; class LoadBundleTaskSnapshotPlatform extends PlatformInterface { // ignore: public_member_api_docs LoadBundleTaskSnapshotPlatform(this.taskState, Map data) - : bytesLoaded = data['bytesLoaded'], - documentsLoaded = data['documentsLoaded'], - totalBytes = data['totalBytes'], - totalDocuments = data['totalDocuments'], - super(token: _token); + : bytesLoaded = data['bytesLoaded'], + documentsLoaded = data['documentsLoaded'], + totalBytes = data['totalBytes'], + totalDocuments = data['totalDocuments'], + super(token: _token); static final Object _token = Object(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_pipeline.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_pipeline.dart index 2d0449ee4aef..8d89b1211ea6 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_pipeline.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_pipeline.dart @@ -14,8 +14,8 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; abstract class PipelinePlatform extends PlatformInterface { /// Create a [PipelinePlatform] instance PipelinePlatform(this.firestore, List>? stages) - : _stages = stages ?? [], - super(token: _token); + : _stages = stages ?? [], + super(token: _token); static final Object _token = Object(); @@ -48,7 +48,5 @@ abstract class PipelinePlatform extends PlatformInterface { PipelinePlatform addStage(Map serializedStage); /// Executes the pipeline and returns a snapshot of the results - Future execute({ - Map? options, - }); + Future execute({Map? options}); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_query.dart index 722cd590dd62..8c8028a3e8b9 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_query.dart @@ -25,8 +25,8 @@ Map _initialParameters = Map.unmodifiable({ abstract class QueryPlatform extends PlatformInterface { /// Create a [QueryPlatform] instance QueryPlatform(this.firestore, Map? params) - : parameters = params ?? _initialParameters, - super(token: _token); + : parameters = params ?? _initialParameters, + super(token: _token); static final Object _token = Object(); @@ -96,7 +96,9 @@ abstract class QueryPlatform extends PlatformInterface { /// * [startAtDocument] for a query that starts at a document. /// * [endAtDocument] for a query that ends at a document. QueryPlatform endBeforeDocument( - Iterable orders, Iterable values) { + Iterable orders, + Iterable values, + ) { throw UnimplementedError('endBeforeDocument() is not implemented'); } @@ -199,7 +201,9 @@ abstract class QueryPlatform extends PlatformInterface { /// * [endAtDocument] for a query that ends at a document. /// * [endBeforeDocument] for a query that ends before a document. QueryPlatform startAtDocument( - Iterable orders, Iterable values) { + Iterable orders, + Iterable values, + ) { throw UnimplementedError('startAtDocument() is not implemented'); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_query_snapshot.dart index e735fea6959c..7197df4de06b 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_query_snapshot.dart @@ -13,11 +13,8 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; /// can be determined by calling [size()]. class QuerySnapshotPlatform extends PlatformInterface { /// Create a [QuerySnapshotPlatform] - QuerySnapshotPlatform( - this.docs, - this.docChanges, - this.metadata, - ) : super(token: _token); + QuerySnapshotPlatform(this.docs, this.docChanges, this.metadata) + : super(token: _token); static final Object _token = Object(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_transaction.dart index 64ae9fef837e..55e42462f662 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_transaction.dart @@ -10,8 +10,8 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; /// The [TransactionHandler] may be executed multiple times, it should be able /// to handle multiple executions. -typedef TransactionHandler = Future? Function( - TransactionPlatform); +typedef TransactionHandler = + Future? Function(TransactionPlatform); /// A [TransactionPlatform] is a set of read and write operations on one or more documents. abstract class TransactionPlatform extends PlatformInterface { @@ -60,8 +60,11 @@ abstract class TransactionPlatform extends PlatformInterface { /// Writes to the document referred to by the provided [documentPath]. /// 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. - TransactionPlatform set(String documentPath, Map data, - [SetOptions? options]) { + TransactionPlatform set( + String documentPath, + Map data, [ + SetOptions? options, + ]) { throw UnimplementedError('set() is not implemented'); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_write_batch.dart index 5dcb32db73cd..e13697d2e518 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_write_batch.dart @@ -49,18 +49,18 @@ abstract class WriteBatchPlatform extends PlatformInterface { /// /// If [SetOptions] are provided, the [data] will be merged into an existing /// document instead of overwriting. - void set(String documentPath, Map data, - [SetOptions? options]) { + void set( + String documentPath, + Map data, [ + SetOptions? options, + ]) { throw UnimplementedError('set() is not implemented'); } /// Updates fields in the document referred to by [document]. /// /// If the document does not exist, the operation will fail. - void update( - String documentPath, - Map data, - ) { + void update(String documentPath, Map data) { throw UnimplementedError('update() is not implemented'); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/utils/load_bundle_task_state.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/utils/load_bundle_task_state.dart index 909b4aec5e82..63da17bac2bc 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/utils/load_bundle_task_state.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/utils/load_bundle_task_state.dart @@ -10,6 +10,6 @@ LoadBundleTaskState convertToTaskState(String state) { 'running' => LoadBundleTaskState.running, 'success' => LoadBundleTaskState.success, 'error' => LoadBundleTaskState.error, - _ => throw UnsupportedError('Unknown LoadBundleTaskState value: $state.') + _ => throw UnsupportedError('Unknown LoadBundleTaskState value: $state.'), }; } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/set_options.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/set_options.dart index 8cda722b90e7..f9bfdd6adcde 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/set_options.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/set_options.dart @@ -9,22 +9,22 @@ import 'field_path.dart'; /// [WriteBatch] and [Transaction]. class SetOptions { /// Creates a [SetOptions] instance. - SetOptions({ - this.merge, - List? mergeFields, - }) : assert( - (merge != null) ^ (mergeFields != null), - "options must provide either 'merge' or 'mergeFields'", - ), - mergeFields = mergeFields?.map((field) { - assert( - field is String || field is FieldPath, - '[mergeFields] can only contain Strings or FieldPaths but got $field', - ); + SetOptions({this.merge, List? mergeFields}) + : assert( + (merge != null) ^ (mergeFields != null), + "options must provide either 'merge' or 'mergeFields'", + ), + mergeFields = mergeFields + ?.map((field) { + assert( + field is String || field is FieldPath, + '[mergeFields] can only contain Strings or FieldPaths but got $field', + ); - if (field is String) return FieldPath.fromString(field); - return field as FieldPath; - }).toList(growable: false); + if (field is String) return FieldPath.fromString(field); + return field as FieldPath; + }) + .toList(growable: false); /// Changes the behavior of a set() call to only replace the values specified /// in its data argument. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/settings.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/settings.dart index 570a9d48d170..dace3437b3d9 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/settings.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/settings.dart @@ -120,23 +120,26 @@ class Settings { WebPersistentTabManager? webPersistentTabManager, }) { assert( - cacheSizeBytes == null || - cacheSizeBytes == CACHE_SIZE_UNLIMITED || - // 1mb and 100mb. minimum and maximum inclusive range. - (cacheSizeBytes >= 1048576 && cacheSizeBytes <= 104857600), - 'Cache size must be between 1048576 bytes (inclusive) and 104857600 bytes (inclusive)'); + cacheSizeBytes == null || + cacheSizeBytes == CACHE_SIZE_UNLIMITED || + // 1mb and 100mb. minimum and maximum inclusive range. + (cacheSizeBytes >= 1048576 && cacheSizeBytes <= 104857600), + 'Cache size must be between 1048576 bytes (inclusive) and 104857600 bytes (inclusive)', + ); return Settings( persistenceEnabled: persistenceEnabled ?? this.persistenceEnabled, host: host ?? this.host, sslEnabled: sslEnabled ?? this.sslEnabled, cacheSizeBytes: cacheSizeBytes ?? this.cacheSizeBytes, - webExperimentalForceLongPolling: webExperimentalForceLongPolling ?? + webExperimentalForceLongPolling: + webExperimentalForceLongPolling ?? this.webExperimentalForceLongPolling, webExperimentalAutoDetectLongPolling: webExperimentalAutoDetectLongPolling ?? - this.webExperimentalAutoDetectLongPolling, - webExperimentalLongPollingOptions: webExperimentalLongPollingOptions ?? + this.webExperimentalAutoDetectLongPolling, + webExperimentalLongPollingOptions: + webExperimentalLongPollingOptions ?? this.webExperimentalLongPollingOptions, ignoreUndefinedProperties: ignoreUndefinedProperties ?? this.ignoreUndefinedProperties, @@ -164,17 +167,17 @@ class Settings { @override int get hashCode => Object.hash( - runtimeType, - persistenceEnabled, - host, - sslEnabled, - cacheSizeBytes, - webExperimentalForceLongPolling, - webExperimentalAutoDetectLongPolling, - webExperimentalLongPollingOptions, - ignoreUndefinedProperties, - webPersistentTabManager, - ); + runtimeType, + persistenceEnabled, + host, + sslEnabled, + cacheSizeBytes, + webExperimentalForceLongPolling, + webExperimentalAutoDetectLongPolling, + webExperimentalLongPollingOptions, + ignoreUndefinedProperties, + webPersistentTabManager, + ); @override String toString() => 'Settings($asMap)'; @@ -267,14 +270,10 @@ class WebExperimentalLongPollingOptions { /// such as 25 seconds, may fix prematurely-closed hanging GET requests. final Duration? timeoutDuration; - const WebExperimentalLongPollingOptions({ - this.timeoutDuration, - }); + const WebExperimentalLongPollingOptions({this.timeoutDuration}); Map get asMap { - return { - 'timeoutDuration': timeoutDuration?.inSeconds, - }; + return {'timeoutDuration': timeoutDuration?.inSeconds}; } @override diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/pigeons/messages.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/pigeons/messages.dart index 27a61ef98f0d..3444b3834797 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/pigeons/messages.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/pigeons/messages.dart @@ -200,7 +200,7 @@ enum AggregateSource { enum PersistenceCacheIndexManagerRequest { enableIndexAutoCreation, disableIndexAutoCreation, - deleteAllIndexes + deleteAllIndexes, } class InternalGetOptions { @@ -213,10 +213,7 @@ class InternalGetOptions { final ServerTimestampBehavior serverTimestampBehavior; } -enum InternalTransactionResult { - success, - failure, -} +enum InternalTransactionResult { success, failure } enum InternalTransactionType { get, @@ -289,17 +286,10 @@ class InternalQueryParameters { final Map? filters; } -enum AggregateType { - count, - sum, - average, -} +enum AggregateType { count, sum, average } class AggregateQuery { - const AggregateQuery({ - required this.type, - required this.field, - }); + const AggregateQuery({required this.type, required this.field}); final AggregateType type; final String? field; @@ -320,10 +310,7 @@ class AggregateQueryResponse { @HostApi(dartHostTestHandler: 'TestFirebaseFirestoreHostApi') abstract class FirebaseFirestoreHostApi { @async - String loadBundle( - FirestorePigeonFirebaseApp app, - Uint8List bundle, - ); + String loadBundle(FirestorePigeonFirebaseApp app, Uint8List bundle); @async InternalQuerySnapshot namedQueryGet( @@ -333,29 +320,19 @@ abstract class FirebaseFirestoreHostApi { ); @async - void clearPersistence( - FirestorePigeonFirebaseApp app, - ); + void clearPersistence(FirestorePigeonFirebaseApp app); @async - void disableNetwork( - FirestorePigeonFirebaseApp app, - ); + void disableNetwork(FirestorePigeonFirebaseApp app); @async - void enableNetwork( - FirestorePigeonFirebaseApp app, - ); + void enableNetwork(FirestorePigeonFirebaseApp app); @async - void terminate( - FirestorePigeonFirebaseApp app, - ); + void terminate(FirestorePigeonFirebaseApp app); @async - void waitForPendingWrites( - FirestorePigeonFirebaseApp app, - ); + void waitForPendingWrites(FirestorePigeonFirebaseApp app); @async void setIndexConfiguration( @@ -364,14 +341,10 @@ abstract class FirebaseFirestoreHostApi { ); @async - void setLoggingEnabled( - bool loggingEnabled, - ); + void setLoggingEnabled(bool loggingEnabled); @async - String snapshotsInSyncSetup( - FirestorePigeonFirebaseApp app, - ); + String snapshotsInSyncSetup(FirestorePigeonFirebaseApp app); @async String transactionCreate( diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml b/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml index 3b2213380349..935b60d7be9b 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml @@ -6,8 +6,8 @@ homepage: https://github.com/firebase/flutterfire/tree/main/packages/cloud_fires repository: https://github.com/firebase/flutterfire/tree/main/packages/cloud_firestore/cloud_firestore_platform_interface environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_path_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_path_test.dart index 8b384e638a08..4e850c2f6a85 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_path_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_path_test.dart @@ -10,10 +10,14 @@ void main() { group('$FieldPath', () { test('equality', () { expect(FieldPath(const ['foo']), equals(FieldPath(const ['foo']))); - expect(FieldPath(const ['foo', 'bar']), - equals(FieldPath(const ['foo', 'bar']))); - expect(FieldPath(const ['foo', 'bar']), - equals(FieldPath.fromString('foo.bar'))); + expect( + FieldPath(const ['foo', 'bar']), + equals(FieldPath(const ['foo', 'bar'])), + ); + expect( + FieldPath(const ['foo', 'bar']), + equals(FieldPath.fromString('foo.bar')), + ); }); test('throws is invalid path is provided', () { @@ -23,9 +27,13 @@ void main() { test('returns a [List] of components', () { expect(FieldPath(const ['foo']).components, equals(const ['foo'])); expect( - FieldPath(const ['foo.bar']).components, equals(const ['foo.bar'])); - expect(FieldPath(const ['foo.bar', 'baz']).components, - equals(const ['foo.bar', 'baz'])); + FieldPath(const ['foo.bar']).components, + equals(const ['foo.bar']), + ); + expect( + FieldPath(const ['foo.bar', 'baz']).components, + equals(const ['foo.bar', 'baz']), + ); }); test('returns a [FieldPathType] for a documentId', () { @@ -48,8 +56,10 @@ void main() { test('creates a [FieldPath]', () { expect(FieldPath.fromString('foo.bar.baz'), isA()); - expect(FieldPath.fromString('foo.bar.baz').components, - equals(['foo', 'bar', 'baz'])); + expect( + FieldPath.fromString('foo.bar.baz').components, + equals(['foo', 'bar', 'baz']), + ); }); }); }); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/internal_tests/pointer_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/internal_tests/pointer_test.dart index 6b3c2bad8ee1..dc53488d987c 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/internal_tests/pointer_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/internal_tests/pointer_test.dart @@ -37,7 +37,9 @@ void main() { test('documentPath() fails if path is already a document', () { expect( - () => Pointer('foo/bar').documentPath('bar'), throwsAssertionError); + () => Pointer('foo/bar').documentPath('bar'), + throwsAssertionError, + ); }); test('collectionPath() returns a valid collection', () { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_firestore_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_firestore_test.dart index 2b58d1d4f8d0..a5ebfbc4053e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_firestore_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_firestore_test.dart @@ -85,54 +85,52 @@ void main() { messenger.setMockMessageHandler(channelName, null); }); - test( - 'does not complete the transaction future twice when native reports an ' - 'error while storing a failure', - () async { - final firestore = MethodChannelFirebaseFirestore( - app: app, - databaseId: '(default)', - ); - - final transactionFuture = firestore.runTransaction( - (_) => throw StateError('handler failed'), - ); - - await eventChannelListened.future; - unawaited( - messenger.handlePlatformMessage( - channelName, - codec.encodeSuccessEnvelope({ - 'appName': 'test-app', - }), - (_) {}, - ), - ); - await hostApi.storeResultCalled.future; - - unawaited( - messenger.handlePlatformMessage( - channelName, - codec.encodeSuccessEnvelope({ - 'error': { - 'code': 'deadline-exceeded', - 'message': 'Transaction timed out', - }, - }), - (_) {}, - ), - ); + test('does not complete the transaction future twice when native reports an ' + 'error while storing a failure', () async { + final firestore = MethodChannelFirebaseFirestore( + app: app, + databaseId: '(default)', + ); - await expectLater( - transactionFuture, - throwsA( - isA() - .having((error) => error.code, 'code', 'deadline-exceeded'), + final transactionFuture = firestore.runTransaction( + (_) => throw StateError('handler failed'), + ); + + await eventChannelListened.future; + unawaited( + messenger.handlePlatformMessage( + channelName, + codec.encodeSuccessEnvelope({'appName': 'test-app'}), + (_) {}, + ), + ); + await hostApi.storeResultCalled.future; + + unawaited( + messenger.handlePlatformMessage( + channelName, + codec.encodeSuccessEnvelope({ + 'error': { + 'code': 'deadline-exceeded', + 'message': 'Transaction timed out', + }, + }), + (_) {}, + ), + ); + + await expectLater( + transactionFuture, + throwsA( + isA().having( + (error) => error.code, + 'code', + 'deadline-exceeded', ), - ); + ), + ); - hostApi.releaseStoreResult.complete(); - await Future.delayed(Duration.zero); - }, - ); + hostApi.releaseStoreResult.complete(); + await Future.delayed(Duration.zero); + }); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/pigeon/test_api.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/pigeon/test_api.dart index 726d510a1f69..3d02a1011ab9 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/pigeon/test_api.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/pigeon/test_api.dart @@ -290,8 +290,9 @@ abstract class TestFirebaseFirestoreHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( 'dev.flutter.pigeon.cloud_firestore_platform_interface.FirebaseFirestoreHostApi.loadBundle$messageChannelSuffix', @@ -303,23 +304,27 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - final Uint8List arg_bundle = args[1]! as Uint8List; - try { - final String output = await api.loadBundle(arg_app, arg_bundle); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + final Uint8List arg_bundle = args[1]! as Uint8List; + try { + final String output = await api.loadBundle(arg_app, arg_bundle); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -333,25 +338,33 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - final String arg_name = args[1]! as String; - final InternalGetOptions arg_options = args[2]! as InternalGetOptions; - try { - final InternalQuerySnapshot output = - await api.namedQueryGet(arg_app, arg_name, arg_options); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + final String arg_name = args[1]! as String; + final InternalGetOptions arg_options = + args[2]! as InternalGetOptions; + try { + final InternalQuerySnapshot output = await api.namedQueryGet( + arg_app, + arg_name, + arg_options, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -365,22 +378,26 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - try { - await api.clearPersistence(arg_app); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + try { + await api.clearPersistence(arg_app); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -394,22 +411,26 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - try { - await api.disableNetwork(arg_app); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + try { + await api.disableNetwork(arg_app); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -423,22 +444,26 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - try { - await api.enableNetwork(arg_app); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + try { + await api.enableNetwork(arg_app); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -452,22 +477,26 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - try { - await api.terminate(arg_app); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + try { + await api.terminate(arg_app); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -481,22 +510,26 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - try { - await api.waitForPendingWrites(arg_app); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + try { + await api.waitForPendingWrites(arg_app); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -510,23 +543,30 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - final String arg_indexConfiguration = args[1]! as String; - try { - await api.setIndexConfiguration(arg_app, arg_indexConfiguration); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + final String arg_indexConfiguration = args[1]! as String; + try { + await api.setIndexConfiguration( + arg_app, + arg_indexConfiguration, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -540,21 +580,25 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final bool arg_loggingEnabled = args[0]! as bool; - try { - await api.setLoggingEnabled(arg_loggingEnabled); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final bool arg_loggingEnabled = args[0]! as bool; + try { + await api.setLoggingEnabled(arg_loggingEnabled); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -568,22 +612,26 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - try { - final String output = await api.snapshotsInSyncSetup(arg_app); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + try { + final String output = await api.snapshotsInSyncSetup(arg_app); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -597,28 +645,32 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - final int arg_timeout = args[1]! as int; - final int arg_maxAttempts = args[2]! as int; - try { - final String output = await api.transactionCreate( - arg_app, - arg_timeout, - arg_maxAttempts, - ); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + final int arg_timeout = args[1]! as int; + final int arg_maxAttempts = args[2]! as int; + try { + final String output = await api.transactionCreate( + arg_app, + arg_timeout, + arg_maxAttempts, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -632,29 +684,34 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_transactionId = args[0]! as String; - final InternalTransactionResult arg_resultType = - args[1]! as InternalTransactionResult; - final List? arg_commands = - (args[2] as List?)?.cast(); - try { - await api.transactionStoreResult( - arg_transactionId, - arg_resultType, - arg_commands, - ); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_transactionId = args[0]! as String; + final InternalTransactionResult arg_resultType = + args[1]! as InternalTransactionResult; + final List? arg_commands = + (args[2] as List?) + ?.cast(); + try { + await api.transactionStoreResult( + arg_transactionId, + arg_resultType, + arg_commands, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -668,25 +725,29 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - final String arg_transactionId = args[1]! as String; - final String arg_path = args[2]! as String; - try { - final InternalDocumentSnapshot output = - await api.transactionGet(arg_app, arg_transactionId, arg_path); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + final String arg_transactionId = args[1]! as String; + final String arg_path = args[2]! as String; + try { + final InternalDocumentSnapshot output = await api + .transactionGet(arg_app, arg_transactionId, arg_path); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -700,24 +761,28 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - final DocumentReferenceRequest arg_request = - args[1]! as DocumentReferenceRequest; - try { - await api.documentReferenceSet(arg_app, arg_request); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + final DocumentReferenceRequest arg_request = + args[1]! as DocumentReferenceRequest; + try { + await api.documentReferenceSet(arg_app, arg_request); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -731,24 +796,28 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - final DocumentReferenceRequest arg_request = - args[1]! as DocumentReferenceRequest; - try { - await api.documentReferenceUpdate(arg_app, arg_request); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + final DocumentReferenceRequest arg_request = + args[1]! as DocumentReferenceRequest; + try { + await api.documentReferenceUpdate(arg_app, arg_request); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -762,25 +831,29 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - final DocumentReferenceRequest arg_request = - args[1]! as DocumentReferenceRequest; - try { - final InternalDocumentSnapshot output = - await api.documentReferenceGet(arg_app, arg_request); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + final DocumentReferenceRequest arg_request = + args[1]! as DocumentReferenceRequest; + try { + final InternalDocumentSnapshot output = await api + .documentReferenceGet(arg_app, arg_request); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -794,24 +867,28 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - final DocumentReferenceRequest arg_request = - args[1]! as DocumentReferenceRequest; - try { - await api.documentReferenceDelete(arg_app, arg_request); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + final DocumentReferenceRequest arg_request = + args[1]! as DocumentReferenceRequest; + try { + await api.documentReferenceDelete(arg_app, arg_request); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -825,33 +902,38 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - final String arg_path = args[1]! as String; - final bool arg_isCollectionGroup = args[2]! as bool; - final InternalQueryParameters arg_parameters = - args[3]! as InternalQueryParameters; - final InternalGetOptions arg_options = args[4]! as InternalGetOptions; - try { - final InternalQuerySnapshot output = await api.queryGet( - arg_app, - arg_path, - arg_isCollectionGroup, - arg_parameters, - arg_options, - ); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + final String arg_path = args[1]! as String; + final bool arg_isCollectionGroup = args[2]! as bool; + final InternalQueryParameters arg_parameters = + args[3]! as InternalQueryParameters; + final InternalGetOptions arg_options = + args[4]! as InternalGetOptions; + try { + final InternalQuerySnapshot output = await api.queryGet( + arg_app, + arg_path, + arg_isCollectionGroup, + arg_parameters, + arg_options, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -865,37 +947,41 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - final String arg_path = args[1]! as String; - final InternalQueryParameters arg_parameters = - args[2]! as InternalQueryParameters; - final AggregateSource arg_source = args[3]! as AggregateSource; - final List arg_queries = - (args[4]! as List).cast(); - final bool arg_isCollectionGroup = args[5]! as bool; - try { - final List output = - await api.aggregateQuery( - arg_app, - arg_path, - arg_parameters, - arg_source, - arg_queries, - arg_isCollectionGroup, - ); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + final String arg_path = args[1]! as String; + final InternalQueryParameters arg_parameters = + args[2]! as InternalQueryParameters; + final AggregateSource arg_source = args[3]! as AggregateSource; + final List arg_queries = + (args[4]! as List).cast(); + final bool arg_isCollectionGroup = args[5]! as bool; + try { + final List output = await api + .aggregateQuery( + arg_app, + arg_path, + arg_parameters, + arg_source, + arg_queries, + arg_isCollectionGroup, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -909,24 +995,29 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - final List arg_writes = - (args[1]! as List).cast(); - try { - await api.writeBatchCommit(arg_app, arg_writes); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + final List arg_writes = + (args[1]! as List) + .cast(); + try { + await api.writeBatchCommit(arg_app, arg_writes); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -940,37 +1031,42 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - final String arg_path = args[1]! as String; - final bool arg_isCollectionGroup = args[2]! as bool; - final InternalQueryParameters arg_parameters = - args[3]! as InternalQueryParameters; - final InternalGetOptions arg_options = args[4]! as InternalGetOptions; - final bool arg_includeMetadataChanges = args[5]! as bool; - final ListenSource arg_source = args[6]! as ListenSource; - try { - final String output = await api.querySnapshot( - arg_app, - arg_path, - arg_isCollectionGroup, - arg_parameters, - arg_options, - arg_includeMetadataChanges, - arg_source, - ); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + final String arg_path = args[1]! as String; + final bool arg_isCollectionGroup = args[2]! as bool; + final InternalQueryParameters arg_parameters = + args[3]! as InternalQueryParameters; + final InternalGetOptions arg_options = + args[4]! as InternalGetOptions; + final bool arg_includeMetadataChanges = args[5]! as bool; + final ListenSource arg_source = args[6]! as ListenSource; + try { + final String output = await api.querySnapshot( + arg_app, + arg_path, + arg_isCollectionGroup, + arg_parameters, + arg_options, + arg_includeMetadataChanges, + arg_source, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -984,31 +1080,35 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - final DocumentReferenceRequest arg_parameters = - args[1]! as DocumentReferenceRequest; - final bool arg_includeMetadataChanges = args[2]! as bool; - final ListenSource arg_source = args[3]! as ListenSource; - try { - final String output = await api.documentReferenceSnapshot( - arg_app, - arg_parameters, - arg_includeMetadataChanges, - arg_source, - ); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + final DocumentReferenceRequest arg_parameters = + args[1]! as DocumentReferenceRequest; + final bool arg_includeMetadataChanges = args[2]! as bool; + final ListenSource arg_source = args[3]! as ListenSource; + try { + final String output = await api.documentReferenceSnapshot( + arg_app, + arg_parameters, + arg_includeMetadataChanges, + arg_source, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -1022,24 +1122,31 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - final PersistenceCacheIndexManagerRequest arg_request = - args[1]! as PersistenceCacheIndexManagerRequest; - try { - await api.persistenceCacheIndexManagerRequest(arg_app, arg_request); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + final PersistenceCacheIndexManagerRequest arg_request = + args[1]! as PersistenceCacheIndexManagerRequest; + try { + await api.persistenceCacheIndexManagerRequest( + arg_app, + arg_request, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { @@ -1053,27 +1160,31 @@ abstract class TestFirebaseFirestoreHostApi { .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final FirestorePigeonFirebaseApp arg_app = - args[0]! as FirestorePigeonFirebaseApp; - final List?> arg_stages = - (args[1]! as List).cast?>(); - final Map? arg_options = - (args[2] as Map?)?.cast(); - try { - final InternalPipelineSnapshot output = - await api.executePipeline(arg_app, arg_stages, arg_options); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString()), - ); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final FirestorePigeonFirebaseApp arg_app = + args[0]! as FirestorePigeonFirebaseApp; + final List?> arg_stages = + (args[1]! as List).cast?>(); + final Map? arg_options = + (args[2] as Map?)?.cast(); + try { + final InternalPipelineSnapshot output = await api + .executePipeline(arg_app, arg_stages, arg_options); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/set_options_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/set_options_test.dart index 65e924e10856..77f5ae1265aa 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/set_options_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/set_options_test.dart @@ -28,22 +28,22 @@ void main() { ); }); - test('mergeFields are set as a [FieldPath] & preserve current FieldPaths', - () { - expect( - SetOptions( - mergeFields: [ - 'foo.bar', - FieldPath(const ['foo', 'bar', 'baz']) - ], - ).mergeFields, - equals( - [ + test( + 'mergeFields are set as a [FieldPath] & preserve current FieldPaths', + () { + expect( + SetOptions( + mergeFields: [ + 'foo.bar', + FieldPath(const ['foo', 'bar', 'baz']), + ], + ).mergeFields, + equals([ FieldPath(const ['foo', 'bar']), FieldPath(const ['foo', 'bar', 'baz']), - ], - ), - ); - }); + ]), + ); + }, + ); }); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/settings_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/settings_test.dart index a035780479f5..7400ab551ecb 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/settings_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/settings_test.dart @@ -32,8 +32,8 @@ void main() { cacheSizeBytes: Settings.CACHE_SIZE_UNLIMITED, webExperimentalLongPollingOptions: WebExperimentalLongPollingOptions( - timeoutDuration: Duration(seconds: 4), - ), + timeoutDuration: Duration(seconds: 4), + ), webPersistentTabManager: WebPersistentMultipleTabManager(), ), ), @@ -85,29 +85,30 @@ void main() { }); expect( - const Settings( - persistenceEnabled: true, - host: 'foo bar', - sslEnabled: true, - cacheSizeBytes: Settings.CACHE_SIZE_UNLIMITED, - webExperimentalAutoDetectLongPolling: true, - webExperimentalForceLongPolling: true, - webExperimentalLongPollingOptions: - WebExperimentalLongPollingOptions( + const Settings( + persistenceEnabled: true, + host: 'foo bar', + sslEnabled: true, + cacheSizeBytes: Settings.CACHE_SIZE_UNLIMITED, + webExperimentalAutoDetectLongPolling: true, + webExperimentalForceLongPolling: true, + webExperimentalLongPollingOptions: WebExperimentalLongPollingOptions( + timeoutDuration: Duration(seconds: 4), + ), + ).asMap, + { + 'persistenceEnabled': true, + 'host': 'foo bar', + 'sslEnabled': true, + 'cacheSizeBytes': Settings.CACHE_SIZE_UNLIMITED, + 'webExperimentalForceLongPolling': true, + 'webExperimentalAutoDetectLongPolling': true, + 'webExperimentalLongPollingOptions': + const WebExperimentalLongPollingOptions( timeoutDuration: Duration(seconds: 4), - )).asMap, - { - 'persistenceEnabled': true, - 'host': 'foo bar', - 'sslEnabled': true, - 'cacheSizeBytes': Settings.CACHE_SIZE_UNLIMITED, - 'webExperimentalForceLongPolling': true, - 'webExperimentalAutoDetectLongPolling': true, - 'webExperimentalLongPollingOptions': - const WebExperimentalLongPollingOptions( - timeoutDuration: Duration(seconds: 4), - ).asMap - }); + ).asMap, + }, + ); }); test('CACHE_SIZE_UNLIMITED returns -1', () { @@ -147,12 +148,14 @@ void main() { persistenceEnabled: true, webPersistentTabManager: WebPersistentMultipleTabManager(), ), - isNot(equals( - const Settings( - persistenceEnabled: true, - webPersistentTabManager: WebPersistentSingleTabManager(), + isNot( + equals( + const Settings( + persistenceEnabled: true, + webPersistentTabManager: WebPersistentSingleTabManager(), + ), ), - )), + ), ); }); @@ -164,8 +167,10 @@ void main() { final copied = settings.copyWith(host: 'localhost'); - expect(copied.webPersistentTabManager, - isA()); + expect( + copied.webPersistentTabManager, + isA(), + ); expect(copied.host, 'localhost'); expect(copied.persistenceEnabled, true); }); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/timestamp_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/timestamp_test.dart index 232d48bb8900..2ecd3f3c2da8 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/timestamp_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/timestamp_test.dart @@ -38,8 +38,10 @@ void main() { }); test('fromMillisecondsSinceEpoch throws max out of range exception', () { - expect(() => Timestamp.fromMillisecondsSinceEpoch(int64MaxValue), - throwsArgumentError); + expect( + () => Timestamp.fromMillisecondsSinceEpoch(int64MaxValue), + throwsArgumentError, + ); }); test('fromMillisecondsSinceEpoch can handle current timestamp', () { @@ -54,9 +56,10 @@ void main() { Timestamp t = Timestamp.fromMillisecondsSinceEpoch(currentEpoch); expect( - t.toDate().millisecondsSinceEpoch > - DateTime.now().millisecondsSinceEpoch, - equals(true)); + t.toDate().millisecondsSinceEpoch > + DateTime.now().millisecondsSinceEpoch, + equals(true), + ); }); test('fromMillisecondsSinceEpoch can handle 0', () { @@ -66,13 +69,15 @@ void main() { expect(t.toDate().toUtc().day, 1); }); - test('fromMillisecondsSinceEpoch can handle negative millisecond values', - () { - Timestamp t = Timestamp.fromMillisecondsSinceEpoch(-9999999999); + test( + 'fromMillisecondsSinceEpoch can handle negative millisecond values', + () { + Timestamp t = Timestamp.fromMillisecondsSinceEpoch(-9999999999); - expect(t.toDate().toUtc().year, 1969); - expect(t.toDate().toUtc().month, 9); - }); + expect(t.toDate().toUtc().year, 1969); + expect(t.toDate().toUtc().month, 9); + }, + ); test('millisecondsSinceEpoch returns correct negative epoch value', () { Timestamp t = Timestamp.fromMillisecondsSinceEpoch(-9999999999); @@ -101,13 +106,14 @@ void main() { }); test( - 'pre-1970 Timestamps should match the original DateTime after conversion', - () { - final date = DateTime(1969, 06, 22, 0, 0, 0, 123); - final timestamp = Timestamp.fromDate(date); - final timestampAsDateTime = timestamp.toDate(); - - expect(date, equals(timestampAsDateTime)); - }); + 'pre-1970 Timestamps should match the original DateTime after conversion', + () { + final date = DateTime(1969, 06, 22, 0, 0, 0, 123); + final timestamp = Timestamp.fromDate(date); + final timestampAsDateTime = timestamp.toDate(); + + expect(date, equals(timestampAsDateTime)); + }, + ); }); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/utils/test_firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/utils/test_firestore_message_codec.dart index d17c62a8ecf1..b7606422688e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/utils/test_firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/utils/test_firestore_message_codec.dart @@ -38,31 +38,38 @@ class TestFirestoreMessageCodec extends FirestoreMessageCodec { case _kArrayUnion: final List value = readValue(buffer)! as List; return FieldValuePlatform( - FieldValueFactoryPlatform.instance.arrayUnion(value)); + FieldValueFactoryPlatform.instance.arrayUnion(value), + ); case _kArrayRemove: final List value = readValue(buffer)! as List; return FieldValuePlatform( - FieldValueFactoryPlatform.instance.arrayRemove(value)); + FieldValueFactoryPlatform.instance.arrayRemove(value), + ); case _kDelete: return FieldValuePlatform(FieldValueFactoryPlatform.instance.delete()); case _kServerTimestamp: return FieldValuePlatform( - FieldValueFactoryPlatform.instance.serverTimestamp()); + FieldValueFactoryPlatform.instance.serverTimestamp(), + ); case _kIncrementDouble: final double value = readValue(buffer)! as double; return FieldValuePlatform( - FieldValueFactoryPlatform.instance.increment(value)); + FieldValueFactoryPlatform.instance.increment(value), + ); case _kIncrementInteger: final int value = readValue(buffer)! as int; return FieldValuePlatform( - FieldValueFactoryPlatform.instance.increment(value)); + FieldValueFactoryPlatform.instance.increment(value), + ); case _kFirestoreInstance: String appName = readValue(buffer)! as String; String databaseURL = readValue(buffer)! as String; readValue(buffer); final FirebaseApp app = Firebase.app(appName); return MethodChannelFirebaseFirestore( - app: app, databaseId: databaseURL); + app: app, + databaseId: databaseURL, + ); case _kFirestoreQuery: Map values = readValue(buffer)! as Map; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/cloud_firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/cloud_firestore_web.dart index 04d722e3decf..5456c54bc2c6 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/cloud_firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/cloud_firestore_web.dart @@ -43,7 +43,10 @@ class FirebaseFirestoreWeb extends FirebaseFirestorePlatform { /// Lazily initialize [_webFirestore] on first method call firestore_interop.Firestore get _delegate { return _webFirestore ??= firestore_interop.getFirestoreInstance( - core_interop.app(app.name), _interopSettings, databaseId); + core_interop.app(app.name), + _interopSettings, + databaseId, + ); } /// Called by PluginRegistry to register this plugin for Flutter Web @@ -57,13 +60,15 @@ class FirebaseFirestoreWeb extends FirebaseFirestorePlatform { /// Builds an instance of [FirebaseFirestoreWeb] with an optional [FirebaseApp] instance /// If [app] is null then the created instance will use the default [FirebaseApp] FirebaseFirestoreWeb({FirebaseApp? app, String? databaseId}) - : super(appInstance: app, databaseChoice: databaseId) { + : super(appInstance: app, databaseChoice: databaseId) { FieldValueFactoryPlatform.instance = FieldValueFactoryWeb(); } @override - FirebaseFirestorePlatform delegateFor( - {required FirebaseApp app, required String databaseId}) { + FirebaseFirestorePlatform delegateFor({ + required FirebaseApp app, + required String databaseId, + }) { return FirebaseFirestoreWeb(app: app, databaseId: databaseId); } @@ -88,8 +93,11 @@ class FirebaseFirestoreWeb extends FirebaseFirestorePlatform { @override QueryPlatform collectionGroup(String collectionPath) { return QueryWeb( - this, collectionPath, _delegate.collectionGroup(collectionPath), - isCollectionGroupQuery: true); + this, + collectionPath, + _delegate.collectionGroup(collectionPath), + isCollectionGroupQuery: true, + ); } @override @@ -207,11 +215,13 @@ class FirebaseFirestoreWeb extends FirebaseFirestorePlatform { // If this is null, it will throw an exception when initializing the Firestore instance via interop JSAny experimentalLongPollingOptions = firestore_interop.ExperimentalLongPollingOptions( - timeoutSeconds: firestoreSettings - .webExperimentalLongPollingOptions - ?.timeoutDuration - ?.inSeconds - .toJS) as JSAny; + timeoutSeconds: firestoreSettings + .webExperimentalLongPollingOptions + ?.timeoutDuration + ?.inSeconds + .toJS, + ) + as JSAny; _interopSettings?.experimentalLongPollingOptions = experimentalLongPollingOptions; } @@ -238,8 +248,9 @@ class FirebaseFirestoreWeb extends FirebaseFirestorePlatform { GetOptions options = const GetOptions(), }) async { firestore_interop.Query? query = await _delegate.namedQuery(name); - firestore_interop.QuerySnapshot snapshot = - await query.get(convertGetOptions(options)); + firestore_interop.QuerySnapshot snapshot = await query.get( + convertGetOptions(options), + ); return convertWebQuerySnapshot( this, @@ -250,9 +261,7 @@ class FirebaseFirestoreWeb extends FirebaseFirestorePlatform { @override Future setIndexConfiguration(String indexConfiguration) async { - return _delegate.setIndexConfiguration( - indexConfiguration, - ); + return _delegate.setIndexConfiguration(indexConfiguration); } @override diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/aggregate_query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/aggregate_query_web.dart index bad4b2929957..34ee4fa8f1d0 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/aggregate_query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/aggregate_query_web.dart @@ -17,9 +17,9 @@ class AggregateQueryWeb extends AggregateQueryPlatform { QueryPlatform query, firestore_interop.Query _webQuery, this._aggregateQueries, - ) : _delegate = firestore_interop.AggregateQuery(_webQuery), - _webQuery = _webQuery, - super(query); + ) : _delegate = firestore_interop.AggregateQuery(_webQuery), + _webQuery = _webQuery, + super(query); final List _aggregateQueries; final firestore_interop.Query _webQuery; @@ -30,8 +30,9 @@ class AggregateQueryWeb extends AggregateQueryPlatform { required AggregateSource source, }) async { // Note: There isn't a source option on the web platform - firestore_interop.AggregateQuerySnapshot snapshot = - await _delegate.get(_aggregateQueries); + firestore_interop.AggregateQuerySnapshot snapshot = await _delegate.get( + _aggregateQueries, + ); List sum = []; List average = []; @@ -70,39 +71,25 @@ class AggregateQueryWeb extends AggregateQueryPlatform { @override AggregateQueryPlatform count() { - return AggregateQueryWeb( - query, - _webQuery, - [ - ..._aggregateQueries, - AggregateQuery( - type: AggregateType.count, - ), - ], - ); + return AggregateQueryWeb(query, _webQuery, [ + ..._aggregateQueries, + AggregateQuery(type: AggregateType.count), + ]); } @override AggregateQueryPlatform sum(String field) { - return AggregateQueryWeb( - query, - _webQuery, - [ - ..._aggregateQueries, - AggregateQuery(type: AggregateType.sum, field: field), - ], - ); + return AggregateQueryWeb(query, _webQuery, [ + ..._aggregateQueries, + AggregateQuery(type: AggregateType.sum, field: field), + ]); } @override AggregateQueryPlatform average(String field) { - return AggregateQueryWeb( - query, - _webQuery, - [ - ..._aggregateQueries, - AggregateQuery(type: AggregateType.average, field: field), - ], - ); + return AggregateQueryWeb(query, _webQuery, [ + ..._aggregateQueries, + AggregateQuery(type: AggregateType.average, field: field), + ]); } } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart index d4215ad7f386..0581f81b188d 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart @@ -12,7 +12,7 @@ import 'query_web.dart'; /// Web implementation for Firestore [CollectionReferencePlatform]. class CollectionReferenceWeb extends QueryWeb implements -//ignore: avoid_implementing_value_types + //ignore: avoid_implementing_value_types CollectionReferencePlatform { /// instance of Firestore from the web plugin final firestore_interop.Firestore _webFirestore; @@ -25,9 +25,11 @@ class CollectionReferenceWeb extends QueryWeb /// Creates an instance of [CollectionReferenceWeb] which represents path /// at [pathComponents] and uses implementation of [webFirestore] CollectionReferenceWeb( - this._firestorePlatform, this._webFirestore, String path) - : _delegate = _webFirestore.collection(path), - super(_firestorePlatform, path, _webFirestore.collection(path)); + this._firestorePlatform, + this._webFirestore, + String path, + ) : _delegate = _webFirestore.collection(path), + super(_firestorePlatform, path, _webFirestore.collection(path)); @override String get path => _delegate.path; @@ -36,7 +38,10 @@ class CollectionReferenceWeb extends QueryWeb DocumentReferencePlatform doc([String? path]) { firestore_interop.DocumentReference documentReference = _delegate.doc(path); return DocumentReferenceWeb( - _firestorePlatform, _webFirestore, documentReference.path); + _firestorePlatform, + _webFirestore, + documentReference.path, + ); } @override @@ -51,6 +56,9 @@ class CollectionReferenceWeb extends QueryWeb } return DocumentReferenceWeb( - _firestorePlatform, _webFirestore, documentReference.path); + _firestorePlatform, + _webFirestore, + documentReference.path, + ); } } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart index 983da921ea2d..a54c080d9ffd 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart @@ -24,8 +24,8 @@ class DocumentReferenceWeb extends DocumentReferencePlatform { FirebaseFirestorePlatform firestore, this.firestoreWeb, String path, - ) : _delegate = firestoreWeb.doc(path), - super(firestore, path); + ) : _delegate = firestoreWeb.doc(path), + super(firestore, path); @override Future set(Map data, [SetOptions? options]) { @@ -45,12 +45,13 @@ class DocumentReferenceWeb extends DocumentReferencePlatform { } @override - Future get( - [GetOptions options = const GetOptions()]) async { + Future get([ + GetOptions options = const GetOptions(), + ]) async { firestore_interop.DocumentSnapshot documentSnapshot = await convertWebExceptions( - () => _delegate.get(convertGetOptions(options)), - ); + () => _delegate.get(convertGetOptions(options)), + ); return convertWebDocumentSnapshot( firestore, @@ -69,11 +70,11 @@ class DocumentReferenceWeb extends DocumentReferencePlatform { bool includeMetadataChanges = false, required ListenSource listenSource, }) { - Stream querySnapshots = - _delegate.onSnapshot( - includeMetadataChanges: includeMetadataChanges, - source: listenSource, - ); + Stream querySnapshots = _delegate + .onSnapshot( + includeMetadataChanges: includeMetadataChanges, + source: listenSource, + ); return convertWebExceptions( () => querySnapshots.map((webSnapshot) { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart index 4bc3104d5ea5..69f202930bce 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart @@ -13,14 +13,18 @@ import 'utils/encode_utility.dart'; /// instances that are [jsify] friendly. class FieldValueFactoryWeb extends FieldValueFactoryPlatform { @override - FieldValueWeb arrayRemove(List elements) => - FieldValueWeb(firestore_interop.FieldValue.arrayRemove( - EncodeUtility.valueEncode(elements))); + FieldValueWeb arrayRemove(List elements) => FieldValueWeb( + firestore_interop.FieldValue.arrayRemove( + EncodeUtility.valueEncode(elements), + ), + ); @override - FieldValueWeb arrayUnion(List elements) => - FieldValueWeb(firestore_interop.FieldValue.arrayUnion( - EncodeUtility.valueEncode(elements))); + FieldValueWeb arrayUnion(List elements) => FieldValueWeb( + firestore_interop.FieldValue.arrayUnion( + EncodeUtility.valueEncode(elements), + ), + ); @override FieldValueWeb delete() => diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/interop/firestore.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/interop/firestore.dart index 9ed2cf332707..377540adc6d5 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/interop/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/interop/firestore.dart @@ -32,27 +32,35 @@ Firestore getFirestoreInstance([ if (app != null && settings != null) { try { - return Firestore.getInstance(firestore_interop.initializeFirestore( - app.jsObject, settings, database.toJS)); + return Firestore.getInstance( + firestore_interop.initializeFirestore( + app.jsObject, + settings, + database.toJS, + ), + ); } catch (e) { if (kDebugMode) { // Fallback to initialize without settings, happens during hot restart return Firestore.getInstance( - firestore_interop.getFirestore(app.jsObject, database.toJS)); + firestore_interop.getFirestore(app.jsObject, database.toJS), + ); } rethrow; } } - return Firestore.getInstance(app != null - ? firestore_interop.getFirestore(app.jsObject, database.toJS) - : firestore_interop.getFirestore()); + return Firestore.getInstance( + app != null + ? firestore_interop.getFirestore(app.jsObject, database.toJS) + : firestore_interop.getFirestore(), + ); } JSString convertListenSource(ListenSource source) { return switch (source) { ListenSource.defaultSource => 'default'.toJS, - ListenSource.cache => 'cache'.toJS + ListenSource.cache => 'cache'.toJS, }; } @@ -71,22 +79,25 @@ class Firestore extends JsObjectWrapper { } Firestore._fromJsObject(firestore_interop.FirestoreJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); WriteBatch? batch() => WriteBatch.getInstance(firestore_interop.writeBatch(jsObject)); CollectionReference collection(String collectionPath) => CollectionReference.getInstance( - firestore_interop.collection(jsObject, collectionPath.toJS)); + firestore_interop.collection(jsObject, collectionPath.toJS), + ); Query collectionGroup(String collectionId) => Query.fromJsObject( - firestore_interop.collectionGroup(jsObject, collectionId.toJS)); + firestore_interop.collectionGroup(jsObject, collectionId.toJS), + ); DocumentReference doc(String documentPath) => DocumentReference.getInstance( - firestore_interop.doc(jsObject as JSAny, documentPath.toJS)); + firestore_interop.doc(jsObject as JSAny, documentPath.toJS), + ); -// purely for debug mode and tracking listeners to clean up on "hot restart" + // purely for debug mode and tracking listeners to clean up on "hot restart" static final Map _snapshotInSyncListeners = {}; String _snapshotInSyncWindowsKey() { if (kDebugMode) { @@ -111,12 +122,11 @@ class Firestore extends JsObjectWrapper { }).toJS; void startListen() { - onSnapshotsInSyncUnsubscribe = - firestore_interop.onSnapshotsInSync(jsObject, nextWrapper); - setWindowsListener( - snapshotKey, - onSnapshotsInSyncUnsubscribe, + onSnapshotsInSyncUnsubscribe = firestore_interop.onSnapshotsInSync( + jsObject, + nextWrapper, ); + setWindowsListener(snapshotKey, onSnapshotsInSyncUnsubscribe); } void stopListen() { @@ -137,12 +147,16 @@ class Firestore extends JsObjectWrapper { firestore_interop.clearIndexedDbPersistence(jsObject).toDart; Future runTransaction( - Function(Transaction?) updateFunction, int maxAttempts) async { + Function(Transaction?) updateFunction, + int maxAttempts, + ) async { final updateFunctionWrap = (firestore_interop.TransactionJsImpl transaction) { - return handleFutureWithMapper( - updateFunction(Transaction.getInstance(transaction)), jsify); - }; + return handleFutureWithMapper( + updateFunction(Transaction.getInstance(transaction)), + jsify, + ); + }; final future = firestore_interop .runTransaction( @@ -170,7 +184,8 @@ class Firestore extends JsObjectWrapper { LoadBundleTask loadBundle(Uint8List bundle) { return LoadBundleTask.getInstance( - firestore_interop.loadBundle(jsObject, bundle.toJS)); + firestore_interop.loadBundle(jsObject, bundle.toJS), + ); } Future setIndexConfiguration(String indexConfiguration) => @@ -187,13 +202,15 @@ class Firestore extends JsObjectWrapper { if (indexManager != null) { return switch (request) { PersistenceCacheIndexManagerRequest.enableIndexAutoCreation => - firestore_interop - .enablePersistentCacheIndexAutoCreation(indexManager), + firestore_interop.enablePersistentCacheIndexAutoCreation( + indexManager, + ), PersistenceCacheIndexManagerRequest.disableIndexAutoCreation => - firestore_interop - .disablePersistentCacheIndexAutoCreation(indexManager), + firestore_interop.disablePersistentCacheIndexAutoCreation( + indexManager, + ), PersistenceCacheIndexManagerRequest.deleteAllIndexes => - firestore_interop.deleteAllPersistentCacheIndexes(indexManager) + firestore_interop.deleteAllPersistentCacheIndexes(indexManager), }; } else { // ignore: avoid_print @@ -210,17 +227,20 @@ class Firestore extends JsObjectWrapper { if (query == null) { // same error as iOS & android to maintain consistency throw FirebaseException( - plugin: 'cloud_firestore', - message: - 'Named query has not been found. Please check it has been loaded properly via loadBundle().', - code: 'non-existent-named-query'); + plugin: 'cloud_firestore', + message: + 'Named query has not been found. Please check it has been loaded properly via loadBundle().', + code: 'non-existent-named-query', + ); } return Query.fromJsObject(query); } - bool refEqual(dynamic /* DocumentReference | CollectionReference */ left, - dynamic /* DocumentReference | CollectionReference */ right) { + bool refEqual( + dynamic /* DocumentReference | CollectionReference */ left, + dynamic /* DocumentReference | CollectionReference */ right, + ) { return firestore_interop.refEqual(left, right).toDart; } @@ -232,7 +252,7 @@ class Firestore extends JsObjectWrapper { class LoadBundleTask extends JsObjectWrapper { LoadBundleTask._fromJsObject(firestore_interop.LoadBundleTaskJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); static final _expando = Expando(); @@ -246,38 +266,42 @@ class LoadBundleTask ///Tracks progress of loadBundle snapshots as the documents are loaded into cache Stream get stream { late StreamController controller; - controller = StreamController(onListen: () { - /// Calls underlying onProgress method on a LoadBundleTask [jsObject]. - jsObject - .onProgress(((firestore_interop.LoadBundleTaskProgressJsImpl data) { - LoadBundleTaskProgress taskProgress = - LoadBundleTaskProgress._fromJsObject(data); - - if (LoadBundleTaskState.error != taskProgress.taskState) { - // Error handled in addError() call below. - controller.add(taskProgress); - } - }).toJS); - - jsObject.then( - ((JSObject value) { - controller.close(); - }).toJS, - ((JSError error) { - controller.addError( - FirebaseException( - plugin: 'cloud_firestore', - message: error.message?.toDart, - code: 'load-bundle-error', - stackTrace: StackTrace.fromString(error.stack?.toDart ?? ''), - ), - ); - controller.close(); - }).toJS, - ); - }, onCancel: () { - controller.close(); - }); + controller = StreamController( + onListen: () { + /// Calls underlying onProgress method on a LoadBundleTask [jsObject]. + jsObject.onProgress( + ((firestore_interop.LoadBundleTaskProgressJsImpl data) { + LoadBundleTaskProgress taskProgress = + LoadBundleTaskProgress._fromJsObject(data); + + if (LoadBundleTaskState.error != taskProgress.taskState) { + // Error handled in addError() call below. + controller.add(taskProgress); + } + }).toJS, + ); + + jsObject.then( + ((JSObject value) { + controller.close(); + }).toJS, + ((JSError error) { + controller.addError( + FirebaseException( + plugin: 'cloud_firestore', + message: error.message?.toDart, + code: 'load-bundle-error', + stackTrace: StackTrace.fromString(error.stack?.toDart ?? ''), + ), + ); + controller.close(); + }).toJS, + ); + }, + onCancel: () { + controller.close(); + }, + ); return controller.stream; } @@ -287,20 +311,20 @@ class LoadBundleTaskProgress extends JsObjectWrapper { LoadBundleTaskProgress._fromJsObject( firestore_interop.LoadBundleTaskProgressJsImpl jsObject, - ) : taskState = convertToTaskState(jsObject.taskState.toDart.toLowerCase()), - // Cannot be done with Dart 3.2 constraints - // ignore: invalid_runtime_check_with_js_interop_types - bytesLoaded = jsObject.bytesLoaded is JSNumber - ? (jsObject.bytesLoaded as JSNumber).toDartInt - : int.parse((jsObject.bytesLoaded as JSString).toDart), - documentsLoaded = jsObject.documentsLoaded.toDartInt, - // Cannot be done with Dart 3.2 constraints - // ignore: invalid_runtime_check_with_js_interop_types - totalBytes = jsObject.totalBytes is JSNumber - ? (jsObject.totalBytes as JSNumber).toDartInt - : int.parse((jsObject.totalBytes as JSString).toDart), - totalDocuments = jsObject.totalDocuments.toDartInt, - super.fromJsObject(jsObject); + ) : taskState = convertToTaskState(jsObject.taskState.toDart.toLowerCase()), + // Cannot be done with Dart 3.2 constraints + // ignore: invalid_runtime_check_with_js_interop_types + bytesLoaded = jsObject.bytesLoaded is JSNumber + ? (jsObject.bytesLoaded as JSNumber).toDartInt + : int.parse((jsObject.bytesLoaded as JSString).toDart), + documentsLoaded = jsObject.documentsLoaded.toDartInt, + // Cannot be done with Dart 3.2 constraints + // ignore: invalid_runtime_check_with_js_interop_types + totalBytes = jsObject.totalBytes is JSNumber + ? (jsObject.totalBytes as JSNumber).toDartInt + : int.parse((jsObject.totalBytes as JSString).toDart), + totalDocuments = jsObject.totalDocuments.toDartInt, + super.fromJsObject(jsObject); static final _expando = Expando(); @@ -308,8 +332,9 @@ class LoadBundleTaskProgress static LoadBundleTaskProgress getInstance( firestore_interop.LoadBundleTaskProgressJsImpl jsObject, ) { - return _expando[jsObject] ??= - LoadBundleTaskProgress._fromJsObject(jsObject); + return _expando[jsObject] ??= LoadBundleTaskProgress._fromJsObject( + jsObject, + ); } final LoadBundleTaskState taskState; @@ -328,30 +353,37 @@ class WriteBatch extends JsObjectWrapper { } WriteBatch._fromJsObject(firestore_interop.WriteBatchJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); Future commit() => jsObject.commit().toDart; WriteBatch delete(DocumentReference documentRef) => WriteBatch.getInstance(jsObject.delete(documentRef.jsObject)); - WriteBatch set(DocumentReference documentRef, Map data, - [firestore_interop.SetOptions? options]) { + WriteBatch set( + DocumentReference documentRef, + Map data, [ + firestore_interop.SetOptions? options, + ]) { var jsObjectSet = (options != null) ? jsObject.set(documentRef.jsObject, jsify(data)! as JSObject, options) : jsObject.set(documentRef.jsObject, jsify(data)! as JSObject); return WriteBatch.getInstance(jsObjectSet); } - WriteBatch update(DocumentReference documentRef, - Map data) { + WriteBatch update( + DocumentReference documentRef, + Map data, + ) { final List alternatingFieldValues = data.keys .map((e) => [jsify(e), jsify(data[e])]) .expand((e) => e) .toList(); - jsObject.callMethodVarArgs( - 'update'.toJS, [documentRef.jsObject, ...alternatingFieldValues]); + jsObject.callMethodVarArgs('update'.toJS, [ + documentRef.jsObject, + ...alternatingFieldValues, + ]); return this; } } @@ -373,17 +405,22 @@ class DocumentReference /// Creates a new DocumentReference from a [jsObject]. static DocumentReference getInstance( - firestore_interop.DocumentReferenceJsImpl jsObject) { + firestore_interop.DocumentReferenceJsImpl jsObject, + ) { return _expando[jsObject] ??= DocumentReference._fromJsObject(jsObject); } DocumentReference._fromJsObject( - firestore_interop.DocumentReferenceJsImpl jsObject) - : super.fromJsObject(jsObject); + firestore_interop.DocumentReferenceJsImpl jsObject, + ) : super.fromJsObject(jsObject); CollectionReference? collection(String collectionPath) { - return CollectionReference.getInstance(firestore_interop.collection( - firestore.jsObject, '$path/$collectionPath'.toJS)); + return CollectionReference.getInstance( + firestore_interop.collection( + firestore.jsObject, + '$path/$collectionPath'.toJS, + ), + ); } Future delete() => firestore_interop.deleteDoc(jsObject).toDart; @@ -399,7 +436,8 @@ class DocumentReference } final result = await future; return DocumentSnapshot.getInstance( - (result)! as firestore_interop.DocumentSnapshotJsImpl); + (result)! as firestore_interop.DocumentSnapshotJsImpl, + ); } // purely for debug mode and tracking listeners to clean up on "hot restart" @@ -421,13 +459,12 @@ class DocumentReference Stream onSnapshot({ bool includeMetadataChanges = false, ListenSource source = ListenSource.defaultSource, - }) => - _createSnapshotStream( - firestore_interop.DocumentListenOptions( - includeMetadataChanges: includeMetadataChanges.toJS, - source: convertListenSource(source), - ), - ).stream; + }) => _createSnapshotStream( + firestore_interop.DocumentListenOptions( + includeMetadataChanges: includeMetadataChanges.toJS, + source: convertListenSource(source), + ), + ).stream; StreamController _createSnapshotStream([ firestore_interop.DocumentListenOptions? options, @@ -447,9 +484,16 @@ class DocumentReference void startListen() { onSnapshotUnsubscribe = (options != null) ? firestore_interop.onSnapshot( - jsObject as JSObject, options as JSAny, nextWrapper, errorWrapper) + jsObject as JSObject, + options as JSAny, + nextWrapper, + errorWrapper, + ) : firestore_interop.onSnapshot( - jsObject as JSObject, nextWrapper, errorWrapper); + jsObject as JSObject, + nextWrapper, + errorWrapper, + ); setWindowsListener(documentKey, onSnapshotUnsubscribe); } @@ -465,8 +509,10 @@ class DocumentReference ); } - Future set(Map data, - [firestore_interop.SetOptions? options]) async { + Future set( + Map data, [ + firestore_interop.SetOptions? options, + ]) async { if (options != null) { await firestore_interop.setDoc(jsObject, jsify(data), options).toDart; return; @@ -480,11 +526,13 @@ class DocumentReference .expand((e) => e) .toList(); - await firestore_interop.updateDoc - .callMethodVarArgs('apply'.toJS, [ - null, - [jsObject, ...alternatingFieldValues].jsify() - ]).toDart; + await firestore_interop.updateDoc.callMethodVarArgs( + 'apply'.toJS, + [ + null, + [jsObject, ...alternatingFieldValues].jsify(), + ], + ).toDart; } } @@ -496,16 +544,28 @@ class Query Query.fromJsObject(T jsObject) : super.fromJsObject(jsObject); Query endAt({DocumentSnapshot? snapshot, List? fieldValues}) => - Query.fromJsObject(firestore_interop.query( + Query.fromJsObject( + firestore_interop.query( jsObject, _createQueryConstraint( - firestore_interop.endAt, snapshot, fieldValues))); + firestore_interop.endAt, + snapshot, + fieldValues, + ), + ), + ); Query endBefore({DocumentSnapshot? snapshot, List? fieldValues}) => - Query.fromJsObject(firestore_interop.query( + Query.fromJsObject( + firestore_interop.query( jsObject, _createQueryConstraint( - firestore_interop.endBefore, snapshot, fieldValues))); + firestore_interop.endBefore, + snapshot, + fieldValues, + ), + ), + ); Future get([firestore_interop.GetOptions? options]) async { late Future future; @@ -519,14 +579,20 @@ class Query } final result = await future; return QuerySnapshot.getInstance( - result! as firestore_interop.QuerySnapshotJsImpl); + result! as firestore_interop.QuerySnapshotJsImpl, + ); } Query limit(num limit) => Query.fromJsObject( - firestore_interop.query(jsObject, firestore_interop.limit(limit.toJS))); + firestore_interop.query(jsObject, firestore_interop.limit(limit.toJS)), + ); - Query limitToLast(num limit) => Query.fromJsObject(firestore_interop.query( - jsObject, firestore_interop.limitToLast(limit.toJS))); + Query limitToLast(num limit) => Query.fromJsObject( + firestore_interop.query( + jsObject, + firestore_interop.limitToLast(limit.toJS), + ), + ); // purely for debug mode and tracking listeners to clean up on "hot restart" static final Map _snapshotListeners = {}; @@ -543,17 +609,17 @@ class Query return 'no-op'; } - Stream onSnapshot( - {bool includeMetadataChanges = false, - required ListenSource listenSource, - required int hashCode}) => - _createSnapshotStream( - firestore_interop.DocumentListenOptions( - includeMetadataChanges: includeMetadataChanges.toJS, - source: convertListenSource(listenSource), - ), - hashCode, - ).stream; + Stream onSnapshot({ + bool includeMetadataChanges = false, + required ListenSource listenSource, + required int hashCode, + }) => _createSnapshotStream( + firestore_interop.DocumentListenOptions( + includeMetadataChanges: includeMetadataChanges.toJS, + source: convertListenSource(listenSource), + ), + hashCode, + ).stream; StreamController _createSnapshotStream( firestore_interop.DocumentListenOptions options, @@ -572,11 +638,12 @@ class Query void startListen() { onSnapshotUnsubscribe = firestore_interop.onSnapshot( - jsObject as JSObject, options as JSObject, nextWrapper, errorWrapper); - setWindowsListener( - snapshotKey, - onSnapshotUnsubscribe, + jsObject as JSObject, + options as JSObject, + nextWrapper, + errorWrapper, ); + setWindowsListener(snapshotKey, onSnapshotUnsubscribe); } void stopListen() { @@ -591,14 +658,17 @@ class Query ); } - Query orderBy(/*String|FieldPath*/ dynamic fieldPath, - [String? /*'desc'|'asc'*/ directionStr]) { + Query orderBy( + /*String|FieldPath*/ dynamic fieldPath, [ + String? /*'desc'|'asc'*/ directionStr, + ]) { var jsObjectOrderBy = (directionStr != null) ? firestore_interop.orderBy(fieldPath, directionStr.toJS) : firestore_interop.orderBy(fieldPath); return Query.fromJsObject( - firestore_interop.query(jsObject, jsObjectOrderBy)); + firestore_interop.query(jsObject, jsObjectOrderBy), + ); } Query startAfter({DocumentSnapshot? snapshot, List? fieldValues}) => @@ -629,11 +699,7 @@ class Query Query.fromJsObject( firestore_interop.query( jsObject, - firestore_interop.where( - fieldPath, - opStr.toJS, - jsify(value), - ), + firestore_interop.where(fieldPath, opStr.toJS, jsify(value)), ), ); @@ -642,23 +708,25 @@ class Query /// We need to call this method in all paginating methods to fix that Dart /// doesn't support varargs - we need to use [List] to call js function. firestore_interop.QueryConstraintJsImpl _createQueryConstraint( - Object method, DocumentSnapshot? snapshot, List? fieldValues) { + Object method, + DocumentSnapshot? snapshot, + List? fieldValues, + ) { if (snapshot == null && fieldValues == null) { throw ArgumentError( - 'Please provide either snapshot or fieldValues parameter.'); + 'Please provide either snapshot or fieldValues parameter.', + ); } final args = (snapshot != null) ? [snapshot.jsObject] : fieldValues!.map(jsify).toList(); - return (method as JSObject).callMethodVarArgs( - 'apply'.toJS, - [ - null, - jsify(args).jsify(), - ], - ) as firestore_interop.QueryConstraintJsImpl; + return (method as JSObject).callMethodVarArgs('apply'.toJS, [ + null, + jsify(args).jsify(), + ]) + as firestore_interop.QueryConstraintJsImpl; } Object _parseFilterWith(Map map) { @@ -667,11 +735,7 @@ class Query String opStr = map['op']! as String; dynamic value = EncodeUtility.valueEncode(map['value']); - return firestore_interop.where( - fieldPath, - opStr.toJS, - jsify(value), - ); + return firestore_interop.where(fieldPath, opStr.toJS, jsify(value)); } String opStr = map['op']! as String; @@ -683,29 +747,27 @@ class Query } if (opStr == 'OR') { - return firestore_interop.or.callMethodVarArgs( - 'apply'.toJS, - [ - null, - jsFilters.jsify(), - ], - ); + return firestore_interop.or.callMethodVarArgs('apply'.toJS, [ + null, + jsFilters.jsify(), + ]); } else if (opStr == 'AND') { - return firestore_interop.and.callMethodVarArgs( - 'apply'.toJS, - [ - null, - jsFilters.jsify(), - ], - ); + return firestore_interop.and.callMethodVarArgs('apply'.toJS, [ + null, + jsFilters.jsify(), + ]); } throw Exception('InvalidOperator'); } Query filterWith(Map map) { - return Query.fromJsObject(firestore_interop.query(jsObject, - _parseFilterWith(map) as firestore_interop.QueryConstraintJsImpl)); + return Query.fromJsObject( + firestore_interop.query( + jsObject, + _parseFilterWith(map) as firestore_interop.QueryConstraintJsImpl, + ), + ); } } @@ -722,21 +784,23 @@ class CollectionReference /// Creates a new CollectionReference from a [jsObject]. static CollectionReference getInstance( - firestore_interop.CollectionReferenceJsImpl jsObject) { + firestore_interop.CollectionReferenceJsImpl jsObject, + ) { return _expando[jsObject] ??= CollectionReference._fromJsObject(jsObject); } factory CollectionReference( - firestore_interop.CollectionReferenceJsImpl jsObject) => - CollectionReference._fromJsObject(jsObject); + firestore_interop.CollectionReferenceJsImpl jsObject, + ) => CollectionReference._fromJsObject(jsObject); CollectionReference._fromJsObject( - firestore_interop.CollectionReferenceJsImpl jsObject) - : super.fromJsObject(jsObject as T); + firestore_interop.CollectionReferenceJsImpl jsObject, + ) : super.fromJsObject(jsObject as T); Future add(Map data) async { - final future = - firestore_interop.addDoc(jsObject, jsify(data)! as JSObject).toDart; + final future = firestore_interop + .addDoc(jsObject, jsify(data)! as JSObject) + .toDart; final result = await future; return DocumentReference.getInstance(result); } @@ -767,12 +831,13 @@ class DocumentChange /// Creates a new DocumentChange from a [jsObject]. static DocumentChange getInstance( - firestore_interop.DocumentChangeJsImpl jsObject) { + firestore_interop.DocumentChangeJsImpl jsObject, + ) { return _expando[jsObject] ??= DocumentChange._fromJsObject(jsObject); } DocumentChange._fromJsObject(firestore_interop.DocumentChangeJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); } class DocumentSnapshot @@ -789,13 +854,14 @@ class DocumentSnapshot /// Creates a new DocumentSnapshot from a [jsObject]. static DocumentSnapshot getInstance( - firestore_interop.DocumentSnapshotJsImpl jsObject) { + firestore_interop.DocumentSnapshotJsImpl jsObject, + ) { return _expando[jsObject] ??= DocumentSnapshot._fromJsObject(jsObject); } DocumentSnapshot._fromJsObject( - firestore_interop.DocumentSnapshotJsImpl jsObject) - : super.fromJsObject(jsObject); + firestore_interop.DocumentSnapshotJsImpl jsObject, + ) : super.fromJsObject(jsObject); Map? data([firestore_interop.SnapshotOptions? options]) { final parsedData = dartify(jsObject.data(options)); @@ -819,20 +885,22 @@ class QuerySnapshot static final _expando = Expando(); // TODO: [SnapshotListenOptions options] - List docChanges( - [firestore_interop.SnapshotListenOptions? options]) { + List docChanges([ + firestore_interop.SnapshotListenOptions? options, + ]) { List changes = options != null ? jsObject - .docChanges( - jsify(options)! as firestore_interop.SnapshotListenOptions) - .toDart - .map((e) => e! as firestore_interop.DocumentChangeJsImpl) - .toList() + .docChanges( + jsify(options)! as firestore_interop.SnapshotListenOptions, + ) + .toDart + .map((e) => e! as firestore_interop.DocumentChangeJsImpl) + .toList() : jsObject - .docChanges() - .toDart - .map((e) => e! as firestore_interop.DocumentChangeJsImpl) - .toList(); + .docChanges() + .toDart + .map((e) => e! as firestore_interop.DocumentChangeJsImpl) + .toList(); return changes // explicitly typing the param as dynamic to work-around @@ -858,16 +926,20 @@ class QuerySnapshot num get size => jsObject.size.toDartInt; static QuerySnapshot getInstance( - firestore_interop.QuerySnapshotJsImpl jsObject) { + firestore_interop.QuerySnapshotJsImpl jsObject, + ) { return _expando[jsObject] ??= QuerySnapshot._fromJsObject(jsObject); } QuerySnapshot._fromJsObject(firestore_interop.QuerySnapshotJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); void forEach(void Function(DocumentSnapshot?) callback) { - final callbackWrap = ((JSObject s) => callback(DocumentSnapshot.getInstance( - s as firestore_interop.DocumentSnapshotJsImpl))).toJS; + final callbackWrap = ((JSObject s) => callback( + DocumentSnapshot.getInstance( + s as firestore_interop.DocumentSnapshotJsImpl, + ), + )).toJS; return jsObject.forEach(callbackWrap); } @@ -885,7 +957,7 @@ class Transaction extends JsObjectWrapper { } Transaction._fromJsObject(firestore_interop.TransactionJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); Transaction delete(DocumentReference documentRef) => Transaction.getInstance(jsObject.delete(documentRef.jsObject)); @@ -896,24 +968,31 @@ class Transaction extends JsObjectWrapper { return DocumentSnapshot.getInstance(result); } - Transaction set(DocumentReference documentRef, Map data, - [firestore_interop.SetOptions? options]) { + Transaction set( + DocumentReference documentRef, + Map data, [ + firestore_interop.SetOptions? options, + ]) { var jsObjectSet = (options != null) ? jsObject.set(documentRef.jsObject, jsify(data)! as JSObject, options) : jsObject.set(documentRef.jsObject, jsify(data)! as JSObject); return Transaction.getInstance(jsObjectSet); } - Transaction update(DocumentReference documentRef, - Map data) { + Transaction update( + DocumentReference documentRef, + Map data, + ) { final List alternatingFieldValues = data.keys .map((e) => [jsify(e), jsify(data[e])]) .expand((e) => e) .toList(); final result = jsObject - .callMethodVarArgs( - 'update'.toJS, [documentRef.jsObject, ...alternatingFieldValues]); + .callMethodVarArgs('update'.toJS, [ + documentRef.jsObject, + ...alternatingFieldValues, + ]); return Transaction.getInstance(result); } } @@ -945,13 +1024,11 @@ class _FieldValueArrayUnion extends _FieldValueArray { @override firestore_interop.FieldValue? _jsify() { - return firestore_interop.arrayUnion.callMethodVarArgs( - 'apply'.toJS, - [ - null, - jsify(elements), - ], - ) as firestore_interop.FieldValue; + return firestore_interop.arrayUnion.callMethodVarArgs('apply'.toJS, [ + null, + jsify(elements), + ]) + as firestore_interop.FieldValue; } @override @@ -964,12 +1041,10 @@ class _FieldValueArrayRemove extends _FieldValueArray { @override firestore_interop.FieldValue? _jsify() { return firestore_interop.arrayRemove.callMethodVarArgs( - 'apply'.toJS, - [ - null, - jsify(elements), - ], - ) as firestore_interop.FieldValue; + 'apply'.toJS, + [null, jsify(elements)], + ) + as firestore_interop.FieldValue; } @override @@ -1041,12 +1116,14 @@ class AggregateQuery { requests['count'] = firestore_interop.count(); break; case AggregateType.sum: - requests[name(aggregateQuery)] = - firestore_interop.sum(aggregateQuery.field!.toJS); + requests[name(aggregateQuery)] = firestore_interop.sum( + aggregateQuery.field!.toJS, + ); break; case AggregateType.average: - requests[name(aggregateQuery)] = - firestore_interop.average(aggregateQuery.field!.toJS); + requests[name(aggregateQuery)] = firestore_interop.average( + aggregateQuery.field!.toJS, + ); break; } } @@ -1068,15 +1145,17 @@ class AggregateQuerySnapshot /// Creates a new [AggregateQuerySnapshot] from a [jsObject]. static AggregateQuerySnapshot getInstance( - firestore_interop.AggregateQuerySnapshotJsImpl jsObject) { - return _expando[jsObject] ??= - AggregateQuerySnapshot._fromJsObject(jsObject); + firestore_interop.AggregateQuerySnapshotJsImpl jsObject, + ) { + return _expando[jsObject] ??= AggregateQuerySnapshot._fromJsObject( + jsObject, + ); } AggregateQuerySnapshot._fromJsObject( - firestore_interop.AggregateQuerySnapshotJsImpl jsObject) - : _data = Map.from(dartify(jsObject.data())), - super.fromJsObject(jsObject); + firestore_interop.AggregateQuerySnapshotJsImpl jsObject, + ) : _data = Map.from(dartify(jsObject.data())), + super.fromJsObject(jsObject); int? get count => (_data['count'] as num?)?.toInt(); @@ -1105,21 +1184,23 @@ class PipelineResult late final DateTime? _updateTime; static PipelineResult getInstance( - firestore_interop.PipelineResultJsImpl jsObject) { + firestore_interop.PipelineResultJsImpl jsObject, + ) { return _expando[jsObject] ??= PipelineResult._fromJsObject(jsObject); } PipelineResult._fromJsObject(firestore_interop.PipelineResultJsImpl jsObject) - : _ref = jsObject.ref != null - ? DocumentReference.getInstance(jsObject.ref!) - : null, - _data = _dataFromResult(jsObject), - _createTime = _timestampToDateTime(jsObject.createTime), - _updateTime = _timestampToDateTime(jsObject.updateTime), - super.fromJsObject(jsObject); + : _ref = jsObject.ref != null + ? DocumentReference.getInstance(jsObject.ref!) + : null, + _data = _dataFromResult(jsObject), + _createTime = _timestampToDateTime(jsObject.createTime), + _updateTime = _timestampToDateTime(jsObject.updateTime), + super.fromJsObject(jsObject); static Map? _dataFromResult( - firestore_interop.PipelineResultJsImpl jsResult) { + firestore_interop.PipelineResultJsImpl jsResult, + ) { final d = jsResult.data(); if (d == null) return null; final parsed = dartify(d); @@ -1153,12 +1234,14 @@ class PipelineSnapshot late final DateTime? _executionTime; static PipelineSnapshot getInstance( - firestore_interop.PipelineSnapshotJsImpl jsObject) { + firestore_interop.PipelineSnapshotJsImpl jsObject, + ) { return _expando[jsObject] ??= PipelineSnapshot._fromJsObject(jsObject); } static List _buildResults( - firestore_interop.PipelineSnapshotJsImpl jsObject) { + firestore_interop.PipelineSnapshotJsImpl jsObject, + ) { final rawResults = jsObject.results.toDart; return rawResults .cast() @@ -1167,10 +1250,10 @@ class PipelineSnapshot } PipelineSnapshot._fromJsObject( - firestore_interop.PipelineSnapshotJsImpl jsObject) - : _results = _buildResults(jsObject), - _executionTime = _executionTimeFromJs(jsObject.executionTime), - super.fromJsObject(jsObject); + firestore_interop.PipelineSnapshotJsImpl jsObject, + ) : _results = _buildResults(jsObject), + _executionTime = _executionTimeFromJs(jsObject.executionTime), + super.fromJsObject(jsObject); static DateTime? _executionTimeFromJs(dynamic value) { if (value == null) return null; @@ -1194,7 +1277,7 @@ class Pipeline extends JsObjectWrapper { } Pipeline._fromJsObject(firestore_interop.PipelineJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); /// Runs this pipeline using the global JS SDK execute function. Future execute(String? executeOptions) async { @@ -1203,8 +1286,9 @@ class Pipeline extends JsObjectWrapper { executeOptionsJs.indexMode = executeOptions.toJS; } executeOptionsJs.pipeline = jsObject as JSAny; - final snapshot = - await firestore_interop.pipelines.execute(executeOptionsJs).toDart; + final snapshot = await firestore_interop.pipelines + .execute(executeOptionsJs) + .toDart; return PipelineSnapshot.getInstance(snapshot); } } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/interop/firestore_interop.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/interop/firestore_interop.dart index 53a2284bf6d0..317164e2704c 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/interop/firestore_interop.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/interop/firestore_interop.dart @@ -20,12 +20,14 @@ external FirestoreJsImpl getFirestore([AppJsImpl? app, JSString? databaseURL]); @JS() @staticInterop -external FirestoreJsImpl initializeFirestore( - [AppJsImpl app, FirestoreSettings settings, JSString? databaseURL]); +external FirestoreJsImpl initializeFirestore([ + AppJsImpl app, + FirestoreSettings settings, + JSString? databaseURL, +]); @JS() @staticInterop - /// Type DocumentReferenceJsImpl external JSPromise addDoc( CollectionReferenceJsImpl reference, @@ -34,34 +36,38 @@ external JSPromise addDoc( @JS() @staticInterop -external JSPromise clearIndexedDbPersistence( - FirestoreJsImpl firestore, -); +external JSPromise clearIndexedDbPersistence(FirestoreJsImpl firestore); @JS() @staticInterop external JSPromise setIndexConfiguration( - FirestoreJsImpl firestore, JSString indexConfiguration); + FirestoreJsImpl firestore, + JSString indexConfiguration, +); @JS() @staticInterop external PersistentCacheIndexManager? getPersistentCacheIndexManager( - FirestoreJsImpl firestore); + FirestoreJsImpl firestore, +); @JS() @staticInterop external void enablePersistentCacheIndexAutoCreation( - PersistentCacheIndexManager indexManager); + PersistentCacheIndexManager indexManager, +); @JS() @staticInterop external void disablePersistentCacheIndexAutoCreation( - PersistentCacheIndexManager indexManager); + PersistentCacheIndexManager indexManager, +); @JS() @staticInterop external void deleteAllPersistentCacheIndexes( - PersistentCacheIndexManager indexManager); + PersistentCacheIndexManager indexManager, +); @JS() @staticInterop @@ -87,9 +93,7 @@ external void connectFirestoreEmulator( @JS() @staticInterop -external JSPromise deleteDoc( - DocumentReferenceJsImpl reference, -); +external JSPromise deleteDoc(DocumentReferenceJsImpl reference); @JS() @staticInterop @@ -102,8 +106,7 @@ external JSPromise disableNetwork(FirestoreJsImpl firestore); @JS() @staticInterop external DocumentReferenceJsImpl doc( - JSAny reference, // Firestore | CollectionReference - [ + JSAny reference, [ // Firestore | CollectionReference JSString documentPath, ]); @@ -141,21 +144,15 @@ external JSPromise getDocFromServer( @JS() @staticInterop -external JSPromise getDocs( - QueryJsImpl query, -); +external JSPromise getDocs(QueryJsImpl query); @JS() @staticInterop -external JSPromise getDocsFromCache( - QueryJsImpl query, -); +external JSPromise getDocsFromCache(QueryJsImpl query); @JS() @staticInterop -external JSPromise getDocsFromServer( - QueryJsImpl query, -); +external JSPromise getDocsFromServer(QueryJsImpl query); @JS() @staticInterop @@ -178,10 +175,7 @@ external LoadBundleTaskJsImpl loadBundle( @JS() @staticInterop -external JSPromise namedQuery( - FirestoreJsImpl firestore, - JSString name, -); +external JSPromise namedQuery(FirestoreJsImpl firestore, JSString name); @JS() @staticInterop @@ -195,7 +189,9 @@ external JSFunction onSnapshot( @JS() @staticInterop external JSFunction onSnapshotsInSync( - FirestoreJsImpl firestore, JSFunction observer); + FirestoreJsImpl firestore, + JSFunction observer, +); @JS() @staticInterop @@ -206,9 +202,7 @@ external QueryConstraintJsImpl orderBy( @JS() @staticInterop -external MemoryLocalCache memoryLocalCache( - MemoryCacheSettings? settings, -); +external MemoryLocalCache memoryLocalCache(MemoryCacheSettings? settings); @JS() @staticInterop @@ -349,7 +343,8 @@ external PipelinesJsImpl get pipelines; /// Use these to build expressions for where(), sort(), addFields(), aggregate(), etc. extension type PipelinesJsImpl._(JSObject _) implements JSObject { external JSPromise execute( - PipelineExecuteOptionsJsImpl pipeline); + PipelineExecuteOptionsJsImpl pipeline, + ); // --- Expression builders --- external ExpressionJsImpl field(JSString path); @@ -387,13 +382,22 @@ extension type PipelinesJsImpl._(JSObject _) implements JSObject { external ExpressionJsImpl split(JSAny expression, JSAny delimiter); external ExpressionJsImpl join(JSAny arrayExpression, JSAny delimiter); external ExpressionJsImpl substring( - JSAny input, JSAny position, JSAny length); + JSAny input, + JSAny position, + JSAny length, + ); external ExpressionJsImpl stringReplaceAll( - JSAny expression, JSAny find, JSAny replacement); + JSAny expression, + JSAny find, + JSAny replacement, + ); external ExpressionJsImpl ifAbsent(JSAny expression, JSAny elseExpr); external ExpressionJsImpl ifError(JSAny expression, JSAny catchExpr); external ExpressionJsImpl conditional( - JSAny condition, JSAny thenExpr, JSAny elseExpr); + JSAny condition, + JSAny thenExpr, + JSAny elseExpr, + ); external ExpressionJsImpl documentId(JSAny path); external ExpressionJsImpl collectionId(JSAny expression); external ExpressionJsImpl mapGet(JSAny mapExpr, JSString key); @@ -401,18 +405,33 @@ extension type PipelinesJsImpl._(JSObject _) implements JSObject { external ExpressionJsImpl mapValues(JSAny mapExpr); external ExpressionJsImpl currentTimestamp(); external ExpressionJsImpl timestampAdd( - JSAny timestamp, JSString unit, JSAny amount); + JSAny timestamp, + JSString unit, + JSAny amount, + ); external ExpressionJsImpl timestampSubtract( - JSAny timestamp, JSString unit, JSAny amount); - external ExpressionJsImpl timestampTruncate(JSAny timestamp, JSString unit, - [JSString? timezone]); + JSAny timestamp, + JSString unit, + JSAny amount, + ); + external ExpressionJsImpl timestampTruncate( + JSAny timestamp, + JSString unit, [ + JSString? timezone, + ]); external ExpressionJsImpl timestampDiff(JSAny end, JSAny start, JSAny unit); - external ExpressionJsImpl timestampExtract(JSAny timestamp, JSAny part, - [JSAny? timezone]); + external ExpressionJsImpl timestampExtract( + JSAny timestamp, + JSAny part, [ + JSAny? timezone, + ]); external ExpressionJsImpl parent(JSAny documentRefOrExpression); external ExpressionJsImpl ifNull(JSAny ifExpr, JSAny elseExpr); external ExpressionJsImpl coalesce( - JSAny first, JSAny second, JSArray more); + JSAny first, + JSAny second, + JSArray more, + ); @JS('switchOn') external JSFunction get switchOnJs; external ExpressionJsImpl abs(JSAny expr); @@ -497,9 +516,14 @@ extension type ExpressionJsImpl._(JSObject _) implements JSObject { external ExpressionJsImpl arraySlice(JSAny offset, [JSAny? length]); external ExpressionJsImpl arrayFilter(JSString alias, JSAny filter); external ExpressionJsImpl arrayTransform( - JSString elementAlias, JSAny transform); + JSString elementAlias, + JSAny transform, + ); external ExpressionJsImpl arrayTransformWithIndex( - JSString elementAlias, JSString indexAlias, JSAny transform); + JSString elementAlias, + JSString indexAlias, + JSAny transform, + ); external ExpressionJsImpl mapSet(JSAny key, JSAny value); external ExpressionJsImpl mapEntries(); } @@ -552,8 +576,10 @@ extension type WriteBatchJsImpl._(JSObject _) implements JSObject { external WriteBatchJsImpl delete(DocumentReferenceJsImpl documentRef); external WriteBatchJsImpl set( - DocumentReferenceJsImpl documentRef, JSObject data, - [SetOptions? options]); + DocumentReferenceJsImpl documentRef, + JSObject data, [ + SetOptions? options, + ]); external WriteBatchJsImpl update( DocumentReferenceJsImpl documentRef, @@ -581,16 +607,18 @@ extension PersistenceSettingsExtension on PersistenceSettings { @JS() @staticInterop class FieldPath { - external factory FieldPath(JSString fieldName0, - [JSString? fieldName1, - JSString? fieldName2, - JSString? fieldName3, - JSString? fieldName4, - JSString? fieldName5, - JSString? fieldName6, - JSString? fieldName7, - JSString? fieldName8, - JSString? fieldName9]); + external factory FieldPath( + JSString fieldName0, [ + JSString? fieldName1, + JSString? fieldName2, + JSString? fieldName3, + JSString? fieldName4, + JSString? fieldName5, + JSString? fieldName6, + JSString? fieldName7, + JSString? fieldName8, + JSString? fieldName9, + ]); } extension FieldPathExtension on FieldPath { @@ -691,25 +719,20 @@ extension QueryConstraintJsImplExtension on QueryConstraintJsImpl { } extension type LoadBundleTaskJsImpl._(JSObject _) implements JSObject { - external void onProgress( - JSFunction? next, - ); + external void onProgress(JSFunction? next); - external JSPromise then([ - JSFunction? onResolve, - JSFunction onReject, - ]); + external JSPromise then([JSFunction? onResolve, JSFunction onReject]); } extension type LoadBundleTaskProgressJsImpl._(JSObject _) implements JSObject { -// int or String? + // int or String? external JSAny get bytesLoaded; external JSNumber get documentsLoaded; external JSString get taskState; -// int or String? + // int or String? external JSAny get totalBytes; external JSNumber get totalDocuments; @@ -753,10 +776,7 @@ extension type QuerySnapshotJsImpl._(JSObject _) implements JSObject { external JSArray docChanges([SnapshotListenOptions? options]); - external void forEach( - JSFunction callback, [ - JSObject thisArg, - ]); + external void forEach(JSFunction callback, [JSObject thisArg]); } extension type TransactionJsImpl._(JSObject _) implements JSObject { @@ -765,11 +785,15 @@ extension type TransactionJsImpl._(JSObject _) implements JSObject { external JSPromise get(DocumentReferenceJsImpl documentRef); external TransactionJsImpl set( - DocumentReferenceJsImpl documentRef, JSObject data, - [SetOptions? options]); + DocumentReferenceJsImpl documentRef, + JSObject data, [ + SetOptions? options, + ]); external TransactionJsImpl update( - DocumentReferenceJsImpl documentRef, JSAny dataOrFieldsAndValues); + DocumentReferenceJsImpl documentRef, + JSAny dataOrFieldsAndValues, + ); } @JS('Timestamp') @@ -806,21 +830,23 @@ extension TimestampJsImplExtension on TimestampJsImpl { @JS() @staticInterop abstract class FirestoreError { - external factory FirestoreError( - {/*|'cancelled'|'unknown'|'invalid-argument'|'deadline-exceeded'|'not-found'|'already-exists'|'permission-denied'|'resource-exhausted'|'failed-precondition'|'aborted'|'out-of-range'|'unimplemented'|'internal'|'unavailable'|'data-loss'|'unauthenticated'*/ JSString - code, - JSString? message, - JSString? name, - JSString? stack}); + external factory FirestoreError({ + /*|'cancelled'|'unknown'|'invalid-argument'|'deadline-exceeded'|'not-found'|'already-exists'|'permission-denied'|'resource-exhausted'|'failed-precondition'|'aborted'|'out-of-range'|'unimplemented'|'internal'|'unavailable'|'data-loss'|'unauthenticated'*/ JSString + code, + JSString? message, + JSString? name, + JSString? stack, + }); } extension FirestoreErrorExtension on FirestoreError { external JSString /*|'cancelled'|'unknown'|'invalid-argument'|'deadline-exceeded'|'not-found'|'already-exists'|'permission-denied'|'resource-exhausted'|'failed-precondition'|'aborted'|'out-of-range'|'unimplemented'|'internal'|'unavailable'|'data-loss'|'unauthenticated'*/ - get code; + get code; external set code( - /*|'cancelled'|'unknown'|'invalid-argument'|'deadline-exceeded'|'not-found'|'already-exists'|'permission-denied'|'resource-exhausted'|'failed-precondition'|'aborted'|'out-of-range'|'unimplemented'|'internal'|'unavailable'|'data-loss'|'unauthenticated'*/ - JSString v); + /*|'cancelled'|'unknown'|'invalid-argument'|'deadline-exceeded'|'not-found'|'already-exists'|'permission-denied'|'resource-exhausted'|'failed-precondition'|'aborted'|'out-of-range'|'unimplemented'|'internal'|'unavailable'|'data-loss'|'unauthenticated'*/ + JSString v, + ); external JSString get message; @@ -911,9 +937,7 @@ extension FirestoreSettingsExtension on FirestoreSettings { @JS() @staticInterop abstract class ExperimentalLongPollingOptions { - external factory ExperimentalLongPollingOptions({ - JSNumber? timeoutSeconds, - }); + external factory ExperimentalLongPollingOptions({JSNumber? timeoutSeconds}); } extension ExperimentalLongPollingOptionsExtension @@ -1133,7 +1157,7 @@ extension SetOptionsExtension on SetOptions { external set merge(JSBoolean v); -//ignore: avoid_setters_without_getters + //ignore: avoid_setters_without_getters external set mergeFields(JSArray v); } @@ -1199,16 +1223,11 @@ external JSObject sum(JSString field); @JS() @staticInterop -external JSPromise getCountFromServer( - QueryJsImpl query, -); +external JSPromise getCountFromServer(QueryJsImpl query); @JS() @staticInterop -external JSPromise getAggregateFromServer( - QueryJsImpl query, - JSObject specs, -); +external JSPromise getAggregateFromServer(QueryJsImpl query, JSObject specs); extension type AggregateQuerySnapshotJsImpl._(JSObject _) implements JSObject { external JSObject data(); @@ -1253,8 +1272,11 @@ extension type PipelineJsImpl._(JSObject _) implements JSObject { external PipelineJsImpl findNearest(JSAny options); external PipelineJsImpl search(JSAny options); external PipelineJsImpl union(JSAny otherOrOptions); - external PipelineJsImpl rawStage(JSString name, JSArray params, - [JSAny? options]); + external PipelineJsImpl rawStage( + JSString name, + JSArray params, [ + JSAny? options, + ]); } /// Options for pipeline execution (e.g. index mode). diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/interop/utils/utils.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/interop/utils/utils.dart index f249b3113e53..4eed52fd1fbe 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/interop/utils/utils.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/interop/utils/utils.dart @@ -32,7 +32,9 @@ dynamic dartify(dynamic object) { if (jsObject.instanceof(TimestampJsConstructor as JSFunction)) { final castedJSObject = jsObject as TimestampJsImpl; return Timestamp( - castedJSObject.seconds.toDartInt, castedJSObject.nanoseconds.toDartInt); + castedJSObject.seconds.toDartInt, + castedJSObject.nanoseconds.toDartInt, + ); } if (jsObject.instanceof(BytesConstructor as JSFunction)) { return jsObject as BytesJsImpl; @@ -74,17 +76,13 @@ JSAny? jsify(Object? dartObject) { if (dartObject is DateTime) { final timestamp = Timestamp.fromDate(dartObject); - return TimestampJsImpl( - timestamp.seconds.toJS, - timestamp.nanoseconds.toJS, - ) as JSAny; + return TimestampJsImpl(timestamp.seconds.toJS, timestamp.nanoseconds.toJS) + as JSAny; } if (dartObject is Timestamp) { - return TimestampJsImpl( - dartObject.seconds.toJS, - dartObject.nanoseconds.toJS, - ) as JSAny; + return TimestampJsImpl(dartObject.seconds.toJS, dartObject.nanoseconds.toJS) + as JSAny; } if (dartObject is DocumentReference) { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/load_bundle_task_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/load_bundle_task_web.dart index 47f11bdb1a38..6e64406b7ce1 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/load_bundle_task_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/load_bundle_task_web.dart @@ -12,17 +12,19 @@ class LoadBundleTaskWeb extends LoadBundleTaskPlatform { LoadBundleTaskWeb(LoadBundleTask task) : super() { stream = task.stream .asBroadcastStream( - onListen: (sub) => sub.resume(), onCancel: (sub) => sub.pause()) + onListen: (sub) => sub.resume(), + onCancel: (sub) => sub.pause(), + ) .map((snapshot) { - Map data = { - 'bytesLoaded': snapshot.bytesLoaded, - 'documentsLoaded': snapshot.documentsLoaded, - 'totalBytes': snapshot.totalBytes, - 'totalDocuments': snapshot.totalDocuments - }; + Map data = { + 'bytesLoaded': snapshot.bytesLoaded, + 'documentsLoaded': snapshot.documentsLoaded, + 'totalBytes': snapshot.totalBytes, + 'totalDocuments': snapshot.totalDocuments, + }; - return LoadBundleTaskSnapshotPlatform(snapshot.taskState, data); - }); + return LoadBundleTaskSnapshotPlatform(snapshot.taskState, data); + }); } @override diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/persistent_cache_index_manager_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/persistent_cache_index_manager_web.dart index 8790f5481611..182944f0e927 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/persistent_cache_index_manager_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/persistent_cache_index_manager_web.dart @@ -9,9 +9,7 @@ import 'package:cloud_firestore_web/src/interop/firestore.dart' class PersistentCacheIndexManagerWeb extends PersistentCacheIndexManagerPlatform { - PersistentCacheIndexManagerWeb( - this._delegate, - ) : super(); + PersistentCacheIndexManagerWeb(this._delegate) : super(); final firestore_interop.Firestore _delegate; @override diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/pipeline_builder_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/pipeline_builder_web.dart index 81e181372491..6c99e6495c24 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/pipeline_builder_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/pipeline_builder_web.dart @@ -22,7 +22,11 @@ interop.PipelineJsImpl buildPipelineFromStages( // Build source stage interop.PipelineJsImpl pipeline = _applySourceStage( - source as interop.PipelineSourceJsImpl, jsFirestore, stageName, first); + source as interop.PipelineSourceJsImpl, + jsFirestore, + stageName, + first, + ); final converter = PipelineExpressionParserWeb(interop.pipelines, jsFirestore); @@ -41,20 +45,23 @@ interop.PipelineJsImpl _applySourceStage( ) { final args = first['args']; return switch (stageName) { - 'collection' => source - .collection(((args as Map)['path']! as String).toJS), + 'collection' => source.collection( + ((args as Map)['path']! as String).toJS, + ), 'collection_group' => source.collectionGroup( - ((args as Map)['path']! as String).toJS), + ((args as Map)['path']! as String).toJS, + ), 'database' => source.database(), 'documents' => source.documents( - (args as List) - .map((e) => (e as Map)['path']! as String) - .map((p) => interop.doc(jsFirestore as JSAny, p.toJS)) - .toList() - .toJS, - ), + (args as List) + .map((e) => (e as Map)['path']! as String) + .map((p) => interop.doc(jsFirestore as JSAny, p.toJS)) + .toList() + .toJS, + ), _ => throw UnsupportedError( - 'Pipeline source stage "$stageName" is not supported on web.'), + 'Pipeline source stage "$stageName" is not supported on web.', + ), }; } @@ -78,8 +85,9 @@ interop.PipelineJsImpl _applyStage( case 'where': final expression = map['expression']; if (expression == null) return pipeline; - final condition = - converter.toBooleanExpression(expression as Map); + final condition = converter.toBooleanExpression( + expression as Map, + ); if (condition == null) { throw UnsupportedError( 'Pipeline where() on web: could not parse the condition expression.', @@ -105,8 +113,9 @@ interop.PipelineJsImpl _applyStage( case 'aggregate': return pipeline.aggregate(converter.toAggregateOptionsFromFunctions(map)); case 'aggregate_with_options': - return pipeline - .aggregate(converter.toAggregateOptionsFromStageAndOptions(map)); + return pipeline.aggregate( + converter.toAggregateOptionsFromStageAndOptions(map), + ); case 'sample': return pipeline.sample(converter.toSampleOptions(args)); case 'unnest': @@ -119,15 +128,18 @@ interop.PipelineJsImpl _applyStage( final expression = map['expression']; if (expression == null) return pipeline; return pipeline.replaceWith( - converter.toReplaceWithOptions(expression as Map)); + converter.toReplaceWithOptions(expression as Map), + ); case 'find_nearest': return pipeline.findNearest(converter.toFindNearestOptions(map)); case 'search': return pipeline.search(converter.toSearchOptions(map)); case 'union': final pipelineStages = map['pipeline'] as List>; - final otherPipeline = - buildPipelineFromStages(jsFirestore, pipelineStages); + final otherPipeline = buildPipelineFromStages( + jsFirestore, + pipelineStages, + ); return pipeline.union(otherPipeline); default: throw FirebaseException( diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/pipeline_expression_parser_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/pipeline_expression_parser_web.dart index 8df3599e5194..06b4473c7a0e 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/pipeline_expression_parser_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/pipeline_expression_parser_web.dart @@ -59,11 +59,13 @@ class PipelineExpressionParserWeb { if (expressions == null || expressions.isEmpty) { throw UnsupportedError('concat requires at least one expression'); } - interop.ExpressionJsImpl result = - toExpression(expressions[0] as Map); + interop.ExpressionJsImpl result = toExpression( + expressions[0] as Map, + ); for (var i = 1; i < expressions.length; i++) { - result = result - .concat(toExpression(expressions[i] as Map)); + result = result.concat( + toExpression(expressions[i] as Map), + ); } return result; case 'length': @@ -127,13 +129,15 @@ class PipelineExpressionParserWeb { ); case 'document_id': final pathArg = argsMap[_kExpression]; - return _pipelines - .documentId(toExpression(pathArg as Map)); + return _pipelines.documentId( + toExpression(pathArg as Map), + ); case 'document_id_from_ref': final path = argsMap['doc_ref'] as String?; if (path == null || path.isEmpty) { throw ArgumentError( - "document_id_from_ref requires a non-empty 'doc_ref' path"); + "document_id_from_ref requires a non-empty 'doc_ref' path", + ); } final docRef = interop.doc(_jsFirestore as JSAny, path.toJS); return _pipelines.documentId(docRef); @@ -148,12 +152,10 @@ class PipelineExpressionParserWeb { final keyString = _constantStringFromExpression(keyExprMap); if (keyString == null) { throw UnsupportedError( - 'mapGet on web only supports a constant string key '); + 'mapGet on web only supports a constant string key ', + ); } - return _pipelines.mapGet( - _expr(argsMap, 'map'), - keyString.toJS, - ); + return _pipelines.mapGet(_expr(argsMap, 'map'), keyString.toJS); } case 'map_keys': return _pipelines.mapKeys(_expr(argsMap, _kExpression)); @@ -195,7 +197,8 @@ class PipelineExpressionParserWeb { final arrays = argsMap['arrays'] as List?; if (arrays == null || arrays.length < 2) { throw UnsupportedError( - 'array_concat_multiple requires at least two arrays'); + 'array_concat_multiple requires at least two arrays', + ); } var arrResult = _pipelines.arrayConcat( toExpression(arrays[0] as Map), @@ -261,7 +264,8 @@ class PipelineExpressionParserWeb { final kv = argsMap['key_values'] as List?; if (kv == null || kv.isEmpty || kv.length.isOdd) { throw UnsupportedError( - 'map_set requires key_values with even length'); + 'map_set requires key_values with even length', + ); } var cur = _expr(argsMap, 'map') as interop.ExpressionJsImpl; for (var i = 0; i < kv.length; i += 2) { @@ -283,9 +287,9 @@ class PipelineExpressionParserWeb { case 'string_replace_one': return (_expr(argsMap, _kExpression) as interop.ExpressionJsImpl) .stringReplaceOne( - _expr(argsMap, 'find'), - _expr(argsMap, 'replacement'), - ); + _expr(argsMap, 'find'), + _expr(argsMap, 'replacement'), + ); case 'string_index_of': return (_expr(argsMap, _kExpression) as interop.ExpressionJsImpl) .stringIndexOf(_expr(argsMap, 'search')); @@ -375,8 +379,9 @@ class PipelineExpressionParserWeb { } case 'array_filter': { - final filter = - toBooleanExpression(argsMap['filter'] as Map); + final filter = toBooleanExpression( + argsMap['filter'] as Map, + ); if (filter == null) { throw UnsupportedError('array_filter requires a boolean filter'); } @@ -386,16 +391,16 @@ class PipelineExpressionParserWeb { case 'array_transform': return (_expr(argsMap, _kExpression) as interop.ExpressionJsImpl) .arrayTransform( - (argsMap['element_alias'] as String).toJS, - _expr(argsMap, 'transform'), - ); + (argsMap['element_alias'] as String).toJS, + _expr(argsMap, 'transform'), + ); case 'array_transform_with_index': return (_expr(argsMap, _kExpression) as interop.ExpressionJsImpl) .arrayTransformWithIndex( - (argsMap['element_alias'] as String).toJS, - (argsMap['index_alias'] as String).toJS, - _expr(argsMap, 'transform'), - ); + (argsMap['element_alias'] as String).toJS, + (argsMap['index_alias'] as String).toJS, + _expr(argsMap, 'transform'), + ); case 'timestamp_diff': return _pipelines.timestampDiff( _expr(argsMap, 'end'), @@ -434,7 +439,8 @@ class PipelineExpressionParserWeb { final exprMaps = argsMap['expressions'] as List?; if (exprMaps == null || exprMaps.length < 2) { throw UnsupportedError( - 'coalesce requires at least two expressions'); + 'coalesce requires at least two expressions', + ); } final first = toExpression(exprMaps[0] as Map); final second = toExpression(exprMaps[1] as Map); @@ -474,9 +480,7 @@ class PipelineExpressionParserWeb { /// The Firebase JS pipeline API represents boolean expressions as values /// where needed (e.g. aliased add_fields); [toBooleanExpression] already /// constructs the correct interop objects. - interop.ExpressionJsImpl _expressionFromBooleanMap( - Map map, - ) { + interop.ExpressionJsImpl _expressionFromBooleanMap(Map map) { final boolExpr = toBooleanExpression(map); if (boolExpr == null) { final n = map[_kName] as String? ?? '?'; @@ -515,10 +519,10 @@ class PipelineExpressionParserWeb { } } return (_pipelines.switchOnJs as JSObject) - .callMethodVarArgs( - 'apply'.toJS, - [_pipelines, allArgs.toJS], - ); + .callMethodVarArgs('apply'.toJS, [ + _pipelines, + allArgs.toJS, + ]); } // ── Boolean expressions ─────────────────────────────────────────────────── @@ -532,22 +536,34 @@ class PipelineExpressionParserWeb { switch (name) { case 'equal': return _pipelines.equal( - _expr(argsMap, _kLeft), _expr(argsMap, _kRight)); + _expr(argsMap, _kLeft), + _expr(argsMap, _kRight), + ); case 'not_equal': return _pipelines.notEqual( - _expr(argsMap, _kLeft), _expr(argsMap, _kRight)); + _expr(argsMap, _kLeft), + _expr(argsMap, _kRight), + ); case 'greater_than': return _pipelines.greaterThan( - _expr(argsMap, _kLeft), _expr(argsMap, _kRight)); + _expr(argsMap, _kLeft), + _expr(argsMap, _kRight), + ); case 'greater_than_or_equal': return _pipelines.greaterThanOrEqual( - _expr(argsMap, _kLeft), _expr(argsMap, _kRight)); + _expr(argsMap, _kLeft), + _expr(argsMap, _kRight), + ); case 'less_than': return _pipelines.lessThan( - _expr(argsMap, _kLeft), _expr(argsMap, _kRight)); + _expr(argsMap, _kLeft), + _expr(argsMap, _kRight), + ); case 'less_than_or_equal': return _pipelines.lessThanOrEqual( - _expr(argsMap, _kLeft), _expr(argsMap, _kRight)); + _expr(argsMap, _kLeft), + _expr(argsMap, _kRight), + ); case 'and': case 'or': case 'xor': @@ -617,7 +633,8 @@ class PipelineExpressionParserWeb { throw FirebaseException( plugin: 'cloud_firestore', code: 'unsupported-boolean-expression', - message: "The boolean expression '$name' is not supported on the web " + message: + "The boolean expression '$name' is not supported on the web " 'platform. The Firebase JS SDK may not expose this expression.', ); } @@ -649,8 +666,9 @@ class PipelineExpressionParserWeb { if (name == _kAlias) { final alias = argsMap[_kAlias] as String; final expression = argsMap[_kExpression]; - return toExpression(expression as Map) - .asAlias(alias.toJS); + return toExpression( + expression as Map, + ).asAlias(alias.toJS); } return toExpression(map); } @@ -682,7 +700,8 @@ class PipelineExpressionParserWeb { /// /// Expects [map] to contain an [aggregate_functions] list. interop.AggregateStageOptionsJsImpl toAggregateOptionsFromFunctions( - Map map) { + Map map, + ) { final list = map['aggregate_functions'] as List; return _buildAccumulators(list); } @@ -692,7 +711,8 @@ class PipelineExpressionParserWeb { /// Expects [map] to contain an [aggregate_stage] map with [accumulators] /// and optionally [groups]. interop.AggregateStageOptionsJsImpl toAggregateOptionsFromStageAndOptions( - Map map) { + Map map, + ) { final stage = map['aggregate_stage'] as Map; final list = stage['accumulators'] as List; final groups = stage['groups'] as List?; @@ -746,7 +766,8 @@ class PipelineExpressionParserWeb { /// Converts find_nearest args to JS FindNearestStageOptions. interop.FindNearestStageOptionsJsImpl toFindNearestOptions( - Map map) { + Map map, + ) { final vectorField = (map['vector_field'] as String?) ?? (map[_kField] as String?); final vectorValue = map['vector_value'] as List?; @@ -826,7 +847,9 @@ class PipelineExpressionParserWeb { if (value is double) return value.toJS; if (value is DateTime) { return interop.TimestampJsImpl.fromMillis( - value.millisecondsSinceEpoch.toJS) as JSAny; + value.millisecondsSinceEpoch.toJS, + ) + as JSAny; } if (value is Timestamp) { @@ -874,11 +897,8 @@ class PipelineExpressionParserWeb { JSAny _expr(Map argsMap, String key) => toExpression(argsMap[key] as Map); - JSAny _jsArrayContains(Map argsMap) => - _pipelines.arrayContains( - _expr(argsMap, 'array'), - _expr(argsMap, 'element'), - ); + JSAny _jsArrayContains(Map argsMap) => _pipelines + .arrayContains(_expr(argsMap, 'array'), _expr(argsMap, 'element')); JSAny? _jsArrayContainsAny(Map argsMap) { final valuesMaps = argsMap['values'] as List?; @@ -933,13 +953,14 @@ class PipelineExpressionParserWeb { interop.ExpressionJsImpl _binaryArithmetic( Map argsMap, interop.ExpressionJsImpl Function( - interop.ExpressionJsImpl left, interop.ExpressionJsImpl right) - op, - ) => - op( - toExpression(argsMap[_kLeft] as Map), - toExpression(argsMap[_kRight] as Map), - ); + interop.ExpressionJsImpl left, + interop.ExpressionJsImpl right, + ) + op, + ) => op( + toExpression(argsMap[_kLeft] as Map), + toExpression(argsMap[_kRight] as Map), + ); JSAny? _buildFilterExpression(Map argsMap) { final operator = argsMap['operator'] as String?; @@ -959,8 +980,10 @@ class PipelineExpressionParserWeb { } List _toSelectableList(List expressions) => expressions - .map((e) => - toSelectable(e is Map ? e : {})) + .map( + (e) => + toSelectable(e is Map ? e : {}), + ) .whereType() .toList(); @@ -972,9 +995,11 @@ class PipelineExpressionParserWeb { if (expr == null) continue; final exprJs = toExpression(expr as Map); final dir = orderingMap['order_direction'] as String?; - list.add(dir == 'desc' - ? _pipelines.descending(exprJs) - : _pipelines.ascending(exprJs)); + list.add( + dir == 'desc' + ? _pipelines.descending(exprJs) + : _pipelines.ascending(exprJs), + ); } return list; } @@ -1009,15 +1034,18 @@ class PipelineExpressionParserWeb { if (alias == null || aggregateFn == null) return null; final fnName = aggregateFn[_kName] as String?; if (fnName == null) return null; - final expressionMap = (aggregateFn[_kArgs] - as Map?)?[_kExpression] as Map?; + final expressionMap = + (aggregateFn[_kArgs] as Map?)?[_kExpression] + as Map?; final exprJs = expressionMap != null ? toExpression(expressionMap) : null; return _buildAggregateFunction(fnName, exprJs)?.asAlias(alias.toJS); } /// Builds one JS aggregate function from a serialized [name] and optional [exprJs]. interop.AggregateFunctionJsImpl? _buildAggregateFunction( - String name, JSAny? exprJs) { + String name, + JSAny? exprJs, + ) { switch (name) { case 'count_all': return _pipelines.countAll(); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/pipeline_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/pipeline_web.dart index 5872ce7c5aaa..6c8a2cc783fb 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/pipeline_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/pipeline_web.dart @@ -24,11 +24,7 @@ class PipelineWeb extends PipelinePlatform { @override PipelinePlatform addStage(Map serializedStage) { - return PipelineWeb( - firestore, - _firestoreWeb, - [...stages, serializedStage], - ); + return PipelineWeb(firestore, _firestoreWeb, [...stages, serializedStage]); } @override @@ -59,17 +55,17 @@ class PipelineResultWeb extends PipelineResultPlatform { FirebaseFirestorePlatform firestore, firestore_interop.Firestore firestoreWeb, interop.PipelineResultJsImpl jsResult, - ) : _document = jsResult.ref != null - ? DocumentReferenceWeb( - firestore, - firestoreWeb, - jsResult.ref!.path.toDart, - ) - : null, - _createTime = _timestampToDateTime(jsResult.createTime), - _updateTime = _timestampToDateTime(jsResult.updateTime), - _data = _dataFromResult(jsResult), - super(); + ) : _document = jsResult.ref != null + ? DocumentReferenceWeb( + firestore, + firestoreWeb, + jsResult.ref!.path.toDart, + ) + : null, + _createTime = _timestampToDateTime(jsResult.createTime), + _updateTime = _timestampToDateTime(jsResult.updateTime), + _data = _dataFromResult(jsResult), + super(); final DocumentReferencePlatform? _document; final DateTime? _createTime; @@ -77,7 +73,8 @@ class PipelineResultWeb extends PipelineResultPlatform { final Map? _data; static Map? _dataFromResult( - interop.PipelineResultJsImpl jsResult) { + interop.PipelineResultJsImpl jsResult, + ) { final d = jsResult.data(); if (d == null) return null; final parsed = dartify(d); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart index 9b066e688756..1796530b5ee0 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart @@ -45,12 +45,12 @@ class QueryWeb extends QueryPlatform { @override int get hashCode => Object.hash( - runtimeType, - firestore, - _path, - isCollectionGroupQuery, - const DeepCollectionEquality().hash(parameters), - ); + runtimeType, + firestore, + _path, + isCollectionGroupQuery, + const DeepCollectionEquality().hash(parameters), + ); QueryWeb _copyWithParameters(Map parameters) { return QueryWeb( @@ -70,27 +70,33 @@ class QueryWeb extends QueryPlatform { for (final List order in parameters['orderBy']) { query = query.orderBy( - EncodeUtility.valueEncode(order[0]), order[1] ? 'desc' : 'asc'); + EncodeUtility.valueEncode(order[0]), + order[1] ? 'desc' : 'asc', + ); } if (parameters['startAt'] != null) { query = query.startAt( - fieldValues: EncodeUtility.valueEncode(parameters['startAt'])); + fieldValues: EncodeUtility.valueEncode(parameters['startAt']), + ); } if (parameters['startAfter'] != null) { query = query.startAfter( - fieldValues: EncodeUtility.valueEncode(parameters['startAfter'])); + fieldValues: EncodeUtility.valueEncode(parameters['startAfter']), + ); } if (parameters['endAt'] != null) { query = query.endAt( - fieldValues: EncodeUtility.valueEncode(parameters['endAt'])); + fieldValues: EncodeUtility.valueEncode(parameters['endAt']), + ); } if (parameters['endBefore'] != null) { query = query.endBefore( - fieldValues: EncodeUtility.valueEncode(parameters['endBefore'])); + fieldValues: EncodeUtility.valueEncode(parameters['endBefore']), + ); } if (parameters['limit'] != null) { @@ -136,7 +142,9 @@ class QueryWeb extends QueryPlatform { @override QueryPlatform endBeforeDocument( - Iterable orders, Iterable values) { + Iterable orders, + Iterable values, + ) { return _copyWithParameters({ 'orderBy': orders, 'endAt': null, @@ -186,10 +194,10 @@ class QueryWeb extends QueryPlatform { }) { Stream querySnapshots = _buildWebQueryWithParameters().onSnapshot( - includeMetadataChanges: includeMetadataChanges, - listenSource: listenSource, - hashCode: hashCode, - ); + includeMetadataChanges: includeMetadataChanges, + listenSource: listenSource, + hashCode: hashCode, + ); return convertWebExceptions( () => querySnapshots.map((webQuerySnapshot) { @@ -226,7 +234,9 @@ class QueryWeb extends QueryPlatform { @override QueryPlatform startAtDocument( - Iterable orders, Iterable values) { + Iterable orders, + Iterable values, + ) { return _copyWithParameters({ 'orderBy': orders, 'startAt': values, @@ -244,29 +254,19 @@ class QueryWeb extends QueryPlatform { @override QueryPlatform where(Iterable> conditions) { - return _copyWithParameters({ - 'where': conditions, - }); + return _copyWithParameters({'where': conditions}); } @override QueryPlatform whereFilter(FilterPlatformInterface filter) { - return _copyWithParameters({ - 'filters': filter.toJson(), - }); + return _copyWithParameters({'filters': filter.toJson()}); } @override AggregateQueryPlatform count() { - return AggregateQueryWeb( - this, - _buildWebQueryWithParameters(), - [ - AggregateQuery( - type: AggregateType.count, - ) - ], - ); + return AggregateQueryWeb(this, _buildWebQueryWithParameters(), [ + AggregateQuery(type: AggregateType.count), + ]); } @override @@ -339,19 +339,11 @@ class QueryWeb extends QueryPlatform { _buildWebQueryWithParameters(), fields.map((e) { if (e is platform_interface.count) { - return AggregateQuery( - type: AggregateType.count, - ); + return AggregateQuery(type: AggregateType.count); } else if (e is platform_interface.sum) { - return AggregateQuery( - type: AggregateType.sum, - field: e.field, - ); + return AggregateQuery(type: AggregateType.sum, field: e.field); } else if (e is platform_interface.average) { - return AggregateQuery( - type: AggregateType.average, - field: e.field, - ); + return AggregateQuery(type: AggregateType.average, field: e.field); } else { throw UnsupportedError( 'Unsupported aggregate field type ${e.runtimeType}', @@ -363,29 +355,15 @@ class QueryWeb extends QueryPlatform { @override AggregateQueryPlatform sum(String field) { - return AggregateQueryWeb( - this, - _buildWebQueryWithParameters(), - [ - AggregateQuery( - type: AggregateType.sum, - field: field, - ) - ], - ); + return AggregateQueryWeb(this, _buildWebQueryWithParameters(), [ + AggregateQuery(type: AggregateType.sum, field: field), + ]); } @override AggregateQueryPlatform average(String field) { - return AggregateQueryWeb( - this, - _buildWebQueryWithParameters(), - [ - AggregateQuery( - type: AggregateType.average, - field: field, - ) - ], - ); + return AggregateQueryWeb(this, _buildWebQueryWithParameters(), [ + AggregateQuery(type: AggregateType.average, field: field), + ]); } } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart index 6434d2e5959d..586730e3a444 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart @@ -19,8 +19,10 @@ class TransactionWeb extends TransactionPlatform { /// Constructor. TransactionWeb( - this._firestore, this._webFirestoreDelegate, this._webTransactionDelegate) - : super(); + this._firestore, + this._webFirestoreDelegate, + this._webTransactionDelegate, + ) : super(); @override TransactionWeb delete(String documentPath) { @@ -30,17 +32,16 @@ class TransactionWeb extends TransactionPlatform { @override Future get(String documentPath) { - return convertWebExceptions( - () async { - final webDocumentSnapshot = await _webTransactionDelegate - .get(_webFirestoreDelegate.doc(documentPath)); - return convertWebDocumentSnapshot( - _firestore, - webDocumentSnapshot, - ServerTimestampBehavior.none, - ); - }, - ); + return convertWebExceptions(() async { + final webDocumentSnapshot = await _webTransactionDelegate.get( + _webFirestoreDelegate.doc(documentPath), + ); + return convertWebDocumentSnapshot( + _firestore, + webDocumentSnapshot, + ServerTimestampBehavior.none, + ); + }); } @override @@ -58,10 +59,7 @@ class TransactionWeb extends TransactionPlatform { } @override - TransactionWeb update( - String documentPath, - Map data, - ) { + TransactionWeb update(String documentPath, Map data) { _webTransactionDelegate.update( _webFirestoreDelegate.doc(documentPath), EncodeUtility.encodeMapDataFieldPath(data)!, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/decode_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/decode_utility.dart index a227cdb710a9..c9a10b8edb0a 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/decode_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/decode_utility.dart @@ -16,7 +16,9 @@ import '../interop/firestore.dart' as firestore_interop; class DecodeUtility { /// Decodes the values on an incoming Map to their proper types. static Map? decodeMapData( - Map? data, FirebaseFirestorePlatform firestore) { + Map? data, + FirebaseFirestorePlatform firestore, + ) { if (data == null) { return null; } @@ -25,7 +27,9 @@ class DecodeUtility { /// Decodes the values on an incoming Array to their proper types. static List? decodeArrayData( - List? data, FirebaseFirestorePlatform firestore) { + List? data, + FirebaseFirestorePlatform firestore, + ) { if (data == null) { return null; } @@ -34,22 +38,28 @@ class DecodeUtility { /// Decodes an incoming value to its proper type. static dynamic valueDecode( - dynamic value, FirebaseFirestorePlatform firestore) { + dynamic value, + FirebaseFirestorePlatform firestore, + ) { // Cannot be done with Dart 3.2 constraints // ignore: invalid_runtime_check_with_js_interop_types if (value is JSObject && value.instanceof(GeoPointConstructor as JSFunction)) { - return GeoPoint((value as GeoPointJsImpl).latitude.toDartDouble, - (value as GeoPointJsImpl).longitude.toDartDouble); + return GeoPoint( + (value as GeoPointJsImpl).latitude.toDartDouble, + (value as GeoPointJsImpl).longitude.toDartDouble, + ); // Cannot be done with Dart 3.2 constraints // ignore: invalid_runtime_check_with_js_interop_types } else if (value is JSObject && value.instanceof(VectorValueConstructor as JSFunction)) { - return VectorValue((value as VectorValueJsImpl) - .toArray() - .toDart - .map((JSAny? e) => (e! as JSNumber).toDartDouble) - .toList()); + return VectorValue( + (value as VectorValueJsImpl) + .toArray() + .toDart + .map((JSAny? e) => (e! as JSNumber).toDartDouble) + .toList(), + ); } else if (value is DateTime) { return Timestamp.fromDate(value); // Cannot be done with Dart 3.2 constraints diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/encode_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/encode_utility.dart index acc3f880b6e4..6d95e0945d67 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/encode_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/encode_utility.dart @@ -20,15 +20,17 @@ class EncodeUtility { } final output = {}; data.forEach((key, value) { - final stringKey = - key is DocumentReferencePlatform ? key.path : key as String; + final stringKey = key is DocumentReferencePlatform + ? key.path + : key as String; output[stringKey] = valueEncode(value); }); return output; } static Map? encodeMapDataFieldPath( - Map? data) { + Map? data, + ) { if (data == null) { return null; } @@ -61,61 +63,81 @@ class EncodeUtility { // deep FieldPaths which the web counterpart supports return switch (length) { 1 => firestore_interop.FieldPath(components[0].toJS), - 2 => - firestore_interop.FieldPath(components[0].toJS, components[1].toJS), + 2 => firestore_interop.FieldPath( + components[0].toJS, + components[1].toJS, + ), 3 => firestore_interop.FieldPath( - components[0].toJS, components[1].toJS, components[2].toJS), - 4 => firestore_interop.FieldPath(components[0].toJS, components[1].toJS, - components[2].toJS, components[3].toJS), - 5 => firestore_interop.FieldPath(components[0].toJS, components[1].toJS, - components[2].toJS, components[3].toJS, components[4].toJS), + components[0].toJS, + components[1].toJS, + components[2].toJS, + ), + 4 => firestore_interop.FieldPath( + components[0].toJS, + components[1].toJS, + components[2].toJS, + components[3].toJS, + ), + 5 => firestore_interop.FieldPath( + components[0].toJS, + components[1].toJS, + components[2].toJS, + components[3].toJS, + components[4].toJS, + ), 6 => firestore_interop.FieldPath( - components[0].toJS, - components[1].toJS, - components[2].toJS, - components[3].toJS, - components[4].toJS, - components[5].toJS), + components[0].toJS, + components[1].toJS, + components[2].toJS, + components[3].toJS, + components[4].toJS, + components[5].toJS, + ), 7 => firestore_interop.FieldPath( - components[0].toJS, - components[1].toJS, - components[2].toJS, - components[3].toJS, - components[4].toJS, - components[5].toJS, - components[6].toJS), + components[0].toJS, + components[1].toJS, + components[2].toJS, + components[3].toJS, + components[4].toJS, + components[5].toJS, + components[6].toJS, + ), 8 => firestore_interop.FieldPath( - components[0].toJS, - components[1].toJS, - components[2].toJS, - components[3].toJS, - components[4].toJS, - components[5].toJS, - components[6].toJS, - components[7].toJS), + components[0].toJS, + components[1].toJS, + components[2].toJS, + components[3].toJS, + components[4].toJS, + components[5].toJS, + components[6].toJS, + components[7].toJS, + ), 9 => firestore_interop.FieldPath( - components[0].toJS, - components[1].toJS, - components[2].toJS, - components[3].toJS, - components[4].toJS, - components[5].toJS, - components[6].toJS, - components[7].toJS, - components[8].toJS), + components[0].toJS, + components[1].toJS, + components[2].toJS, + components[3].toJS, + components[4].toJS, + components[5].toJS, + components[6].toJS, + components[7].toJS, + components[8].toJS, + ), 10 => firestore_interop.FieldPath( - components[0].toJS, - components[1].toJS, - components[2].toJS, - components[3].toJS, - components[4].toJS, - components[5].toJS, - components[6].toJS, - components[7].toJS, - components[8].toJS, - components[9].toJS), + components[0].toJS, + components[1].toJS, + components[2].toJS, + components[3].toJS, + components[4].toJS, + components[5].toJS, + components[6].toJS, + components[7].toJS, + components[8].toJS, + components[9].toJS, + ), _ => throw Exception( - 'Firestore web FieldPath only supports 10 levels deep field paths') + 'Firestore web FieldPath only supports 10 levels deep field paths', + ), }; } else if (value == FieldPath.documentId) { return firestore_interop.documentId(); @@ -126,7 +148,9 @@ class EncodeUtility { ); } else if (value is GeoPoint) { return firestore_interop.GeoPointJsImpl( - value.latitude.toJS, value.longitude.toJS); + value.latitude.toJS, + value.longitude.toJS, + ); } else if (value is VectorValue) { return firestore_interop.vector(value.toArray().jsify()! as JSArray); } else if (value is Blob) { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/web_utils.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/web_utils.dart index c92ef6b73fb8..8dee2ded7120 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/web_utils.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/web_utils.dart @@ -22,30 +22,35 @@ String getServerTimestampBehaviorString( return switch (serverTimestampBehavior) { ServerTimestampBehavior.none => 'none', ServerTimestampBehavior.estimate => 'estimate', - ServerTimestampBehavior.previous => 'previous' + ServerTimestampBehavior.previous => 'previous', }; } /// Converts a [web.QuerySnapshot] to a [QuerySnapshotPlatform]. QuerySnapshotPlatform convertWebQuerySnapshot( - FirebaseFirestorePlatform firestore, - firestore_interop.QuerySnapshot webQuerySnapshot, - ServerTimestampBehavior serverTimestampBehavior) { + FirebaseFirestorePlatform firestore, + firestore_interop.QuerySnapshot webQuerySnapshot, + ServerTimestampBehavior serverTimestampBehavior, +) { return QuerySnapshotPlatform( webQuerySnapshot.docs - .map((webDocumentSnapshot) => convertWebDocumentSnapshot( - firestore, - webDocumentSnapshot!, - serverTimestampBehavior, - )) + .map( + (webDocumentSnapshot) => convertWebDocumentSnapshot( + firestore, + webDocumentSnapshot!, + serverTimestampBehavior, + ), + ) .toList(), webQuerySnapshot .docChanges() - .map((webDocumentChange) => convertWebDocumentChange( - firestore, - webDocumentChange, - serverTimestampBehavior, - )) + .map( + (webDocumentChange) => convertWebDocumentChange( + firestore, + webDocumentChange, + serverTimestampBehavior, + ), + ) .toList(), convertWebSnapshotMetadata(webQuerySnapshot.metadata), ); @@ -61,10 +66,13 @@ DocumentSnapshotPlatform convertWebDocumentSnapshot( firestore, webSnapshot.ref!.path, DecodeUtility.decodeMapData( - webSnapshot.data(SnapshotOptions( - serverTimestamps: - getServerTimestampBehaviorString(serverTimestampBehavior).toJS, - )), + webSnapshot.data( + SnapshotOptions( + serverTimestamps: getServerTimestampBehaviorString( + serverTimestampBehavior, + ).toJS, + ), + ), firestore, ), InternalSnapshotMetadata( @@ -81,14 +89,15 @@ DocumentChangePlatform convertWebDocumentChange( ServerTimestampBehavior serverTimestampBehavior, ) { return DocumentChangePlatform( - convertWebDocumentChangeType(webDocumentChange.type), - webDocumentChange.oldIndex.toInt(), - webDocumentChange.newIndex.toInt(), - convertWebDocumentSnapshot( - firestore, - webDocumentChange.doc!, - serverTimestampBehavior, - )); + convertWebDocumentChangeType(webDocumentChange.type), + webDocumentChange.oldIndex.toInt(), + webDocumentChange.newIndex.toInt(), + convertWebDocumentSnapshot( + firestore, + webDocumentChange.doc!, + serverTimestampBehavior, + ), + ); } /// Converts a [web.DocumentChange] type into a [DocumentChangeType]. @@ -97,15 +106,18 @@ DocumentChangeType convertWebDocumentChangeType(String changeType) { _kChangeTypeAdded => DocumentChangeType.added, _kChangeTypeModified => DocumentChangeType.modified, _kChangeTypeRemoved => DocumentChangeType.removed, - _ => throw UnsupportedError('Unknown DocumentChangeType: $changeType.') + _ => throw UnsupportedError('Unknown DocumentChangeType: $changeType.'), }; } /// Converts a [web.SnapshotMetadata] to a [SnapshotMetadataPlatform]. SnapshotMetadataPlatform convertWebSnapshotMetadata( - firestore_interop.SnapshotMetadata webSnapshotMetadata) { - return SnapshotMetadataPlatform(webSnapshotMetadata.hasPendingWrites.toDart, - webSnapshotMetadata.fromCache.toDart); + firestore_interop.SnapshotMetadata webSnapshotMetadata, +) { + return SnapshotMetadataPlatform( + webSnapshotMetadata.hasPendingWrites.toDart, + webSnapshotMetadata.fromCache.toDart, + ); } /// Converts a [GetOptions] to a [web.GetOptions]. @@ -115,7 +127,7 @@ firestore_interop.GetOptions? convertGetOptions(GetOptions? options) { final source = switch (options.source) { Source.serverAndCache => 'default', Source.cache => 'cache', - Source.server => 'server' + Source.server => 'server', }; return firestore_interop.GetOptions(source: source.toJS); @@ -143,5 +155,6 @@ firestore_interop.SetOptions? convertSetOptions(SetOptions? options) { /// Converts a [FieldPath] to a [web.FieldPath]. firestore_interop.FieldPath convertFieldPath(FieldPath fieldPath) { return firestore_interop.FieldPath( - fieldPath.components.toList().join('.').toJS); + fieldPath.components.toList().join('.').toJS, + ); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart index b3a063eb1dcd..4c946475d174 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart @@ -17,8 +17,8 @@ class WriteBatchWeb extends WriteBatchPlatform { /// Constructor. WriteBatchWeb(this._webFirestoreDelegate) - : _webWriteBatchDelegate = _webFirestoreDelegate.batch()!, - super(); + : _webWriteBatchDelegate = _webFirestoreDelegate.batch()!, + super(); @override Future commit() { @@ -31,18 +31,23 @@ class WriteBatchWeb extends WriteBatchPlatform { } @override - void set(String documentPath, Map data, - [SetOptions? options]) { - _webWriteBatchDelegate.set(_webFirestoreDelegate.doc(documentPath), - EncodeUtility.encodeMapData(data)!, convertSetOptions(options)); + void set( + String documentPath, + Map data, [ + SetOptions? options, + ]) { + _webWriteBatchDelegate.set( + _webFirestoreDelegate.doc(documentPath), + EncodeUtility.encodeMapData(data)!, + convertSetOptions(options), + ); } @override - void update( - String documentPath, - Map data, - ) { - _webWriteBatchDelegate.update(_webFirestoreDelegate.doc(documentPath), - EncodeUtility.encodeMapDataFieldPath(data)!); + void update(String documentPath, Map data) { + _webWriteBatchDelegate.update( + _webFirestoreDelegate.doc(documentPath), + EncodeUtility.encodeMapDataFieldPath(data)!, + ); } } diff --git a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml index 1e58f41116b3..de37941e2d0b 100644 --- a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml @@ -7,8 +7,8 @@ version: 5.7.3 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.22.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/cloud_functions/cloud_functions/example/integration_test/e2e_test.dart b/packages/cloud_functions/cloud_functions/example/integration_test/e2e_test.dart index b2f088f9cd01..1f615eab47d8 100644 --- a/packages/cloud_functions/cloud_functions/example/integration_test/e2e_test.dart +++ b/packages/cloud_functions/cloud_functions/example/integration_test/e2e_test.dart @@ -48,8 +48,9 @@ void main() { } } FirebaseFunctions.instance.useFunctionsEmulator('localhost', 5001); - callable = - FirebaseFunctions.instance.httpsCallable(kTestFunctionDefaultRegion); + callable = FirebaseFunctions.instance.httpsCallable( + kTestFunctionDefaultRegion, + ); }); group('HttpsCallable', () { @@ -155,8 +156,9 @@ void main() { test( '[HttpsCallableResult.data] should return Map type for returned objects', () async { - HttpsCallable callable = - FirebaseFunctions.instance.httpsCallable(kTestMapConvertType); + HttpsCallable callable = FirebaseFunctions.instance.httpsCallable( + kTestMapConvertType, + ); var result = await callable(); @@ -165,11 +167,12 @@ void main() { ); test('can be called using an String url', () async { - final localhostMapped = - kIsWeb || !Platform.isAndroid ? 'localhost' : '10.0.2.2'; + final localhostMapped = kIsWeb || !Platform.isAndroid + ? 'localhost' + : '10.0.2.2'; - HttpsCallable callable = - FirebaseFunctions.instance.httpsCallableFromUrl( + HttpsCallable + callable = FirebaseFunctions.instance.httpsCallableFromUrl( 'http://$localhostMapped:5001/flutterfire-e2e-tests/us-central1/listfruits2ndgen', ); @@ -178,11 +181,12 @@ void main() { }); test('can be called using an Uri url', () async { - final localhostMapped = - kIsWeb || !Platform.isAndroid ? 'localhost' : '10.0.2.2'; + final localhostMapped = kIsWeb || !Platform.isAndroid + ? 'localhost' + : '10.0.2.2'; - HttpsCallable callable = - FirebaseFunctions.instance.httpsCallableFromUri( + HttpsCallable + callable = FirebaseFunctions.instance.httpsCallableFromUri( Uri.parse( 'http://$localhostMapped:5001/flutterfire-e2e-tests/us-central1/listfruits2ndgen', ), @@ -194,19 +198,21 @@ void main() { }); group('FirebaseFunctionsException', () { - test('HttpsCallable returns a FirebaseFunctionsException on error', - () async { - try { - await callable({}); - fail('Should have thrown'); - } on FirebaseFunctionsException catch (e) { - expect(e.code, equals('invalid-argument')); - expect(e.message, equals('Invalid test requested.')); - return; - } catch (e) { - fail('$e'); - } - }); + test( + 'HttpsCallable returns a FirebaseFunctionsException on error', + () async { + try { + await callable({}); + fail('Should have thrown'); + } on FirebaseFunctionsException catch (e) { + expect(e.code, equals('invalid-argument')); + expect(e.message, equals('Invalid test requested.')); + return; + } catch (e) { + fail('$e'); + } + }, + ); test('it returns "details" value as part of the exception', () async { try { @@ -235,8 +241,9 @@ void main() { test('accepts a custom region', () async { final instance = FirebaseFunctions.instanceFor(region: 'europe-west1'); instance.useFunctionsEmulator('localhost', 5001); - final customRegionCallable = - instance.httpsCallable(kTestFunctionCustomRegion); + final customRegionCallable = instance.httpsCallable( + kTestFunctionCustomRegion, + ); final result = await customRegionCallable(); expect(result.data, equals('europe-west1')); }); @@ -254,8 +261,9 @@ void main() { ); try { await timeoutCallable({ - 'testTimeout': - const Duration(seconds: 6).inMilliseconds.toString(), + 'testTimeout': const Duration( + seconds: 6, + ).inMilliseconds.toString(), }); fail('Should have thrown'); } on FirebaseFunctionsException catch (e) { @@ -269,29 +277,27 @@ void main() { skip: defaultTargetPlatform == TargetPlatform.android, ); - test( - 'allow passing of `limitedUseAppCheckToken` as option', - () async { - final instance = FirebaseFunctions.instance; - instance.useFunctionsEmulator('localhost', 5001); - final timeoutCallable = FirebaseFunctions.instance.httpsCallable( - kTestFunctionDefaultRegion, - options: HttpsCallableOptions( - timeout: const Duration(seconds: 3), - limitedUseAppCheckToken: true, - ), - ); + test('allow passing of `limitedUseAppCheckToken` as option', () async { + final instance = FirebaseFunctions.instance; + instance.useFunctionsEmulator('localhost', 5001); + final timeoutCallable = FirebaseFunctions.instance.httpsCallable( + kTestFunctionDefaultRegion, + options: HttpsCallableOptions( + timeout: const Duration(seconds: 3), + limitedUseAppCheckToken: true, + ), + ); - HttpsCallableResult results = await timeoutCallable(); - expect(results.data, equals('null')); - }, - ); + HttpsCallableResult results = await timeoutCallable(); + expect(results.data, equals('null')); + }); }); group('HttpsCallable Stream', () { test('returns a [StreamResponse]', () { - final streamResponseCallable = - FirebaseFunctions.instance.httpsCallable(kTestStreamResponse); + final streamResponseCallable = FirebaseFunctions.instance.httpsCallable( + kTestStreamResponse, + ); final stream = streamResponseCallable.stream(); expect(stream, emits(isA())); }); @@ -301,8 +307,11 @@ void main() { await expectLater( stream, emits( - isA() - .having((e) => e.partialData, 'partialData', equals('string')), + isA().having( + (e) => e.partialData, + 'partialData', + equals('string'), + ), ), ); }); @@ -315,8 +324,11 @@ void main() { await expectLater( stream, emits( - isA() - .having((e) => e.partialData, 'partialData', equals('number')), + isA().having( + (e) => e.partialData, + 'partialData', + equals('number'), + ), ), ); }); @@ -329,8 +341,11 @@ void main() { await expectLater( stream, emits( - isA() - .having((e) => e.partialData, 'partialData', equals('null')), + isA().having( + (e) => e.partialData, + 'partialData', + equals('null'), + ), ), ); }); @@ -340,8 +355,11 @@ void main() { await expectLater( stream, emits( - isA() - .having((e) => e.partialData, 'partialData', equals('boolean')), + isA().having( + (e) => e.partialData, + 'partialData', + equals('boolean'), + ), ), ); }); @@ -351,18 +369,22 @@ void main() { await expectLater( stream, emits( - isA() - .having((e) => e.partialData, 'partialData', equals('boolean')), + isA().having( + (e) => e.partialData, + 'partialData', + equals('boolean'), + ), ), ); }); test('can be called using an String url', () async { - final localhostMapped = - kIsWeb || !Platform.isAndroid ? 'localhost' : '10.0.2.2'; + final localhostMapped = kIsWeb || !Platform.isAndroid + ? 'localhost' + : '10.0.2.2'; - HttpsCallable callable = - FirebaseFunctions.instance.httpsCallableFromUrl( + HttpsCallable + callable = FirebaseFunctions.instance.httpsCallableFromUrl( 'http://$localhostMapped:5001/flutterfire-e2e-tests/us-central1/listfruits2ndgen', ); @@ -371,11 +393,12 @@ void main() { }); test('can be called using an Uri url', () async { - final localhostMapped = - kIsWeb || !Platform.isAndroid ? 'localhost' : '10.0.2.2'; + final localhostMapped = kIsWeb || !Platform.isAndroid + ? 'localhost' + : '10.0.2.2'; - HttpsCallable callable = - FirebaseFunctions.instance.httpsCallableFromUri( + HttpsCallable + callable = FirebaseFunctions.instance.httpsCallableFromUri( Uri.parse( 'http://$localhostMapped:5001/flutterfire-e2e-tests/us-central1/listfruits2ndgen', ), @@ -385,33 +408,27 @@ void main() { await expectLater(stream, emits(isA())); }); - test( - 'concurrent streams on the same callable do not collide', - () async { - // Regression test for https://github.com/firebase/flutterfire/issues/18036 - final stream1 = callable - .stream('foo') - .where((event) => event is Chunk) - .map((event) => (event as Chunk).partialData) - .first; - final stream2 = callable - .stream(123) - .where((event) => event is Chunk) - .map((event) => (event as Chunk).partialData) - .first; - - final results = await Future.wait([stream1, stream2]); - expect(results[0], equals('string')); - expect(results[1], equals('number')); - }, - ); + test('concurrent streams on the same callable do not collide', () async { + // Regression test for https://github.com/firebase/flutterfire/issues/18036 + final stream1 = callable + .stream('foo') + .where((event) => event is Chunk) + .map((event) => (event as Chunk).partialData) + .first; + final stream2 = callable + .stream(123) + .where((event) => event is Chunk) + .map((event) => (event as Chunk).partialData) + .first; + + final results = await Future.wait([stream1, stream2]); + expect(results[0], equals('string')); + expect(results[1], equals('number')); + }); test('should emit a [Result] as last value', () async { final stream = await callable.stream().last; - expect( - stream, - isA(), - ); + expect(stream, isA()); }); test( @@ -424,31 +441,31 @@ void main() { final terminalEvent = await stream.where((e) => e is Result).last; expect(terminalEvent, isA()); final result = (terminalEvent as Result).result; - expect( - result.data, - isA>(), - ); + expect(result.data, isA>()); }, skip: !kIsWeb, ); test('accepts a [List]', () async { - final stream = - callable.stream(data.list).where((event) => event is Chunk); + final stream = callable + .stream(data.list) + .where((event) => event is Chunk); await expectLater( stream, emits( - isA() - .having((e) => e.partialData, 'partialData', equals('array')), + isA().having( + (e) => e.partialData, + 'partialData', + equals('array'), + ), ), ); }); test('accepts a deeply nested [Map]', () async { - final stream = callable.stream({ - 'type': 'deepMap', - 'inputData': data.deepMap, - }).where((event) => event is Chunk); + final stream = callable + .stream({'type': 'deepMap', 'inputData': data.deepMap}) + .where((event) => event is Chunk); await expectLater( stream, emits( @@ -461,75 +478,73 @@ void main() { ); }); - test( - 'throws error when aborted with TimeLimit signal', - () async { - final instance = FirebaseFunctions.instance; - instance.useFunctionsEmulator('localhost', 5001); + test('throws error when aborted with TimeLimit signal', () async { + final instance = FirebaseFunctions.instance; + instance.useFunctionsEmulator('localhost', 5001); - final completer = Completer(); + final completer = Completer(); - final timeoutCallable = FirebaseFunctions.instance.httpsCallable( - kTestFunctionTimeout, - options: HttpsCallableOptions( - webAbortSignal: TimeLimit(const Duration(seconds: 3)), - ), - ); - - timeoutCallable.stream({ - 'testTimeout': const Duration(seconds: 6).inMilliseconds.toString(), - }).listen( - (data) { - completer.completeError('Should have thrown'); - }, - onError: (error) { - if (error is FirebaseFunctionsException) { - expect(error.code, equals('internal')); - completer.complete(); - } else { - completer.completeError('Unexpected error type: $error'); - } - }, - ); - await completer.future.timeout(_completerTimeout); - }, - skip: !kIsWeb, - ); + final timeoutCallable = FirebaseFunctions.instance.httpsCallable( + kTestFunctionTimeout, + options: HttpsCallableOptions( + webAbortSignal: TimeLimit(const Duration(seconds: 3)), + ), + ); - test( - 'throws error when aborted with Abort signal', - () async { - final instance = FirebaseFunctions.instance; - instance.useFunctionsEmulator('localhost', 5001); + timeoutCallable + .stream({ + 'testTimeout': const Duration( + seconds: 6, + ).inMilliseconds.toString(), + }) + .listen( + (data) { + completer.completeError('Should have thrown'); + }, + onError: (error) { + if (error is FirebaseFunctionsException) { + expect(error.code, equals('internal')); + completer.complete(); + } else { + completer.completeError('Unexpected error type: $error'); + } + }, + ); + await completer.future.timeout(_completerTimeout); + }, skip: !kIsWeb); + + test('throws error when aborted with Abort signal', () async { + final instance = FirebaseFunctions.instance; + instance.useFunctionsEmulator('localhost', 5001); - final completer = Completer(); + final completer = Completer(); - final timeoutCallable = FirebaseFunctions.instance.httpsCallable( - kTestFunctionTimeout, - options: HttpsCallableOptions( - webAbortSignal: Abort('aborted'), - ), - ); + final timeoutCallable = FirebaseFunctions.instance.httpsCallable( + kTestFunctionTimeout, + options: HttpsCallableOptions(webAbortSignal: Abort('aborted')), + ); - timeoutCallable.stream({ - 'testTimeout': const Duration(seconds: 6).inMilliseconds.toString(), - }).listen( - (data) { - completer.completeError('Should have thrown'); - }, - onError: (error) { - if (error is FirebaseFunctionsException) { - expect(error.code, equals('internal')); - completer.complete(); - } else { - completer.completeError('Unexpected error type: $error'); - } - }, - ); - await completer.future.timeout(_completerTimeout); - }, - skip: !kIsWeb, - ); + timeoutCallable + .stream({ + 'testTimeout': const Duration( + seconds: 6, + ).inMilliseconds.toString(), + }) + .listen( + (data) { + completer.completeError('Should have thrown'); + }, + onError: (error) { + if (error is FirebaseFunctionsException) { + expect(error.code, equals('internal')); + completer.complete(); + } else { + completer.completeError('Unexpected error type: $error'); + } + }, + ); + await completer.future.timeout(_completerTimeout); + }, skip: !kIsWeb); }); }); } diff --git a/packages/cloud_functions/cloud_functions/example/integration_test/report_test_results.dart b/packages/cloud_functions/cloud_functions/example/integration_test/report_test_results.dart index f04b57f3cf38..ae1d2ffb7574 100644 --- a/packages/cloud_functions/cloud_functions/example/integration_test/report_test_results.dart +++ b/packages/cloud_functions/cloud_functions/example/integration_test/report_test_results.dart @@ -26,8 +26,9 @@ void reportTestResultsToDriver(IntegrationTestWidgetsFlutterBinding binding) { for (final entry in binding.results.entries) if (entry.value is Failure) entry.key, ]; - bool didFail(String name) => failures - .any((failure) => name == failure || name.endsWith(' $failure')); + bool didFail(String name) => failures.any( + (failure) => name == failure || name.endsWith(' $failure'), + ); binding.reportData ??= {}; binding.reportData!['testResults'] = { diff --git a/packages/cloud_functions/cloud_functions/example/integration_test/sample_data.dart b/packages/cloud_functions/cloud_functions/example/integration_test/sample_data.dart index acf390931a17..ef8fa834d29a 100644 --- a/packages/cloud_functions/cloud_functions/example/integration_test/sample_data.dart +++ b/packages/cloud_functions/cloud_functions/example/integration_test/sample_data.dart @@ -18,8 +18,4 @@ Map deepMap = { 'map': map, }; -List deepList = [ - ...list, - list, - map, -]; +List deepList = [...list, list, map]; diff --git a/packages/cloud_functions/cloud_functions/example/lib/firebase_options.dart b/packages/cloud_functions/cloud_functions/example/lib/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/cloud_functions/cloud_functions/example/lib/firebase_options.dart +++ b/packages/cloud_functions/cloud_functions/example/lib/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/cloud_functions/cloud_functions/example/lib/main.dart b/packages/cloud_functions/cloud_functions/example/lib/main.dart index 00f397f66d8c..d6ad048e673c 100644 --- a/packages/cloud_functions/cloud_functions/example/lib/main.dart +++ b/packages/cloud_functions/cloud_functions/example/lib/main.dart @@ -14,9 +14,7 @@ import 'package:flutter/material.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); + await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); // You should have the Functions Emulator running locally to use it // https://firebase.google.com/docs/functions/local-emulator @@ -47,36 +45,35 @@ class _MyAppState extends State { .httpsCallable('testStreamResponse') .stream>() .listen( - (data) { - switch (data) { - case Chunk>(:final partialData): - setState(() { - // adds individual stream values to list - fruit.add(partialData); - }); - case Result>(:final result): - setState(() { - // stores complete stream result - streamResult = List.from(result.data); - }); - } - }, - onError: (e) { - debugPrint('Error: $e'); - }, - ); + (data) { + switch (data) { + case Chunk>(:final partialData): + setState(() { + // adds individual stream values to list + fruit.add(partialData); + }); + case Result>(:final result): + setState(() { + // stores complete stream result + streamResult = List.from(result.data); + }); + } + }, + onError: (e) { + debugPrint('Error: $e'); + }, + ); } @override Widget build(BuildContext context) { - final localhostMapped = - kIsWeb || !Platform.isAndroid ? 'localhost' : '10.0.2.2'; + final localhostMapped = kIsWeb || !Platform.isAndroid + ? 'localhost' + : '10.0.2.2'; return MaterialApp( home: Scaffold( - appBar: AppBar( - title: const Text('Firebase Functions Example'), - ), + appBar: AppBar(title: const Text('Firebase Functions Example')), body: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -84,9 +81,7 @@ class _MyAppState extends State { child: ListView.builder( itemCount: fruit.length, itemBuilder: (context, index) { - return ListTile( - title: Text('${fruit[index]}'), - ); + return ListTile(title: Text('${fruit[index]}')); }, ), ), @@ -94,18 +89,14 @@ class _MyAppState extends State { visible: streamResult.isNotEmpty, child: const Text( "Stream's Complete Result: ", - style: TextStyle( - fontWeight: FontWeight.bold, - ), + style: TextStyle(fontWeight: FontWeight.bold), ), ), Expanded( child: ListView.builder( itemCount: streamResult.length, itemBuilder: (context, index) { - return ListTile( - title: Text('${streamResult[index]}'), - ); + return ListTile(title: Text('${streamResult[index]}')); }, ), ), @@ -128,13 +119,13 @@ class _MyAppState extends State { onPressed: () async { // See .github/workflows/scripts/functions/src/index.ts for the example function we // are using for this example - HttpsCallable callable = - FirebaseFunctions.instance.httpsCallable( - 'listFruit', - options: HttpsCallableOptions( - timeout: const Duration(seconds: 5), - ), - ); + HttpsCallable callable = FirebaseFunctions.instance + .httpsCallable( + 'listFruit', + options: HttpsCallableOptions( + timeout: const Duration(seconds: 5), + ), + ); await callingFunction(callable, context); }, @@ -147,8 +138,8 @@ class _MyAppState extends State { onPressed: () async { // See .github/workflows/scripts/functions/src/index.ts for the example function we // are using for this example - HttpsCallable callable = - FirebaseFunctions.instance.httpsCallableFromUrl( + HttpsCallable + callable = FirebaseFunctions.instance.httpsCallableFromUrl( 'http://$localhostMapped:5001/flutterfire-e2e-tests/us-central1/listfruits2ndgen', options: HttpsCallableOptions( timeout: const Duration(seconds: 5), @@ -183,11 +174,9 @@ class _MyAppState extends State { }); }); } catch (e) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text('ERROR: $e'), - ), - ); + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('ERROR: $e'))); } } } diff --git a/packages/cloud_functions/cloud_functions/example/pubspec.yaml b/packages/cloud_functions/cloud_functions/example/pubspec.yaml index 6e8525a294f4..e8a24660d78e 100644 --- a/packages/cloud_functions/cloud_functions/example/pubspec.yaml +++ b/packages/cloud_functions/cloud_functions/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the cloud_functions plugin. resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: cloud_functions: ^6.4.0 diff --git a/packages/cloud_functions/cloud_functions/example/test_driver/integration_test.dart b/packages/cloud_functions/cloud_functions/example/test_driver/integration_test.dart index 691723cbbfe1..9ccbcc26ab97 100644 --- a/packages/cloud_functions/cloud_functions/example/test_driver/integration_test.dart +++ b/packages/cloud_functions/cloud_functions/example/test_driver/integration_test.dart @@ -7,28 +7,32 @@ import 'dart:io'; import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver( - writeResponseOnFailure: true, - responseDataCallback: (Map? data) async { - final results = - (data?['testResults'] as Map?)?.cast() ?? - const {}; - var passed = 0; - var failed = 0; - for (final entry in results.entries) { - final ok = entry.value == 'success'; - ok ? passed++ : failed++; - // ignore: avoid_print - print('${ok ? '✅' : '❌'} ${entry.key}'); - } - // ignore: avoid_print - print('Web e2e summary: $passed passed, $failed failed, ' - '${results.length} total'); - if (results.isEmpty) { - // ignore: avoid_print - print('[E] No tests reported by the app - treating as ' - 'infrastructure failure.'); - exit(1); - } - await writeResponseData(data); - }, + writeResponseOnFailure: true, + responseDataCallback: (Map? data) async { + final results = + (data?['testResults'] as Map?)?.cast() ?? + const {}; + var passed = 0; + var failed = 0; + for (final entry in results.entries) { + final ok = entry.value == 'success'; + ok ? passed++ : failed++; + // ignore: avoid_print + print('${ok ? '✅' : '❌'} ${entry.key}'); + } + // ignore: avoid_print + print( + 'Web e2e summary: $passed passed, $failed failed, ' + '${results.length} total', ); + if (results.isEmpty) { + // ignore: avoid_print + print( + '[E] No tests reported by the app - treating as ' + 'infrastructure failure.', + ); + exit(1); + } + await writeResponseData(data); + }, +); diff --git a/packages/cloud_functions/cloud_functions/lib/src/firebase_functions.dart b/packages/cloud_functions/cloud_functions/lib/src/firebase_functions.dart index aef9a37c036a..8b07cdb13445 100644 --- a/packages/cloud_functions/cloud_functions/lib/src/firebase_functions.dart +++ b/packages/cloud_functions/cloud_functions/lib/src/firebase_functions.dart @@ -10,8 +10,8 @@ part of '../cloud_functions.dart'; /// You can get an instance by calling [FirebaseFunctions.instance]. class FirebaseFunctions extends FirebasePlugin { FirebaseFunctions._({required this.app, String? region}) - : _region = region ??= 'us-central1', - super(app.name, 'plugins.flutter.io/firebase_functions'); + : _region = region ??= 'us-central1', + super(app.name, 'plugins.flutter.io/firebase_functions'); // Cached and lazily loaded instance of [FirebaseFunctionsPlatform] to avoid // creating a [MethodChannelFirebaseFunctions] when not needed or creating an @@ -22,8 +22,10 @@ class FirebaseFunctions extends FirebasePlugin { /// [FirebaseFunctions] instance. This is useful for testing purposes only. @visibleForTesting FirebaseFunctionsPlatform get delegate { - return _delegatePackingProperty ??= - FirebaseFunctionsPlatform.instanceFor(app: app, region: _region); + return _delegatePackingProperty ??= FirebaseFunctionsPlatform.instanceFor( + app: app, + region: _region, + ); } /// The [FirebaseApp] for this current [FirebaseFunctions] instance. @@ -33,9 +35,7 @@ class FirebaseFunctions extends FirebasePlugin { /// Returns an instance using the default [FirebaseApp] and region. static FirebaseFunctions get instance { - return FirebaseFunctions.instanceFor( - app: Firebase.app(), - ); + return FirebaseFunctions.instanceFor(app: Firebase.app()); } /// Returns an instance using a specified [FirebaseApp] & region. @@ -48,8 +48,10 @@ class FirebaseFunctions extends FirebasePlugin { return _cachedInstances[cachedKey]!; } - FirebaseFunctions newInstance = - FirebaseFunctions._(app: app, region: region); + FirebaseFunctions newInstance = FirebaseFunctions._( + app: app, + region: region, + ); _cachedInstances[cachedKey] = newInstance; return newInstance; @@ -62,10 +64,7 @@ class FirebaseFunctions extends FirebasePlugin { /// A reference to the Callable HTTPS trigger with the given name. /// /// Should be the name of the Callable function in Firebase - HttpsCallable httpsCallable( - String name, { - HttpsCallableOptions? options, - }) { + HttpsCallable httpsCallable(String name, {HttpsCallableOptions? options}) { assert(name.isNotEmpty); options ??= HttpsCallableOptions(); return HttpsCallable._(delegate.httpsCallable(_origin, name, options)); @@ -81,27 +80,29 @@ class FirebaseFunctions extends FirebasePlugin { final uri = Uri.parse(url); options ??= HttpsCallableOptions(); return HttpsCallable._( - delegate.httpsCallableWithUri(_origin, uri, options)); + delegate.httpsCallableWithUri(_origin, uri, options), + ); } /// A reference to the Callable HTTPS trigger with the given Uri. /// /// Should be Uri of the 2nd gen Callable function in Firebase. - HttpsCallable httpsCallableFromUri( - Uri uri, { - HttpsCallableOptions? options, - }) { + HttpsCallable httpsCallableFromUri(Uri uri, {HttpsCallableOptions? options}) { options ??= HttpsCallableOptions(); return HttpsCallable._( - delegate.httpsCallableWithUri(_origin, uri, options)); + delegate.httpsCallableWithUri(_origin, uri, options), + ); } /// Changes this instance to point to a Cloud Functions emulator running locally. /// /// Set the [host] of the local emulator, such as "localhost" /// Set the [port] of the local emulator, such as "5001" (port 5001 is default for functions package) - void useFunctionsEmulator(String host, int port, - {bool automaticHostMapping = true}) { + void useFunctionsEmulator( + String host, + int port, { + bool automaticHostMapping = true, + }) { String mappedHost = host; // Android considers localhost as 10.0.2.2 - automatically handle this for users. if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) { diff --git a/packages/cloud_functions/cloud_functions/pubspec.yaml b/packages/cloud_functions/cloud_functions/pubspec.yaml index b02a8dfc15df..8a34cc1d5033 100644 --- a/packages/cloud_functions/cloud_functions/pubspec.yaml +++ b/packages/cloud_functions/cloud_functions/pubspec.yaml @@ -14,8 +14,8 @@ false_secrets: - example/** environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: cloud_functions_platform_interface: ^6.0.7 diff --git a/packages/cloud_functions/cloud_functions/test/firebase_functions_test.dart b/packages/cloud_functions/cloud_functions/test/firebase_functions_test.dart index b3a870044019..8929961ecb78 100644 --- a/packages/cloud_functions/cloud_functions/test/firebase_functions_test.dart +++ b/packages/cloud_functions/cloud_functions/test/firebase_functions_test.dart @@ -15,21 +15,26 @@ void main() { setUp(() async { resetFirebaseCoreMocks(); await Firebase.initializeApp(); - FirebaseFunctionsPlatform.instance = - MockFirebaseFunctionsPlatform(region: 'us-central1'); + FirebaseFunctionsPlatform.instance = MockFirebaseFunctionsPlatform( + region: 'us-central1', + ); }); group('FirebaseFunctions', () { group('.instance', () { test('uses the default FirebaseApp instance', () { expect(FirebaseFunctions.instance.app, isA()); - expect(FirebaseFunctions.instance.app.name, - equals(defaultFirebaseAppName)); + expect( + FirebaseFunctions.instance.app.name, + equals(defaultFirebaseAppName), + ); }); test('uses the default Functions region', () { expect( - FirebaseFunctions.instance.delegate.region, equals('us-central1')); + FirebaseFunctions.instance.delegate.region, + equals('us-central1'), + ); }); }); @@ -51,24 +56,30 @@ void main() { }); test('accepts a secondary FirebaseApp instance', () async { - FirebaseFunctions functionsSecondary = - FirebaseFunctions.instanceFor(app: secondaryApp); - expect(functionsSecondary.app, isA()); - expect(functionsSecondary.app.name, secondaryApp!.name); - }); - - test('accepts a secondary FirebaseApp instance and custom region', - () async { FirebaseFunctions functionsSecondary = FirebaseFunctions.instanceFor( - app: secondaryApp, region: 'europe-west1'); + app: secondaryApp, + ); expect(functionsSecondary.app, isA()); expect(functionsSecondary.app.name, secondaryApp!.name); - expect(functionsSecondary.delegate.region, equals('europe-west1')); }); + test( + 'accepts a secondary FirebaseApp instance and custom region', + () async { + FirebaseFunctions functionsSecondary = FirebaseFunctions.instanceFor( + app: secondaryApp, + region: 'europe-west1', + ); + expect(functionsSecondary.app, isA()); + expect(functionsSecondary.app.name, secondaryApp!.name); + expect(functionsSecondary.delegate.region, equals('europe-west1')); + }, + ); + test('accepts a custom region for the default app', () async { - FirebaseFunctions functions = - FirebaseFunctions.instanceFor(region: 'europe-west1'); + FirebaseFunctions functions = FirebaseFunctions.instanceFor( + region: 'europe-west1', + ); expect(functions.app, isA()); expect(functions.app.name, defaultFirebaseAppName); expect(functions.delegate.region, equals('europe-west1')); @@ -76,20 +87,25 @@ void main() { test('caches instances by FirebaseApp and region', () async { // Instances using the same region and FirebaseApp should be identical. - FirebaseFunctions functions1 = - FirebaseFunctions.instanceFor(region: 'europe-west1'); - FirebaseFunctions functions2 = - FirebaseFunctions.instanceFor(region: 'europe-west1'); + FirebaseFunctions functions1 = FirebaseFunctions.instanceFor( + region: 'europe-west1', + ); + FirebaseFunctions functions2 = FirebaseFunctions.instanceFor( + region: 'europe-west1', + ); expect(functions1, same(functions2)); // Instances using the same region but a different FirebaseApp should not be identical. FirebaseFunctions functions3 = FirebaseFunctions.instanceFor( - app: secondaryApp, region: 'europe-west1'); + app: secondaryApp, + region: 'europe-west1', + ); expect(functions1, isNot(same(functions3))); // Instances using the same FirebaseApp but a different region should not be identical. - FirebaseFunctions functions4 = - FirebaseFunctions.instanceFor(region: 'europe-west2'); + FirebaseFunctions functions4 = FirebaseFunctions.instanceFor( + region: 'europe-west2', + ); expect(functions1, isNot(same(functions4))); }); }); @@ -97,34 +113,39 @@ void main() { group('.useEmulator()', () { test('passes emulator "origin" through to the delegate', () { // Check null by default. - expect(FirebaseFunctions.instance.httpsCallable('test').delegate.origin, - isNull); + expect( + FirebaseFunctions.instance.httpsCallable('test').delegate.origin, + isNull, + ); // Set the origin for the default FirebaseFunctions instance. FirebaseFunctions.instance.useFunctionsEmulator('0.0.0.0', 5000); - expect(FirebaseFunctions.instance.httpsCallable('test').delegate.origin, - equals('http://0.0.0.0:5000')); - }); - - test('"origin" is only set for the specific FirebaseFunctions instance', - () { - FirebaseFunctions.instance.useFunctionsEmulator('0.0.0.0', 5000); - // Origin on the default FirebaseFunctions instance should be set. - expect(FirebaseFunctions.instance.httpsCallable('test').delegate.origin, - equals('http://0.0.0.0:5000')); - // Origin on a secondary FirebaseFunctions instance should remain unset/null. expect( - FirebaseFunctions.instanceFor(region: 'europe-west1') - .httpsCallable('test') - .delegate - .origin, - isNull); + FirebaseFunctions.instance.httpsCallable('test').delegate.origin, + equals('http://0.0.0.0:5000'), + ); }); + test( + '"origin" is only set for the specific FirebaseFunctions instance', + () { + FirebaseFunctions.instance.useFunctionsEmulator('0.0.0.0', 5000); + // Origin on the default FirebaseFunctions instance should be set. + expect( + FirebaseFunctions.instance.httpsCallable('test').delegate.origin, + equals('http://0.0.0.0:5000'), + ); + // Origin on a secondary FirebaseFunctions instance should remain unset/null. + expect( + FirebaseFunctions.instanceFor( + region: 'europe-west1', + ).httpsCallable('test').delegate.origin, + isNull, + ); + }, + ); + test('handles "localhost" and "127.0.0.1" origin only for Android', () { - const testLocalhostOrigins = [ - '127.0.0.1', - 'localhost', - ]; + const testLocalhostOrigins = ['127.0.0.1', 'localhost']; for (final platform in TargetPlatform.values) { debugDefaultTargetPlatformOverride = platform; @@ -137,11 +158,9 @@ void main() { FirebaseFunctions.instance.useFunctionsEmulator(testOrigin, 5000); // Origin on the default FirebaseFunctions instance should be set. expect( - FirebaseFunctions.instance - .httpsCallable('test') - .delegate - .origin, - equals(expectedOrigin)); + FirebaseFunctions.instance.httpsCallable('test').delegate.origin, + equals(expectedOrigin), + ); } } }); @@ -155,20 +174,27 @@ void main() { }); test('passes "name" through to delegate', () { - expect(FirebaseFunctions.instance.httpsCallable('foo').delegate.name, - equals('foo')); + expect( + FirebaseFunctions.instance.httpsCallable('foo').delegate.name, + equals('foo'), + ); }); test('provides default "options" if none provided', () { - expect(FirebaseFunctions.instance.httpsCallable('foo').delegate.options, - isNotNull); + expect( + FirebaseFunctions.instance.httpsCallable('foo').delegate.options, + isNotNull, + ); }); test('passes custom "options" through to the delegate', () { HttpsCallablePlatform delegate = FirebaseFunctions.instance - .httpsCallable('foo', - options: HttpsCallableOptions( - timeout: const Duration(seconds: 1337))) + .httpsCallable( + 'foo', + options: HttpsCallableOptions( + timeout: const Duration(seconds: 1337), + ), + ) .delegate; expect(delegate.options, isNotNull); expect(delegate.options.timeout, isA()); diff --git a/packages/cloud_functions/cloud_functions/test/https_callable_test.dart b/packages/cloud_functions/cloud_functions/test/https_callable_test.dart index 8a9224ad470a..936b6dd640a5 100644 --- a/packages/cloud_functions/cloud_functions/test/https_callable_test.dart +++ b/packages/cloud_functions/cloud_functions/test/https_callable_test.dart @@ -19,8 +19,9 @@ void main() { setUp(() async { resetFirebaseCoreMocks(); await Firebase.initializeApp(); - FirebaseFunctionsPlatform.instance = - MockFirebaseFunctionsPlatform(region: 'us-central1'); + FirebaseFunctionsPlatform.instance = MockFirebaseFunctionsPlatform( + region: 'us-central1', + ); httpsCallable = FirebaseFunctions.instance.httpsCallable('foo'); }); @@ -32,13 +33,7 @@ void main() { test('parameter validation accepts string values', () async { final result = await httpsCallable!.call('foo'); - expect( - result.data, - allOf( - isA(), - equals('foo'), - ), - ); + expect(result.data, allOf(isA(), equals('foo'))); }); test('parameter validation accepts numeric values', () async { @@ -55,67 +50,45 @@ void main() { test('parameter validation accepts List values', () async { final result = await httpsCallable!.call(data.list); - expect( - result.data, - allOf( - isA(), - equals(data.list), - ), - ); + expect(result.data, allOf(isA(), equals(data.list))); }); test('parameter validation accepts nested List values', () async { final result = await httpsCallable!.call(data.deepList); - expect( - result.data, - allOf( - isA(), - equals(data.deepList), - ), - ); + expect(result.data, allOf(isA(), equals(data.deepList))); }); test('parameter validation accepts Map values', () async { final result = await httpsCallable!.call(data.map); - expect( - result.data, - allOf( - isA(), - equals(data.map), - ), - ); + expect(result.data, allOf(isA(), equals(data.map))); }); test('parameter validation accepts nested Map values', () async { final result = await httpsCallable!.call(data.deepMap); - expect( - result.data, - allOf( - isA(), - equals(data.deepMap), - ), - ); + expect(result.data, allOf(isA(), equals(data.deepMap))); }); - test('converts typed data lists in map values to regular lists', - () async { - final result = await httpsCallable!.call({ - 'bytes': Uint8List.fromList([1, 2, 3]), - 'ints': Int32List.fromList([4, 5, 6]), - 'floats': Float32List.fromList([1.0, 2.0]), - 'doubles': Float64List.fromList([3.0, 4.0]), - }); - final data = result.data as Map; - expect(data['bytes'], isA>()); - expect(data['bytes'], isNot(isA())); - expect(data['bytes'], equals([1, 2, 3])); - expect(data['ints'], isA>()); - expect(data['ints'], isNot(isA())); - expect(data['floats'], isA>()); - expect(data['floats'], isNot(isA())); - expect(data['doubles'], isA>()); - expect(data['doubles'], isNot(isA())); - }); + test( + 'converts typed data lists in map values to regular lists', + () async { + final result = await httpsCallable!.call({ + 'bytes': Uint8List.fromList([1, 2, 3]), + 'ints': Int32List.fromList([4, 5, 6]), + 'floats': Float32List.fromList([1.0, 2.0]), + 'doubles': Float64List.fromList([3.0, 4.0]), + }); + final data = result.data as Map; + expect(data['bytes'], isA>()); + expect(data['bytes'], isNot(isA())); + expect(data['bytes'], equals([1, 2, 3])); + expect(data['ints'], isA>()); + expect(data['ints'], isNot(isA())); + expect(data['floats'], isA>()); + expect(data['floats'], isNot(isA())); + expect(data['doubles'], isA>()); + expect(data['doubles'], isNot(isA())); + }, + ); test('converts typed data lists passed as direct parameters', () async { final result = await httpsCallable!.call(Uint8List.fromList([7, 8, 9])); @@ -136,23 +109,25 @@ void main() { expect(data[1], isNot(isA())); }); - test('parameter validation throws if any other type of data is passed', - () async { - expect(() { - return httpsCallable!.call(() => {}); - }, throwsA(isA())); - - // Check nested values in Lists or Maps also throw if invalid: - expect(() { - return httpsCallable!.call({ - 'valid': 'hello world', - 'not_valid': () => {}, - }); - }, throwsA(isA())); - expect(() { - return httpsCallable!.call(['valid', () => {}]); - }, throwsA(isA())); - }); + test( + 'parameter validation throws if any other type of data is passed', + () async { + expect(() { + return httpsCallable!.call(() => {}); + }, throwsA(isA())); + + // Check nested values in Lists or Maps also throw if invalid: + expect(() { + return httpsCallable!.call({ + 'valid': 'hello world', + 'not_valid': () => {}, + }); + }, throwsA(isA())); + expect(() { + return httpsCallable!.call(['valid', () => {}]); + }, throwsA(isA())); + }, + ); }); }); } diff --git a/packages/cloud_functions/cloud_functions/test/mock.dart b/packages/cloud_functions/cloud_functions/test/mock.dart index aa9a67961ece..08d3b93effae 100644 --- a/packages/cloud_functions/cloud_functions/test/mock.dart +++ b/packages/cloud_functions/cloud_functions/test/mock.dart @@ -29,9 +29,13 @@ void resetFirebaseCoreMocks() { } class MockHttpsCallablePlatform extends HttpsCallablePlatform { - MockHttpsCallablePlatform(FirebaseFunctionsPlatform functions, String? origin, - String? name, HttpsCallableOptions options, Uri? uri) - : super(functions, origin, name, options, uri); + MockHttpsCallablePlatform( + FirebaseFunctionsPlatform functions, + String? origin, + String? name, + HttpsCallableOptions options, + Uri? uri, + ) : super(functions, origin, name, options, uri); @override Future call([dynamic parameters]) async { @@ -42,27 +46,45 @@ class MockHttpsCallablePlatform extends HttpsCallablePlatform { class MockFirebaseFunctionsPlatform extends FirebaseFunctionsPlatform { MockFirebaseFunctionsPlatform({FirebaseApp? app, required String region}) - : super(app, region); + : super(app, region); @override HttpsCallablePlatform httpsCallable( - String? origin, String name, HttpsCallableOptions options) { - HttpsCallablePlatform httpsCallablePlatform = - MockHttpsCallablePlatform(this, origin, name, options, null); + String? origin, + String name, + HttpsCallableOptions options, + ) { + HttpsCallablePlatform httpsCallablePlatform = MockHttpsCallablePlatform( + this, + origin, + name, + options, + null, + ); return httpsCallablePlatform; } @override HttpsCallablePlatform httpsCallableWithUri( - String? origin, Uri uri, HttpsCallableOptions options) { - HttpsCallablePlatform httpsCallablePlatform = - MockHttpsCallablePlatform(this, origin, null, options, uri); + String? origin, + Uri uri, + HttpsCallableOptions options, + ) { + HttpsCallablePlatform httpsCallablePlatform = MockHttpsCallablePlatform( + this, + origin, + null, + options, + uri, + ); return httpsCallablePlatform; } @override - FirebaseFunctionsPlatform delegateFor( - {FirebaseApp? app, required String region}) { + FirebaseFunctionsPlatform delegateFor({ + FirebaseApp? app, + required String region, + }) { MockFirebaseFunctionsPlatform functionsPlatform = MockFirebaseFunctionsPlatform(app: app, region: region); return functionsPlatform; diff --git a/packages/cloud_functions/cloud_functions/test/sample.dart b/packages/cloud_functions/cloud_functions/test/sample.dart index 58fd5ca81e0b..c88346218808 100644 --- a/packages/cloud_functions/cloud_functions/test/sample.dart +++ b/packages/cloud_functions/cloud_functions/test/sample.dart @@ -13,12 +13,6 @@ Map map = { List list = ['1', 2, true, false]; -Map deepMap = { - 'list': list, - 'map': map, -}; +Map deepMap = {'list': list, 'map': map}; -List deepList = [ - list, - map, -]; +List deepList = [list, map]; diff --git a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/firebase_functions_exception.dart b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/firebase_functions_exception.dart index cd89025a9d7d..d529bc893d3a 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/firebase_functions_exception.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/firebase_functions_exception.dart @@ -18,10 +18,11 @@ class FirebaseFunctionsException extends FirebaseException StackTrace? stackTrace, this.details, }) : super( - plugin: 'firebase_functions', - message: message, - code: code, - stackTrace: stackTrace); + plugin: 'firebase_functions', + message: message, + code: code, + stackTrace: stackTrace, + ); /// Additional data provided with the exception. final dynamic details; diff --git a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/https_callable_options.dart b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/https_callable_options.dart index 69e154f8b22e..849cdafddc50 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/https_callable_options.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/https_callable_options.dart @@ -8,10 +8,11 @@ class HttpsCallableOptions { /// Constructs a new [HttpsCallableOptions] instance with given `timeout` & `limitedUseAppCheckToken` /// Defaults [timeout] to 60 seconds. /// Defaults [limitedUseAppCheckToken] to `false` - HttpsCallableOptions( - {this.timeout = const Duration(seconds: 60), - this.limitedUseAppCheckToken = false, - this.webAbortSignal}); + HttpsCallableOptions({ + this.timeout = const Duration(seconds: 60), + this.limitedUseAppCheckToken = false, + this.webAbortSignal, + }); /// Returns the timeout for this instance Duration timeout; diff --git a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/method_channel_firebase_functions.dart b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/method_channel_firebase_functions.dart index 12bf6769bc98..5ed63703e451 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/method_channel_firebase_functions.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/method_channel_firebase_functions.dart @@ -15,7 +15,7 @@ class MethodChannelFirebaseFunctions extends FirebaseFunctionsPlatform { /// Creates a new [MethodChannelFirebaseFunctions] instance with an [app] and/or /// [region]. MethodChannelFirebaseFunctions({FirebaseApp? app, required String region}) - : super(app, region); + : super(app, region); /// Internal stub class initializer. /// @@ -37,20 +37,28 @@ class MethodChannelFirebaseFunctions extends FirebaseFunctionsPlatform { static final pigeonChannel = CloudFunctionsHostApi(); @override - FirebaseFunctionsPlatform delegateFor( - {FirebaseApp? app, required String region}) { + FirebaseFunctionsPlatform delegateFor({ + FirebaseApp? app, + required String region, + }) { return MethodChannelFirebaseFunctions(app: app, region: region); } @override HttpsCallablePlatform httpsCallable( - String? origin, String name, HttpsCallableOptions options) { + String? origin, + String name, + HttpsCallableOptions options, + ) { return MethodChannelHttpsCallable(this, origin, name, options, null); } @override HttpsCallablePlatform httpsCallableWithUri( - String? origin, Uri uri, HttpsCallableOptions options) { + String? origin, + Uri uri, + HttpsCallableOptions options, + ) { return MethodChannelHttpsCallable(this, origin, null, options, uri); } } diff --git a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/method_channel_https_callable.dart b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/method_channel_https_callable.dart index 41f51be90557..4c2568eb601d 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/method_channel_https_callable.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/method_channel_https_callable.dart @@ -26,11 +26,15 @@ dynamic _convertNested(Object? value) { /// Method Channel delegate for [HttpsCallablePlatform]. class MethodChannelHttpsCallable extends HttpsCallablePlatform { /// Creates a new [MethodChannelHttpsCallable] instance. - MethodChannelHttpsCallable(FirebaseFunctionsPlatform functions, - String? origin, String? name, HttpsCallableOptions options, Uri? uri) - : _baseEventChannelId = - name ?? uri?.pathSegments.join('_').replaceAll('.', '_') ?? '', - super(functions, origin, name, options, uri); + MethodChannelHttpsCallable( + FirebaseFunctionsPlatform functions, + String? origin, + String? name, + HttpsCallableOptions options, + Uri? uri, + ) : _baseEventChannelId = + name ?? uri?.pathSegments.join('_').replaceAll('.', '_') ?? '', + super(functions, origin, name, options, uri); static int _streamIdCounter = 0; final String _baseEventChannelId; @@ -40,15 +44,15 @@ class MethodChannelHttpsCallable extends HttpsCallablePlatform { try { Object? result = await MethodChannelFirebaseFunctions.pigeonChannel .call({ - 'appName': functions.app!.name, - 'functionName': name, - 'functionUri': uri?.toString(), - 'origin': origin, - 'region': functions.region, - 'timeout': options.timeout.inMilliseconds, - 'parameters': parameters, - 'limitedUseAppCheckToken': options.limitedUseAppCheckToken, - }); + 'appName': functions.app!.name, + 'functionName': name, + 'functionUri': uri?.toString(), + 'origin': origin, + 'region': functions.region, + 'timeout': options.timeout.inMilliseconds, + 'parameters': parameters, + 'limitedUseAppCheckToken': options.limitedUseAppCheckToken, + }); return _convertNested(result); } catch (e, s) { @@ -61,15 +65,16 @@ class MethodChannelHttpsCallable extends HttpsCallablePlatform { // Each stream() call gets a unique channel ID to prevent collisions // when invoking the same function concurrently. See #18036. final eventChannelId = '${_baseEventChannelId}_${_streamIdCounter++}'; - final channel = - EventChannel('plugins.flutter.io/firebase_functions/$eventChannelId'); + final channel = EventChannel( + 'plugins.flutter.io/firebase_functions/$eventChannelId', + ); try { await MethodChannelFirebaseFunctions.pigeonChannel .registerEventChannel({ - 'eventChannelId': eventChannelId, - 'appName': functions.app!.name, - 'region': functions.region, - }); + 'eventChannelId': eventChannelId, + 'appName': functions.app!.name, + 'region': functions.region, + }); final eventData = { 'functionName': name, 'functionUri': uri?.toString(), diff --git a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/pigeon/messages.pigeon.dart b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/pigeon/messages.pigeon.dart index ed2a18de54a0..0767d08be8ae 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/pigeon/messages.pigeon.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/pigeon/messages.pigeon.dart @@ -37,8 +37,11 @@ Object? _extractReplyValueOrThrow( return replyList.firstOrNull; } -List wrapResponse( - {Object? result, PlatformException? error, bool empty = false}) { +List wrapResponse({ + Object? result, + PlatformException? error, + bool empty = false, +}) { if (empty) { return []; } @@ -73,11 +76,13 @@ class CloudFunctionsHostApi { /// Constructor for [CloudFunctionsHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - CloudFunctionsHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + CloudFunctionsHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -92,8 +97,9 @@ class CloudFunctionsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([arguments]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [arguments], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -112,8 +118,9 @@ class CloudFunctionsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([arguments]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [arguments], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( diff --git a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/platform_interface/platform_interface_firebase_functions.dart b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/platform_interface/platform_interface_firebase_functions.dart index d9eac236d341..55364825f021 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/platform_interface/platform_interface_firebase_functions.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/platform_interface/platform_interface_firebase_functions.dart @@ -23,10 +23,14 @@ abstract class FirebaseFunctionsPlatform extends PlatformInterface { FirebaseFunctionsPlatform(this.app, this.region) : super(token: _token); /// Create an instance using [app] using the existing implementation - factory FirebaseFunctionsPlatform.instanceFor( - {FirebaseApp? app, required String region}) { - return FirebaseFunctionsPlatform.instance - .delegateFor(app: app, region: region); + factory FirebaseFunctionsPlatform.instanceFor({ + FirebaseApp? app, + required String region, + }) { + return FirebaseFunctionsPlatform.instance.delegateFor( + app: app, + region: region, + ); } static final Object _token = Object(); @@ -56,20 +60,28 @@ abstract class FirebaseFunctionsPlatform extends PlatformInterface { /// Enables delegates to create new instances of themselves if a none default /// [FirebaseApp] instance or region is required by the user. @protected - FirebaseFunctionsPlatform delegateFor( - {FirebaseApp? app, required String region}) { + FirebaseFunctionsPlatform delegateFor({ + FirebaseApp? app, + required String region, + }) { throw UnimplementedError('delegateFor() is not implemented'); } /// Creates a [HttpsCallablePlatform] instance HttpsCallablePlatform httpsCallable( - String? origin, String name, HttpsCallableOptions options) { + String? origin, + String name, + HttpsCallableOptions options, + ) { throw UnimplementedError('httpsCallable() is not implemented'); } /// Creates a [HttpsCallablePlatform] instance from a [Uri] HttpsCallablePlatform httpsCallableWithUri( - String? origin, Uri uri, HttpsCallableOptions options) { + String? origin, + Uri uri, + HttpsCallableOptions options, + ) { throw UnimplementedError('httpsCallableWithUri() is not implemented'); } } diff --git a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/platform_interface/platform_interface_https_callable.dart b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/platform_interface/platform_interface_https_callable.dart index be287c7a9571..c37bf98b8983 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/platform_interface/platform_interface_https_callable.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/platform_interface/platform_interface_https_callable.dart @@ -20,8 +20,8 @@ abstract class HttpsCallablePlatform extends PlatformInterface { this.name, this.options, this.uri, - ) : assert(name != null || uri != null), - super(token: _token); + ) : assert(name != null || uri != null), + super(token: _token); static final Object _token = Object(); diff --git a/packages/cloud_functions/cloud_functions_platform_interface/pubspec.yaml b/packages/cloud_functions/cloud_functions_platform_interface/pubspec.yaml index a83b4c1607ab..bb30f04a6913 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/pubspec.yaml +++ b/packages/cloud_functions/cloud_functions_platform_interface/pubspec.yaml @@ -9,8 +9,8 @@ version: 6.0.7 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core: ^4.14.0 diff --git a/packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/method_channel_firebase_functions_test.dart b/packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/method_channel_firebase_functions_test.dart index f6bafb45888d..fb2cf7f1bdf8 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/method_channel_firebase_functions_test.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/method_channel_firebase_functions_test.dart @@ -21,13 +21,17 @@ void main() { setUpAll(() async { app = await Firebase.initializeApp(); - functions = - MethodChannelFirebaseFunctions(app: app, region: 'us-central1'); + functions = MethodChannelFirebaseFunctions( + app: app, + region: 'us-central1', + ); }); test('channel', () { - expect(MethodChannelFirebaseFunctions.channel.name, - 'plugins.flutter.io/firebase_functions'); + expect( + MethodChannelFirebaseFunctions.channel.name, + 'plugins.flutter.io/firebase_functions', + ); }); test('instance', () { @@ -38,10 +42,14 @@ void main() { }); test('delegateFor', () { - final testFunctions = - TestMethodChannelFirebaseFunctions(app: app, region: 'us-central1'); - final result = - testFunctions.delegateFor(app: app, region: 'europe-west1'); + final testFunctions = TestMethodChannelFirebaseFunctions( + app: app, + region: 'us-central1', + ); + final result = testFunctions.delegateFor( + app: app, + region: 'europe-west1', + ); expect(result, isA()); expect(result.app, isA()); expect(result.app, equals(app)); @@ -51,8 +59,11 @@ void main() { test('httpsCallable', () { const testOrigin = 'http://localhost:5000'; const testFunctionName = 'test_function_name'; - final callable = functions! - .httpsCallable(testOrigin, testFunctionName, HttpsCallableOptions()); + final callable = functions!.httpsCallable( + testOrigin, + testFunctionName, + HttpsCallableOptions(), + ); expect(callable, isA()); expect(callable.origin, equals(testOrigin)); expect(callable.name, equals(testFunctionName)); @@ -63,5 +74,5 @@ void main() { class TestMethodChannelFirebaseFunctions extends MethodChannelFirebaseFunctions { TestMethodChannelFirebaseFunctions({FirebaseApp? app, required String region}) - : super(app: app, region: region); + : super(app: app, region: region); } diff --git a/packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/method_channel_https_callable_test.dart b/packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/method_channel_https_callable_test.dart index 50c92849d903..1c9c5018fd4b 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/method_channel_https_callable_test.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/method_channel_https_callable_test.dart @@ -32,18 +32,24 @@ void main() { setUpAll(() async { FirebaseApp app = await Firebase.initializeApp(); - TestCloudFunctionsHostApi.setUp(_TestCloudFunctionsHostApi(() async { - if (mockExceptionThrown) { - throw Exception(); - } else if (mockPlatformExceptionThrown) { - throw PlatformException( - code: 'UNKNOWN', message: kPlatformExceptionMessage); - } - return kParameters; - })); - - functions = - MethodChannelFirebaseFunctions(app: app, region: 'us-central1'); + TestCloudFunctionsHostApi.setUp( + _TestCloudFunctionsHostApi(() async { + if (mockExceptionThrown) { + throw Exception(); + } else if (mockPlatformExceptionThrown) { + throw PlatformException( + code: 'UNKNOWN', + message: kPlatformExceptionMessage, + ); + } + return kParameters; + }), + ); + + functions = MethodChannelFirebaseFunctions( + app: app, + region: 'us-central1', + ); httpsCallable = MethodChannelHttpsCallable( functions!, kOrigin, @@ -114,11 +120,12 @@ void main() { }); test( - 'catch a [PlatformException] error and throws a [FirebaseStorageException] error', - () async { - mockPlatformExceptionThrown = true; - await testExceptionHandling('PLATFORM', httpsCallable!.call); - }); + 'catch a [PlatformException] error and throws a [FirebaseStorageException] error', + () async { + mockPlatformExceptionThrown = true; + await testExceptionHandling('PLATFORM', httpsCallable!.call); + }, + ); }); }); } diff --git a/packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/utils/exception_test.dart b/packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/utils/exception_test.dart index 0af22be8f48e..1d2d71ce4cc9 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/utils/exception_test.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/utils/exception_test.dart @@ -24,48 +24,53 @@ void main() { }); test( - 'should catch a [PlatformException] and throw a [FirebaseFunctionsException]', - () async { - PlatformException platformException = PlatformException( - code: 'foo', - message: testMessage, - ); + 'should catch a [PlatformException] and throw a [FirebaseFunctionsException]', + () async { + PlatformException platformException = PlatformException( + code: 'foo', + message: testMessage, + ); - expect( - () => convertPlatformException(platformException, StackTrace.empty), - throwsA( - isA() - .having((e) => e.code, 'code', 'unknown') - .having((e) => e.message, 'message', testMessage) - .having((e) => e.details, 'details', isNull), - ), - ); - }); + expect( + () => convertPlatformException(platformException, StackTrace.empty), + throwsA( + isA() + .having((e) => e.code, 'code', 'unknown') + .having((e) => e.message, 'message', testMessage) + .having((e) => e.details, 'details', isNull), + ), + ); + }, + ); - test('should override code and message if provided to additional details', - () async { - String code = 'baz'; - PlatformException platformException = PlatformException( + test( + 'should override code and message if provided to additional details', + () async { + String code = 'baz'; + PlatformException platformException = PlatformException( code: 'foo', message: 'bar', - details: {'code': code, 'message': testMessage}); + details: {'code': code, 'message': testMessage}, + ); - expect( - () => convertPlatformException(platformException, StackTrace.empty), - throwsA( - isA() - .having((e) => e.code, 'code', code) - .having((e) => e.message, 'message', testMessage) - .having((e) => e.details, 'details', isNull), - ), - ); - }); + expect( + () => convertPlatformException(platformException, StackTrace.empty), + throwsA( + isA() + .having((e) => e.code, 'code', code) + .having((e) => e.message, 'message', testMessage) + .having((e) => e.details, 'details', isNull), + ), + ); + }, + ); test('should provide additionalData as details', () async { PlatformException platformException = PlatformException( - code: 'UNKNOWN', - message: testMessage, - details: {'additionalData': testAdditionalData}); + code: 'UNKNOWN', + message: testMessage, + details: {'additionalData': testAdditionalData}, + ); expect( () => convertPlatformException(platformException, StackTrace.empty), @@ -74,10 +79,14 @@ void main() { .having((e) => e.code, 'code', 'unknown') .having((e) => e.message, 'message', testMessage) .having( - (e) => e.details, - 'details', - isA>() - .having((e) => e['foo'], 'additionalData', 'bar')), + (e) => e.details, + 'details', + isA>().having( + (e) => e['foo'], + 'additionalData', + 'bar', + ), + ), ), ); }); diff --git a/packages/cloud_functions/cloud_functions_platform_interface/test/mock.dart b/packages/cloud_functions/cloud_functions_platform_interface/test/mock.dart index f990f975a132..4444cfcf92ca 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/test/mock.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/test/mock.dart @@ -23,10 +23,11 @@ void setupFirebaseFunctionsMocks([Callback? customHandlers]) { void handleMethodCall(MethodCallCallback methodCallCallback) => TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(MethodChannelFirebaseFunctions.channel, - (call) async { - return await methodCallCallback(call); - }); + .setMockMethodCallHandler(MethodChannelFirebaseFunctions.channel, ( + call, + ) async { + return await methodCallCallback(call); + }); Future testExceptionHandling(String type, Function testMethod) async { try { @@ -36,7 +37,8 @@ Future testExceptionHandling(String type, Function testMethod) async { return; } fail( - 'testExceptionHandling: $testMethod threw unexpected FirebaseFunctionsException'); + 'testExceptionHandling: $testMethod threw unexpected FirebaseFunctionsException', + ); } catch (e) { fail('testExceptionHandling: $testMethod threw invalid exception $e'); } diff --git a/packages/cloud_functions/cloud_functions_platform_interface/test/pigeon/test_api.dart b/packages/cloud_functions/cloud_functions_platform_interface/test/pigeon/test_api.dart index 3583ef25e17d..40f46dc454df 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/test/pigeon/test_api.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/test/pigeon/test_api.dart @@ -48,60 +48,73 @@ abstract class TestCloudFunctionsHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.cloud_functions_platform_interface.CloudFunctionsHostApi.call$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.cloud_functions_platform_interface.CloudFunctionsHostApi.call$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final Map arg_arguments = - (args[0]! as Map).cast(); - try { - final Object? output = await api.call(arg_arguments); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final Map arg_arguments = + (args[0]! as Map).cast(); + try { + final Object? output = await api.call(arg_arguments); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.cloud_functions_platform_interface.CloudFunctionsHostApi.registerEventChannel$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.cloud_functions_platform_interface.CloudFunctionsHostApi.registerEventChannel$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final Map arg_arguments = - (args[0]! as Map).cast(); - try { - await api.registerEventChannel(arg_arguments); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final Map arg_arguments = + (args[0]! as Map).cast(); + try { + await api.registerEventChannel(arg_arguments); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } diff --git a/packages/cloud_functions/cloud_functions_platform_interface/test/platform_interface/platform_interface_firebase_functions_test.dart b/packages/cloud_functions/cloud_functions_platform_interface/test/platform_interface/platform_interface_firebase_functions_test.dart index 6903c5c9ef8f..02ddfd4254b1 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/test/platform_interface/platform_interface_firebase_functions_test.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/test/platform_interface/platform_interface_firebase_functions_test.dart @@ -47,7 +47,9 @@ void main() { test('FirebaseFunctionsPlatform.instanceFor', () { final result = FirebaseFunctionsPlatform.instanceFor( - app: app, region: 'us-central1'); + app: app, + region: 'us-central1', + ); expect(result, isA()); expect(result.app, isA()); expect(result.app!.name, defaultFirebaseAppName); @@ -55,19 +57,26 @@ void main() { test('get.instance', () { expect( - FirebaseFunctionsPlatform.instance, isA()); + FirebaseFunctionsPlatform.instance, + isA(), + ); expect(FirebaseFunctionsPlatform.instance.app, isNull); }); group('set.instance', () { test('sets the current instance', () { - FirebaseFunctionsPlatform.instance = - TestFirebaseFunctionsPlatform(secondaryApp); + FirebaseFunctionsPlatform.instance = TestFirebaseFunctionsPlatform( + secondaryApp, + ); - expect(FirebaseFunctionsPlatform.instance, - isA()); expect( - FirebaseFunctionsPlatform.instance.app!.name, equals('testApp2')); + FirebaseFunctionsPlatform.instance, + isA(), + ); + expect( + FirebaseFunctionsPlatform.instance.app!.name, + equals('testApp2'), + ); }); }); @@ -84,8 +93,11 @@ void main() { test('throws if httpsCallable()', () { try { - firebaseFunctionsPlatform! - .httpsCallable('', '', HttpsCallableOptions()); + firebaseFunctionsPlatform!.httpsCallable( + '', + '', + HttpsCallableOptions(), + ); // ignore: avoid_catching_errors, acceptable as UnimplementedError usage is correct } on UnimplementedError catch (e) { expect(e.message, equals('httpsCallable() is not implemented')); diff --git a/packages/cloud_functions/cloud_functions_platform_interface/test/platform_interface/platform_interface_https_callable_test.dart b/packages/cloud_functions/cloud_functions_platform_interface/test/platform_interface/platform_interface_https_callable_test.dart index af01a8f887f4..1ef0283cc114 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/test/platform_interface/platform_interface_https_callable_test.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/test/platform_interface/platform_interface_https_callable_test.dart @@ -20,8 +20,9 @@ void main() { TestFirebaseFunctionsPlatform firebaseFunctionsPlatform = TestFirebaseFunctionsPlatform(app); - httpsCallablePlatform = - TestHttpsCallablePlatform(firebaseFunctionsPlatform); + httpsCallablePlatform = TestHttpsCallablePlatform( + firebaseFunctionsPlatform, + ); handleMethodCall((call) async { switch (call.method) { @@ -51,7 +52,7 @@ void main() { class TestHttpsCallablePlatform extends HttpsCallablePlatform { TestHttpsCallablePlatform(FirebaseFunctionsPlatform functions) - : super(functions, null, 'function_name', HttpsCallableOptions(), null); + : super(functions, null, 'function_name', HttpsCallableOptions(), null); } class TestFirebaseFunctionsPlatform extends FirebaseFunctionsPlatform { diff --git a/packages/cloud_functions/cloud_functions_web/lib/cloud_functions_web.dart b/packages/cloud_functions/cloud_functions_web/lib/cloud_functions_web.dart index 43661665914a..c0dfa09563cb 100644 --- a/packages/cloud_functions/cloud_functions_web/lib/cloud_functions_web.dart +++ b/packages/cloud_functions/cloud_functions_web/lib/cloud_functions_web.dart @@ -21,13 +21,11 @@ class FirebaseFunctionsWeb extends FirebaseFunctionsPlatform { /// The entry point for the [FirebaseFunctionsWeb] class. FirebaseFunctionsWeb({FirebaseApp? app, required String region}) - : super(app, region); + : super(app, region); /// Stub initializer to allow the [registerWith] to create an instance without /// registering the web delegates or listeners. - FirebaseFunctionsWeb._() - : _webFunctions = null, - super(null, 'us-central1'); + FirebaseFunctionsWeb._() : _webFunctions = null, super(null, 'us-central1'); /// Instance of functions from the web plugin functions_interop.Functions? _webFunctions; @@ -35,7 +33,9 @@ class FirebaseFunctionsWeb extends FirebaseFunctionsPlatform { /// Lazily initialize [_webFunctions] on first method call functions_interop.Functions get _delegate { return _webFunctions ??= functions_interop.getFunctionsInstance( - core_interop.app(app?.name), region); + core_interop.app(app?.name), + region, + ); } /// Create the default instance of the [FirebaseFunctionsPlatform] as a [FirebaseFunctionsWeb] @@ -52,20 +52,28 @@ class FirebaseFunctionsWeb extends FirebaseFunctionsPlatform { } @override - FirebaseFunctionsPlatform delegateFor( - {FirebaseApp? app, required String region}) { + FirebaseFunctionsPlatform delegateFor({ + FirebaseApp? app, + required String region, + }) { return FirebaseFunctionsWeb(app: app, region: region); } @override HttpsCallablePlatform httpsCallable( - String? origin, String name, HttpsCallableOptions options) { + String? origin, + String name, + HttpsCallableOptions options, + ) { return HttpsCallableWeb(this, _delegate, origin, name, options, null); } @override HttpsCallablePlatform httpsCallableWithUri( - String? origin, Uri uri, HttpsCallableOptions options) { + String? origin, + Uri uri, + HttpsCallableOptions options, + ) { return HttpsCallableWeb(this, _delegate, origin, null, options, uri); } } diff --git a/packages/cloud_functions/cloud_functions_web/lib/https_callable_web.dart b/packages/cloud_functions/cloud_functions_web/lib/https_callable_web.dart index 31e30afc1859..bebcfb23e24f 100644 --- a/packages/cloud_functions/cloud_functions_web/lib/https_callable_web.dart +++ b/packages/cloud_functions/cloud_functions_web/lib/https_callable_web.dart @@ -16,9 +16,14 @@ import 'package:web/web.dart' as web; /// A web specific implementation of [HttpsCallable]. class HttpsCallableWeb extends HttpsCallablePlatform { /// Constructor. - HttpsCallableWeb(FirebaseFunctionsPlatform functions, this._webFunctions, - String? origin, String? name, HttpsCallableOptions options, Uri? uri) - : super(functions, origin, name, options, uri); + HttpsCallableWeb( + FirebaseFunctionsPlatform functions, + this._webFunctions, + String? origin, + String? name, + HttpsCallableOptions options, + Uri? uri, + ) : super(functions, origin, name, options, uri); final functions_interop.Functions _webFunctions; @@ -32,9 +37,9 @@ class HttpsCallableWeb extends HttpsCallablePlatform { functions_interop.HttpsCallableOptions callableOptions = functions_interop.HttpsCallableOptions( - timeout: options.timeout.inMilliseconds.toJS, - limitedUseAppCheckTokens: options.limitedUseAppCheckToken.toJS, - ); + timeout: options.timeout.inMilliseconds.toJS, + limitedUseAppCheckTokens: options.limitedUseAppCheckToken.toJS, + ); late functions_interop.HttpsCallable callable; @@ -84,11 +89,14 @@ class HttpsCallableWeb extends HttpsCallablePlatform { } interop.HttpsCallableStreamOptions callableStreamOptions = interop.HttpsCallableStreamOptions( - limitedUseAppCheckTokens: options.limitedUseAppCheckToken.toJS, - signal: signal); + limitedUseAppCheckTokens: options.limitedUseAppCheckToken.toJS, + signal: signal, + ); try { - await for (final value - in callable.stream(parametersJS, callableStreamOptions)) { + await for (final value in callable.stream( + parametersJS, + callableStreamOptions, + )) { yield value; } } catch (e, s) { diff --git a/packages/cloud_functions/cloud_functions_web/lib/interop/functions.dart b/packages/cloud_functions/cloud_functions_web/lib/interop/functions.dart index e884d6954576..b180cd6310bb 100644 --- a/packages/cloud_functions/cloud_functions_web/lib/interop/functions.dart +++ b/packages/cloud_functions/cloud_functions_web/lib/interop/functions.dart @@ -23,7 +23,7 @@ Functions getFunctionsInstance(App app, [String? region]) { class Functions extends JsObjectWrapper { Functions._fromJsObject(functions_interop.FunctionsJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); static final _expando = Expando(); /// Creates a new Functions from a [jsObject]. @@ -35,27 +35,39 @@ class Functions extends JsObjectWrapper { AppJsImpl get app => jsObject.app; - HttpsCallable httpsCallable(String name, - [functions_interop.HttpsCallableOptions? options]) { + HttpsCallable httpsCallable( + String name, [ + functions_interop.HttpsCallableOptions? options, + ]) { JSFunction httpCallableImpl; if (options != null) { - httpCallableImpl = - functions_interop.httpsCallable(jsObject, name.toJS, options); + httpCallableImpl = functions_interop.httpsCallable( + jsObject, + name.toJS, + options, + ); } else { httpCallableImpl = functions_interop.httpsCallable(jsObject, name.toJS); } return HttpsCallable.getInstance(httpCallableImpl); } - HttpsCallable httpsCallableUri(Uri uri, - [functions_interop.HttpsCallableOptions? options]) { + HttpsCallable httpsCallableUri( + Uri uri, [ + functions_interop.HttpsCallableOptions? options, + ]) { JSFunction httpCallableImpl; if (options != null) { httpCallableImpl = functions_interop.httpsCallableFromURL( - jsObject, uri.toString().toJS, options); + jsObject, + uri.toString().toJS, + options, + ); } else { - httpCallableImpl = - functions_interop.httpsCallableFromURL(jsObject, uri.toString().toJS); + httpCallableImpl = functions_interop.httpsCallableFromURL( + jsObject, + uri.toString().toJS, + ); } return HttpsCallable.getInstance(httpCallableImpl); } @@ -66,7 +78,7 @@ class Functions extends JsObjectWrapper { class HttpsCallable extends JsObjectWrapper { HttpsCallable._fromJsObject(JSFunction jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); static final _expando = Expando(); @@ -84,8 +96,10 @@ class HttpsCallable extends JsObjectWrapper { ); } - Stream stream(JSAny? data, - functions_interop.HttpsCallableStreamOptions? options) async* { + Stream stream( + JSAny? data, + functions_interop.HttpsCallableStreamOptions? options, + ) async* { final streamCallable = await (jsObject as functions_interop.HttpsCallable) .stream(data, options) .toDart; @@ -141,16 +155,17 @@ dynamic _convertNested(dynamic object) { class HttpsCallableResult extends JsObjectWrapper { HttpsCallableResult._fromJsObject( - functions_interop.HttpsCallableResultJsImpl jsObject) - : _data = _dartify(jsObject.data), - super.fromJsObject(jsObject); + functions_interop.HttpsCallableResultJsImpl jsObject, + ) : _data = _dartify(jsObject.data), + super.fromJsObject(jsObject); static final _expando = Expando(); final dynamic _data; /// Creates a new HttpsCallableResult from a [jsObject]. static HttpsCallableResult getInstance( - functions_interop.HttpsCallableResultJsImpl jsObject) { + functions_interop.HttpsCallableResultJsImpl jsObject, + ) { return _expando[jsObject] ??= HttpsCallableResult._fromJsObject(jsObject); } @@ -162,18 +177,20 @@ class HttpsCallableResult class HttpsCallableStreamResult extends JsObjectWrapper { HttpsCallableStreamResult._fromJsObject( - functions_interop.HttpsStreamIterableResult jsObject) - : _data = _dartify(jsObject.value), - super.fromJsObject(jsObject); + functions_interop.HttpsStreamIterableResult jsObject, + ) : _data = _dartify(jsObject.value), + super.fromJsObject(jsObject); static final _expando = Expando(); final dynamic _data; /// Creates a new HttpsCallableResult from a [jsObject]. static HttpsCallableStreamResult getInstance( - functions_interop.HttpsStreamIterableResult jsObject) { - return _expando[jsObject] ??= - HttpsCallableStreamResult._fromJsObject(jsObject); + functions_interop.HttpsStreamIterableResult jsObject, + ) { + return _expando[jsObject] ??= HttpsCallableStreamResult._fromJsObject( + jsObject, + ); } dynamic get data { diff --git a/packages/cloud_functions/cloud_functions_web/lib/interop/functions_interop.dart b/packages/cloud_functions/cloud_functions_web/lib/interop/functions_interop.dart index 79674889d92d..76af1666245a 100644 --- a/packages/cloud_functions/cloud_functions_web/lib/interop/functions_interop.dart +++ b/packages/cloud_functions/cloud_functions_web/lib/interop/functions_interop.dart @@ -16,24 +16,34 @@ import 'package:firebase_core_web/firebase_core_web_interop.dart'; @JS() @staticInterop -external FunctionsJsImpl getFunctions( - [AppJsImpl? app, JSString? regionOrDomain]); +external FunctionsJsImpl getFunctions([ + AppJsImpl? app, + JSString? regionOrDomain, +]); @JS() @staticInterop external void connectFunctionsEmulator( - FunctionsJsImpl functions, JSString host, JSNumber port); + FunctionsJsImpl functions, + JSString host, + JSNumber port, +); @JS() @staticInterop -external JSFunction httpsCallable(FunctionsJsImpl functions, JSString name, - [HttpsCallableOptions? options]); +external JSFunction httpsCallable( + FunctionsJsImpl functions, + JSString name, [ + HttpsCallableOptions? options, +]); @JS() @staticInterop external JSFunction httpsCallableFromURL( - FunctionsJsImpl functions, JSString url, - [HttpsCallableOptions? options]); + FunctionsJsImpl functions, + JSString url, [ + HttpsCallableOptions? options, +]); /// The Cloud Functions for Firebase service interface. /// @@ -49,8 +59,10 @@ extension type FunctionsJsImpl._(JSObject _) implements JSObject { /// /// See: . extension type HttpsCallableOptions._(JSObject _) implements JSObject { - external factory HttpsCallableOptions( - {JSNumber? timeout, JSBoolean? limitedUseAppCheckTokens}); + external factory HttpsCallableOptions({ + JSNumber? timeout, + JSBoolean? limitedUseAppCheckTokens, + }); external JSNumber? get timeout; external set timeout(JSNumber? t); external JSBoolean? get limitedUseAppCheckTokens; @@ -75,8 +87,10 @@ extension type HttpsCallableStreamResultJsImpl._(JSObject _) } extension type HttpsCallableStreamOptions._(JSObject _) implements JSObject { - external factory HttpsCallableStreamOptions( - {JSBoolean? limitedUseAppCheckTokens, web.AbortSignal? signal}); + external factory HttpsCallableStreamOptions({ + JSBoolean? limitedUseAppCheckTokens, + web.AbortSignal? signal, + }); external JSBoolean? get limitedUseAppCheckTokens; external set limitedUseAppCheckTokens(JSBoolean? t); external web.AbortSignal? signal; @@ -94,9 +108,11 @@ extension type JsAsyncIterator._(JSObject _) final object = (iterator as JSFunction).callAsFunction()! as JSObject; while (true) { // Wait for the next iteration result. - final result = await ((object.getProperty('next'.toJS)! as JSFunction) - .callAsFunction()! as JSPromise) - .toDart; + final result = + await ((object.getProperty('next'.toJS)! as JSFunction) + .callAsFunction()! + as JSPromise) + .toDart; final dartObject = (result.dartify()! as Map).cast(); if (dartObject['done'] as bool) { break; diff --git a/packages/cloud_functions/cloud_functions_web/lib/utils.dart b/packages/cloud_functions/cloud_functions_web/lib/utils.dart index 06a586fa0223..a3538e1589e3 100644 --- a/packages/cloud_functions/cloud_functions_web/lib/utils.dart +++ b/packages/cloud_functions/cloud_functions_web/lib/utils.dart @@ -9,13 +9,14 @@ import 'dart:js_interop_unsafe'; import 'package:cloud_functions_platform_interface/cloud_functions_platform_interface.dart'; /// Given a web error, a [FirebaseFunctionsException] is returned. -FirebaseFunctionsException convertFirebaseFunctionsException(JSObject exception, - [StackTrace? stackTrace]) { +FirebaseFunctionsException convertFirebaseFunctionsException( + JSObject exception, [ + StackTrace? stackTrace, +]) { String originalCode = (exception.getProperty('code'.toJS)! as JSString).toDart; String code = originalCode.replaceFirst('functions/', ''); - String message = (exception.getProperty('message'.toJS)! as JSString) - .toDart + String message = (exception.getProperty('message'.toJS)! as JSString).toDart .replaceFirst('($originalCode)', ''); return FirebaseFunctionsException( diff --git a/packages/cloud_functions/cloud_functions_web/pubspec.yaml b/packages/cloud_functions/cloud_functions_web/pubspec.yaml index 5a73d36fa915..f76ad8f96b29 100644 --- a/packages/cloud_functions/cloud_functions_web/pubspec.yaml +++ b/packages/cloud_functions/cloud_functions_web/pubspec.yaml @@ -7,8 +7,8 @@ version: 5.1.13 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.22.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: cloud_functions_platform_interface: ^6.0.7 diff --git a/packages/firebase_ai/firebase_ai/example/integration_test/firebase_ai_headers_e2e_test.dart b/packages/firebase_ai/firebase_ai/example/integration_test/firebase_ai_headers_e2e_test.dart index 0650556a1997..4d35ca78fd22 100644 --- a/packages/firebase_ai/firebase_ai/example/integration_test/firebase_ai_headers_e2e_test.dart +++ b/packages/firebase_ai/firebase_ai/example/integration_test/firebase_ai_headers_e2e_test.dart @@ -23,41 +23,40 @@ void main() { if (!kIsWeb) { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler( - const MethodChannel('plugins.flutter.io/firebase_ai'), - (MethodCall call) async { - if (call.method == 'getPlatformHeaders') { - return { - 'X-Android-Package': 'com.example.test', - 'X-Android-Cert': '12345', - 'x-ios-bundle-identifier': 'com.example.test', - }; - } - return null; - }); + const MethodChannel('plugins.flutter.io/firebase_ai'), + (MethodCall call) async { + if (call.method == 'getPlatformHeaders') { + return { + 'X-Android-Package': 'com.example.test', + 'X-Android-Cert': '12345', + 'x-ios-bundle-identifier': 'com.example.test', + }; + } + return null; + }, + ); } group('platform security headers', () { const _channel = MethodChannel('plugins.flutter.io/firebase_ai'); - testWidgets( - 'returns non-empty headers on mobile platforms', - skip: kIsWeb, - (WidgetTester tester) async { - final headers = await _channel.invokeMapMethod( - 'getPlatformHeaders', - ); + testWidgets('returns non-empty headers on mobile platforms', skip: kIsWeb, ( + WidgetTester tester, + ) async { + final headers = await _channel.invokeMapMethod( + 'getPlatformHeaders', + ); - expect( - headers, - isNotNull, - reason: 'Native plugin should return platform headers', - ); - expect( - headers, - isNotEmpty, - reason: 'Native plugin should return non-empty platform headers', - ); - }, - ); + expect( + headers, + isNotNull, + reason: 'Native plugin should return platform headers', + ); + expect( + headers, + isNotEmpty, + reason: 'Native plugin should return non-empty platform headers', + ); + }); testWidgets( 'returns correct Android headers', @@ -81,7 +80,8 @@ void main() { testWidgets( 'returns correct iOS/macOS headers', - skip: kIsWeb || + skip: + kIsWeb || (defaultTargetPlatform != TargetPlatform.iOS && defaultTargetPlatform != TargetPlatform.macOS), (WidgetTester tester) async { @@ -99,19 +99,15 @@ void main() { }, ); - testWidgets( - 'returns empty headers on web', - skip: !kIsWeb, - (WidgetTester tester) async { - // On web, no native plugin is registered, so the channel call - // should throw a MissingPluginException. - expect( - () => _channel.invokeMapMethod( - 'getPlatformHeaders', - ), - throwsA(isA()), - ); - }, - ); + testWidgets('returns empty headers on web', skip: !kIsWeb, ( + WidgetTester tester, + ) async { + // On web, no native plugin is registered, so the channel call + // should throw a MissingPluginException. + expect( + () => _channel.invokeMapMethod('getPlatformHeaders'), + throwsA(isA()), + ); + }); }); } diff --git a/packages/firebase_ai/firebase_ai/example/integration_test/firebase_ai_mock_test.dart b/packages/firebase_ai/firebase_ai/example/integration_test/firebase_ai_mock_test.dart index d4bda2c6957c..8a073627247c 100644 --- a/packages/firebase_ai/firebase_ai/example/integration_test/firebase_ai_mock_test.dart +++ b/packages/firebase_ai/firebase_ai/example/integration_test/firebase_ai_mock_test.dart @@ -70,7 +70,7 @@ void main() { {'text': 'Hello!'}, ], }, - } + }, ], }; @@ -106,7 +106,7 @@ void main() { {'text': '{"name": "Apple", "price": 1.2}'}, ], }, - } + }, ], }; @@ -158,7 +158,7 @@ void main() { {'text': 'Hello!'}, ], }, - } + }, ], }; @@ -185,7 +185,7 @@ void main() { {'text': 'I am good.'}, ], }, - } + }, ], }; diff --git a/packages/firebase_ai/firebase_ai/example/integration_test/firebase_ai_response_parsing_e2e_test.dart b/packages/firebase_ai/firebase_ai/example/integration_test/firebase_ai_response_parsing_e2e_test.dart index 0c52c07c7634..4dd659392896 100644 --- a/packages/firebase_ai/firebase_ai/example/integration_test/firebase_ai_response_parsing_e2e_test.dart +++ b/packages/firebase_ai/firebase_ai/example/integration_test/firebase_ai_response_parsing_e2e_test.dart @@ -36,8 +36,7 @@ void main() { ); }); - test('test against all json responses from vertexai-sdk-test-data', - () async { + test('test against all json responses from vertexai-sdk-test-data', () async { final treeUrl = Uri.parse( 'https://api.github.com/repos/FirebaseExtended/vertexai-sdk-test-data/git/trees/main?recursive=1', ); @@ -73,8 +72,9 @@ void main() { final jsonData = jsonDecode(response.body); final isVertex = path.contains('vertexai'); - final serializer = - isVertex ? AgentPlatformSerialization() : DeveloperSerialization(); + final serializer = isVertex + ? AgentPlatformSerialization() + : DeveloperSerialization(); try { if (path.contains('total-tokens') || path.contains('token')) { diff --git a/packages/firebase_ai/firebase_ai/example/integration_test/report_test_results.dart b/packages/firebase_ai/firebase_ai/example/integration_test/report_test_results.dart index 8adf5e71620a..31ac2f7e63b9 100644 --- a/packages/firebase_ai/firebase_ai/example/integration_test/report_test_results.dart +++ b/packages/firebase_ai/firebase_ai/example/integration_test/report_test_results.dart @@ -36,8 +36,9 @@ void reportTestResultsToDriver(IntegrationTestWidgetsFlutterBinding binding) { for (final entry in binding.results.entries) if (entry.value is Failure) entry.key, ]; - bool didFail(String name) => failures - .any((failure) => name == failure || name.endsWith(' $failure')); + bool didFail(String name) => failures.any( + (failure) => name == failure || name.endsWith(' $failure'), + ); binding.reportData ??= {}; binding.reportData!['testResults'] = { diff --git a/packages/firebase_ai/firebase_ai/example/lib/main.dart b/packages/firebase_ai/firebase_ai/example/lib/main.dart index a5cf530d46ab..8eb64e423ae4 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/main.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/main.dart @@ -69,10 +69,12 @@ class _GenerativeAISampleState extends State { void _initializeModel(bool useVertexBackend) { if (useVertexBackend) { - final agentPlatformInstance = - FirebaseAI.agentPlatform(location: 'global'); - _currentModel = - agentPlatformInstance.generativeModel(model: 'gemini-3.1-flash-lite'); + final agentPlatformInstance = FirebaseAI.agentPlatform( + location: 'global', + ); + _currentModel = agentPlatformInstance.generativeModel( + model: 'gemini-3.1-flash-lite', + ); } else { final googleAI = FirebaseAI.googleAI(); _currentModel = googleAI.generativeModel(model: 'gemini-3.1-flash-lite'); @@ -94,9 +96,7 @@ class _GenerativeAISampleState extends State { themeMode: ThemeMode.dark, theme: _darkTheme, home: HomeScreen( - key: ValueKey( - '${_useAgentPlatform}_${_currentModel.hashCode}', - ), + key: ValueKey('${_useAgentPlatform}_${_currentModel.hashCode}'), model: _currentModel, useAgentPlatform: _useAgentPlatform, onBackendChanged: _toggleBackend, @@ -130,7 +130,7 @@ class _HomeScreenState extends State { }); } -// Method to build the selected page on demand + // Method to build the selected page on demand Widget _buildSelectedPage( int index, GenerativeModel currentModel, @@ -138,15 +138,9 @@ class _HomeScreenState extends State { ) { switch (index) { case 0: - return ChatPage( - title: 'Chat', - useAgentPlatform: useAgentPlatform, - ); + return ChatPage(title: 'Chat', useAgentPlatform: useAgentPlatform); case 1: - return CapabilitiesPage( - title: 'Capabilities', - model: currentModel, - ); + return CapabilitiesPage(title: 'Capabilities', model: currentModel); case 2: // FunctionCallingPage initializes its own model as per original design return FunctionCallingPage( @@ -175,17 +169,11 @@ class _HomeScreenState extends State { useAgentPlatform: useAgentPlatform, ); case 7: - return TTSPage( - title: 'TTS Test', - useAgentPlatform: useAgentPlatform, - ); + return TTSPage(title: 'TTS Test', useAgentPlatform: useAgentPlatform); default: // Fallback to the first page in case of an unexpected index - return ChatPage( - title: 'Chat', - useAgentPlatform: useAgentPlatform, - ); + return ChatPage(title: 'Chat', useAgentPlatform: useAgentPlatform); } } @@ -237,10 +225,9 @@ class _HomeScreenState extends State { fontSize: 12, color: widget.useAgentPlatform ? Theme.of(context).colorScheme.primary - : Theme.of(context) - .colorScheme - .onSurface - .withAlpha(180), + : Theme.of( + context, + ).colorScheme.onSurface.withAlpha(180), ), ), ], @@ -285,30 +272,22 @@ class _HomeScreenState extends State { tooltip: 'Image Generation', ), BottomNavigationBarItem( - icon: Icon( - Icons.stream, - ), + icon: Icon(Icons.stream), label: 'Live', tooltip: 'Live Stream', ), BottomNavigationBarItem( - icon: Icon( - Icons.storage, - ), + icon: Icon(Icons.storage), label: 'Server', tooltip: 'Server Template', ), BottomNavigationBarItem( - icon: Icon( - Icons.location_on, - ), + icon: Icon(Icons.location_on), label: 'Grounding', tooltip: 'Search & Maps Grounding', ), BottomNavigationBarItem( - icon: Icon( - Icons.record_voice_over, - ), + icon: Icon(Icons.record_voice_over), label: 'TTS', tooltip: 'Text to Speech', ), diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/bidi_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/bidi_page.dart index bf8d3cf5be3f..6fd2a8f77830 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/bidi_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/bidi_page.dart @@ -105,13 +105,10 @@ class BidiMediaManager { // Wait for Mac Camera to Settle (Prevent audio hijack) await Future.delayed(const Duration(milliseconds: 1000)); - _videoSubscription = _videoInput.startStreamingImages().listen( - (data) { - String mimeType = 'image/jpeg'; - onData(data, mimeType); - }, - onError: (e) => developer.log('Video Stream Error: $e'), - ); + _videoSubscription = _videoInput.startStreamingImages().listen((data) { + String mimeType = 'image/jpeg'; + onData(data, mimeType); + }, onError: (e) => developer.log('Video Stream Error: $e')); } Future stopVideo() async { @@ -938,7 +935,8 @@ class _BidiPageState extends State { height: 200, color: Colors.black, alignment: Alignment.center, - child: (_controller.mediaManager.cameraController != null && + child: + (_controller.mediaManager.cameraController != null && _controller.mediaManager.controllerInitialized) ? FullCameraPreview( controller: _controller.mediaManager.cameraController, @@ -969,8 +967,10 @@ class _BidiPageState extends State { ), ), Padding( - padding: - const EdgeInsets.symmetric(vertical: 25, horizontal: 15), + padding: const EdgeInsets.symmetric( + vertical: 25, + horizontal: 15, + ), child: Row( children: [ Expanded( diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/capabilities_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/capabilities_page.dart index 6787f1cce1aa..953a50e87f54 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/capabilities_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/capabilities_page.dart @@ -96,17 +96,15 @@ class _CapabilitiesPageState extends State } void _scrollDown(ScrollController controller) { - WidgetsBinding.instance.addPostFrameCallback( - (_) { - if (controller.hasClients) { - controller.animateTo( - controller.position.maxScrollExtent, - duration: const Duration(milliseconds: 750), - curve: Curves.easeOutCirc, - ); - } - }, - ); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (controller.hasClients) { + controller.animateTo( + controller.position.maxScrollExtent, + duration: const Duration(milliseconds: 750), + curve: Curves.easeOutCirc, + ); + } + }); } void _showError(String message) { @@ -115,9 +113,7 @@ class _CapabilitiesPageState extends State builder: (context) { return AlertDialog( title: const Text('Something went wrong'), - content: SingleChildScrollView( - child: SelectableText(message), - ), + content: SingleChildScrollView(child: SelectableText(message)), actions: [ TextButton( onPressed: () { @@ -246,9 +242,7 @@ class _CapabilitiesPageState extends State '${dir.path}/recording_${DateTime.now().millisecondsSinceEpoch}.wav'; await record.start( - const RecordConfig( - encoder: AudioEncoder.wav, - ), + const RecordConfig(encoder: AudioEncoder.wav), path: filePath, ); } @@ -294,8 +288,9 @@ class _CapabilitiesPageState extends State ]); setState(() { - _multimodalMessages - .add(MessageData(text: response.text, fromUser: false)); + _multimodalMessages.add( + MessageData(text: response.text, fromUser: false), + ); _multimodalLoading = false; }); @@ -314,8 +309,9 @@ class _CapabilitiesPageState extends State _multimodalLoading = true; }); - ByteData videoBytes = - await rootBundle.load('assets/videos/landscape.mp4'); + ByteData videoBytes = await rootBundle.load( + 'assets/videos/landscape.mp4', + ); const promptText = 'Can you tell me what is in the video?'; @@ -323,16 +319,19 @@ class _CapabilitiesPageState extends State _multimodalMessages.add(MessageData(text: promptText, fromUser: true)); }); - final videoPart = - InlineDataPart('video/mp4', videoBytes.buffer.asUint8List()); + final videoPart = InlineDataPart( + 'video/mp4', + videoBytes.buffer.asUint8List(), + ); final response = await widget.model.generateContent([ Content.multi([const TextPart(promptText), videoPart]), ]); setState(() { - _multimodalMessages - .add(MessageData(text: response.text, fromUser: false)); + _multimodalMessages.add( + MessageData(text: response.text, fromUser: false), + ); _multimodalLoading = false; }); @@ -351,8 +350,9 @@ class _CapabilitiesPageState extends State _multimodalLoading = true; }); - ByteData docBytes = - await rootBundle.load('assets/documents/gemini_summary.pdf'); + ByteData docBytes = await rootBundle.load( + 'assets/documents/gemini_summary.pdf', + ); const promptText = 'Write me a summary in one sentence what this document is about.'; @@ -361,16 +361,19 @@ class _CapabilitiesPageState extends State _multimodalMessages.add(MessageData(text: promptText, fromUser: true)); }); - final pdfPart = - InlineDataPart('application/pdf', docBytes.buffer.asUint8List()); + final pdfPart = InlineDataPart( + 'application/pdf', + docBytes.buffer.asUint8List(), + ); final response = await widget.model.generateContent([ Content.multi([const TextPart(promptText), pdfPart]), ]); setState(() { - _multimodalMessages - .add(MessageData(text: response.text, fromUser: false)); + _multimodalMessages.add( + MessageData(text: response.text, fromUser: false), + ); _multimodalLoading = false; }); @@ -433,10 +436,7 @@ class _CapabilitiesPageState extends State await stopRecord(); } }, - icon: Icon( - Icons.mic, - color: _recording ? Colors.red : null, - ), + icon: Icon(Icons.mic, color: _recording ? Colors.red : null), label: Text(_recording ? 'Stop Rec' : 'Record Audio'), ), ElevatedButton.icon( @@ -488,8 +488,9 @@ class _CapabilitiesPageState extends State 'characters': Schema.array( items: Schema.object( properties: { - 'name': - Schema.string(description: 'The name of the character.'), + 'name': Schema.string( + description: 'The name of the character.', + ), 'species': Schema.string(description: 'The animal species.'), 'age': Schema.integer( description: 'The age of the character in years.', @@ -543,10 +544,12 @@ class _CapabilitiesPageState extends State if (response.text == null) { _showError('No response from API.'); } else { - final text = const JsonEncoder.withIndent(' ') - .convert(json.decode(response.text!) as Object?); - _structuredMessages - .add(MessageData(text: '```json\n$text\n```', fromUser: false)); + final text = const JsonEncoder.withIndent( + ' ', + ).convert(json.decode(response.text!) as Object?); + _structuredMessages.add( + MessageData(text: '```json\n$text\n```', fromUser: false), + ); setState(() { _structuredLoading = false; _scrollDown(_structuredScrollController); @@ -588,9 +591,7 @@ class _CapabilitiesPageState extends State ); final jsonSchema = JSONSchema.object( - defs: { - 'text_widget': textWidgetSchema, - }, + defs: {'text_widget': textWidgetSchema}, properties: { 'type': JSONSchema.enumString(enumValues: ['Column']), 'children': JSONSchema.array( @@ -619,10 +620,12 @@ class _CapabilitiesPageState extends State ), ); - var text = const JsonEncoder.withIndent(' ') - .convert(json.decode(response.text ?? '') as Object?); - _structuredMessages - .add(MessageData(text: '```json\n$text\n```', fromUser: false)); + var text = const JsonEncoder.withIndent( + ' ', + ).convert(json.decode(response.text ?? '') as Object?); + _structuredMessages.add( + MessageData(text: '```json\n$text\n```', fromUser: false), + ); setState(() { _structuredLoading = false; @@ -692,10 +695,7 @@ class _CapabilitiesPageState extends State // 1. Text only const prompt = 'tell a short story'; _tokensMessages.add( - MessageData( - text: 'Count tokens for text: "$prompt"', - fromUser: true, - ), + MessageData(text: 'Count tokens for text: "$prompt"', fromUser: true), ); final content = Content.text(prompt); @@ -716,16 +716,18 @@ class _CapabilitiesPageState extends State ), ); ByteData catBytes = await rootBundle.load('assets/images/cat.jpg'); - ByteData docBytes = - await rootBundle.load('assets/documents/gemini_summary.pdf'); + ByteData docBytes = await rootBundle.load( + 'assets/documents/gemini_summary.pdf', + ); final multimodalContent = Content.multi([ const TextPart('Describe this cat and summarize this document.'), InlineDataPart('image/jpeg', catBytes.buffer.asUint8List()), InlineDataPart('application/pdf', docBytes.buffer.asUint8List()), ]); - final multimodalTokenResponse = - await widget.model.countTokens([multimodalContent]); + final multimodalTokenResponse = await widget.model.countTokens([ + multimodalContent, + ]); final promptDetails = multimodalTokenResponse.promptTokensDetails ?.map((d) => '${d.modality.name}: ${d.tokenCount}') .join(', '); @@ -773,8 +775,10 @@ class _CapabilitiesPageState extends State final response = await widget.model.generateContent( content, generationConfig: GenerationConfig( - thinkingConfig: - ThinkingConfig.withThinkingBudget(2048, includeThoughts: true), + thinkingConfig: ThinkingConfig.withThinkingBudget( + 2048, + includeThoughts: true, + ), ), ); @@ -787,11 +791,7 @@ class _CapabilitiesPageState extends State if (thoughts != null && thoughts.isNotEmpty) { _tokensMessages.add( - MessageData( - text: thoughts, - fromUser: false, - isThought: true, - ), + MessageData(text: thoughts, fromUser: false, isThought: true), ); } @@ -805,7 +805,8 @@ class _CapabilitiesPageState extends State ?.map((d) => '${d.modality.name}: ${d.tokenCount}') .join(', '); - final message = ''' + final message = + ''' Usage Metadata: - promptTokenCount: ${usageMetadata.promptTokenCount} (Details: $promptDetails) - candidatesTokenCount: ${usageMetadata.candidatesTokenCount} (Details: $candidateDetails) @@ -813,18 +814,10 @@ Usage Metadata: - thoughtsTokenCount: ${usageMetadata.thoughtsTokenCount} - cachedContentTokenCount: ${usageMetadata.cachedContentTokenCount} '''; - _tokensMessages.add( - MessageData( - text: message, - fromUser: false, - ), - ); + _tokensMessages.add(MessageData(text: message, fromUser: false)); } else { _tokensMessages.add( - MessageData( - text: 'No usage metadata available.', - fromUser: false, - ), + MessageData(text: 'No usage metadata available.', fromUser: false), ); } } catch (e) { diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart index 572968688d79..5e99364d16ce 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/chat_page.dart @@ -70,9 +70,7 @@ class _ChatPageState extends State { WidgetsBinding.instance.addPostFrameCallback( (_) => _scrollController.animateTo( _scrollController.position.maxScrollExtent, - duration: const Duration( - milliseconds: 750, - ), + duration: const Duration(milliseconds: 750), curve: Curves.easeOutCirc, ), ); @@ -81,9 +79,7 @@ class _ChatPageState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), + appBar: AppBar(title: Text(widget.title)), body: Padding( padding: const EdgeInsets.all(8), child: Column( @@ -121,10 +117,7 @@ class _ChatPageState extends State { ), ), Padding( - padding: const EdgeInsets.symmetric( - vertical: 25, - horizontal: 15, - ), + padding: const EdgeInsets.symmetric(vertical: 25, horizontal: 15), child: Row( children: [ Expanded( @@ -135,9 +128,7 @@ class _ChatPageState extends State { onSubmitted: _sendChatMessage, ), ), - const SizedBox.square( - dimension: 15, - ), + const SizedBox.square(dimension: 15), if (!_loading) Row( children: [ @@ -181,9 +172,7 @@ class _ChatPageState extends State { try { _messages.add(MessageData(text: message, fromUser: true)); - final responseStream = _chat?.sendMessageStream( - Content.text(message), - ); + final responseStream = _chat?.sendMessageStream(Content.text(message)); if (responseStream == null) { _showError('No response from API.'); @@ -202,8 +191,10 @@ class _ChatPageState extends State { } textBuffer.write(response.text ?? ''); setState(() { - _messages.last = - MessageData(text: textBuffer.toString(), fromUser: false); + _messages.last = MessageData( + text: textBuffer.toString(), + fromUser: false, + ); }); _scrollDown(); } @@ -230,13 +221,12 @@ class _ChatPageState extends State { try { _messages.add(MessageData(text: message, fromUser: true)); - var response = await _chat?.sendMessage( - Content.text(message), - ); + var response = await _chat?.sendMessage(Content.text(message)); final thought = response?.thoughtSummary; if (thought != null) { - _messages - .add(MessageData(text: thought, fromUser: false, isThought: true)); + _messages.add( + MessageData(text: thought, fromUser: false, isThought: true), + ); } var text = response?.text; _messages.add(MessageData(text: text, fromUser: false)); @@ -270,9 +260,7 @@ class _ChatPageState extends State { builder: (context) { return AlertDialog( title: const Text('Something went wrong'), - content: SingleChildScrollView( - child: SelectableText(message), - ), + content: SingleChildScrollView(child: SelectableText(message)), actions: [ TextButton( onPressed: () { diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart index a18bba00f476..2f6f5895d231 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/function_calling_page.dart @@ -61,12 +61,8 @@ class _FunctionCallingPageState extends State { description: 'The name of the city and its state for which to get the weather. Only cities in the USA are supported.', properties: { - 'city': Schema.string( - description: 'The city of the location.', - ), - 'state': Schema.string( - description: 'The state of the location.', - ), + 'city': Schema.string(description: 'The city of the location.'), + 'state': Schema.string(description: 'The state of the location.'), }, ), 'date': Schema.string( @@ -80,9 +76,7 @@ class _FunctionCallingPageState extends State { name: 'findRestaurants', description: 'Find restaurants of a certain cuisine in a given location.', parameters: { - 'cuisine': Schema.string( - description: 'The cuisine of the restaurant.', - ), + 'cuisine': Schema.string(description: 'The cuisine of the restaurant.'), 'location': Schema.string( description: 'The location to search for restaurants. e.g. San Francisco, CA', @@ -116,8 +110,9 @@ class _FunctionCallingPageState extends State { description: 'Plans a complex vacation itinerary combining flights, hotels, and activities.', parameters: { - 'destination': - Schema.string(description: 'The city or country to travel to.'), + 'destination': Schema.string( + description: 'The city or country to travel to.', + ), 'travelers': Schema.integer( description: 'Number of travelers.', minimum: 1, @@ -127,8 +122,9 @@ class _FunctionCallingPageState extends State { enumValues: ['ECONOMY', 'BUSINESS', 'FIRST'], description: 'The preferred travel class.', ), - 'budget': - Schema.number(description: 'Total budget for the trip in USD.'), + 'budget': Schema.number( + description: 'Total budget for the trip in USD.', + ), 'activities': Schema.array( items: Schema.string(), description: 'A list of preferred activities.', @@ -257,17 +253,16 @@ class _FunctionCallingPageState extends State { model: 'gemini-3.1-flash-lite', generationConfig: generationConfig, tools: [ - Tool.functionDeclarations( - [_autoFindRestaurantsTool, _autoGetRestaurantMenuTool], - ), + Tool.functionDeclarations([ + _autoFindRestaurantsTool, + _autoGetRestaurantMenuTool, + ]), ], ); _codeExecutionModel = aiClient.generativeModel( model: 'gemini-3.1-flash-lite', generationConfig: generationConfig, - tools: [ - Tool.codeExecution(), - ], + tools: [Tool.codeExecution()], ); _complexSchemaModel = aiClient.generativeModel( model: 'gemini-3.1-flash-lite', @@ -291,19 +286,17 @@ class _FunctionCallingPageState extends State { 'Get the weather conditions for a specific city on a specific date.', parameters: { 'location': Schema.object( - description: 'The name of the city and its state for which to get ' + description: + 'The name of the city and its state for which to get ' 'the weather. Only cities in the USA are supported.', properties: { - 'city': Schema.string( - description: 'The city of the location.', - ), - 'state': Schema.string( - description: 'The state of the location.', - ), + 'city': Schema.string(description: 'The city of the location.'), + 'state': Schema.string(description: 'The state of the location.'), }, ), 'date': Schema.string( - description: 'The date for which to get the weather. ' + description: + 'The date for which to get the weather. ' 'Date must be in the format: YYYY-MM-DD.', ), }, @@ -342,9 +335,7 @@ class _FunctionCallingPageState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), + appBar: AppBar(title: Text(widget.title)), body: Padding( padding: const EdgeInsets.all(8), child: Column( @@ -375,10 +366,7 @@ class _FunctionCallingPageState extends State { ), ), Padding( - padding: const EdgeInsets.symmetric( - vertical: 25, - horizontal: 15, - ), + padding: const EdgeInsets.symmetric(vertical: 25, horizontal: 15), child: Column( children: [ Row( @@ -403,8 +391,9 @@ class _FunctionCallingPageState extends State { children: [ Expanded( child: ElevatedButton( - onPressed: - !_loading ? _testAutoFunctionCalling : null, + onPressed: !_loading + ? _testAutoFunctionCalling + : null, child: const Text('Auto Function Calling'), ), ), @@ -424,16 +413,18 @@ class _FunctionCallingPageState extends State { children: [ Expanded( child: ElevatedButton( - onPressed: - !_loading ? _testStreamFunctionCalling : null, + onPressed: !_loading + ? _testStreamFunctionCalling + : null, child: const Text('Stream FC'), ), ), const SizedBox(width: 8), Expanded( child: ElevatedButton( - onPressed: - !_loading ? _testAutoStreamFunctionCalling : null, + onPressed: !_loading + ? _testAutoStreamFunctionCalling + : null, child: const Text('Auto Stream FC'), ), ), @@ -472,8 +463,9 @@ class _FunctionCallingPageState extends State { Future _testAutoFunctionCalling({bool parallel = false}) async { await _runTest(() async { - final model = - parallel ? _parallelAutoFunctionCallModel : _autoFunctionCallModel; + final model = parallel + ? _parallelAutoFunctionCallModel + : _autoFunctionCallModel; final prompt = parallel ? 'Find me a good vegetarian restaurant in San Francisco and get its menu.' : 'What is the weather like in Boston, MA on 10/02 in year 2024?'; @@ -490,8 +482,9 @@ class _FunctionCallingPageState extends State { final thought = response.thoughtSummary; if (thought != null) { - _messages - .add(MessageData(text: thought, fromUser: false, isThought: true)); + _messages.add( + MessageData(text: thought, fromUser: false, isThought: true), + ); } // The SDK should have handled the function call automatically. @@ -620,14 +613,13 @@ class _FunctionCallingPageState extends State { setState(() {}); // Send the message to the generative model. - var response = await functionCallChat.sendMessage( - Content.text(prompt), - ); + var response = await functionCallChat.sendMessage(Content.text(prompt)); final thought = response.thoughtSummary; if (thought != null) { - _messages - .add(MessageData(text: thought, fromUser: false, isThought: true)); + _messages.add( + MessageData(text: thought, fromUser: false, isThought: true), + ); } final functionCalls = response.functionCalls.toList(); @@ -651,19 +643,22 @@ class _FunctionCallingPageState extends State { Future _testCodeExecution() async { await _runTest(() async { final codeExecutionChat = _codeExecutionModel.startChat(); - const prompt = 'What is the sum of the first 50 prime numbers? ' + const prompt = + 'What is the sum of the first 50 prime numbers? ' 'Generate and run code for the calculation, and make sure you get all 50.'; _messages.add(MessageData(text: prompt, fromUser: true)); setState(() {}); - final response = - await codeExecutionChat.sendMessage(Content.text(prompt)); + final response = await codeExecutionChat.sendMessage( + Content.text(prompt), + ); final thought = response.thoughtSummary; if (thought != null) { - _messages - .add(MessageData(text: thought, fromUser: false, isThought: true)); + _messages.add( + MessageData(text: thought, fromUser: false, isThought: true), + ); } final buffer = StringBuffer(); @@ -684,12 +679,7 @@ class _FunctionCallingPageState extends State { } if (buffer.isNotEmpty) { - _messages.add( - MessageData( - text: buffer.toString(), - fromUser: false, - ), - ); + _messages.add(MessageData(text: buffer.toString(), fromUser: false)); } }); } @@ -707,8 +697,9 @@ class _FunctionCallingPageState extends State { final thought = response.thoughtSummary; if (thought != null) { - _messages - .add(MessageData(text: thought, fromUser: false, isThought: true)); + _messages.add( + MessageData(text: thought, fromUser: false, isThought: true), + ); } if (response.text case final text?) { @@ -732,8 +723,9 @@ class _FunctionCallingPageState extends State { final thought = response.thoughtSummary; if (thought != null) { - _messages - .add(MessageData(text: thought, fromUser: false, isThought: true)); + _messages.add( + MessageData(text: thought, fromUser: false, isThought: true), + ); } if (response.text case final text?) { @@ -750,9 +742,7 @@ class _FunctionCallingPageState extends State { builder: (context) { return AlertDialog( title: const Text('Something went wrong'), - content: SingleChildScrollView( - child: SelectableText(message), - ), + content: SingleChildScrollView(child: SelectableText(message)), actions: [ TextButton( onPressed: () { diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart index f8d8315bab92..37c1ab777bf5 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/grounding_page.dart @@ -114,17 +114,19 @@ class _GroundingPageState extends State { final groundingMetadata = response?.candidates.firstOrNull?.groundingMetadata; if (groundingMetadata != null) { - final chunks = groundingMetadata.groundingChunks.map((chunk) { - if (chunk.web != null) { - final title = chunk.web!.title ?? chunk.web!.uri; - return '- [$title](${chunk.web!.uri})'; - } - if (chunk.maps != null) { - final title = chunk.maps!.title ?? chunk.maps!.uri; - return '- [${title ?? 'Maps Result'}](${chunk.maps!.uri ?? ''})'; - } - return '- Unknown chunk'; - }).join('\n'); + final chunks = groundingMetadata.groundingChunks + .map((chunk) { + if (chunk.web != null) { + final title = chunk.web!.title ?? chunk.web!.uri; + return '- [$title](${chunk.web!.uri})'; + } + if (chunk.maps != null) { + final title = chunk.maps!.title ?? chunk.maps!.uri; + return '- [${title ?? 'Maps Result'}](${chunk.maps!.uri ?? ''})'; + } + return '- Unknown chunk'; + }) + .join('\n'); if (chunks.isNotEmpty) { text = '$text\n\n**Grounding Sources:**\n$chunks'; @@ -157,9 +159,7 @@ class _GroundingPageState extends State { builder: (context) { return AlertDialog( title: const Text('Something went wrong'), - content: SingleChildScrollView( - child: SelectableText(message), - ), + content: SingleChildScrollView(child: SelectableText(message)), actions: [ TextButton( onPressed: () { @@ -176,9 +176,7 @@ class _GroundingPageState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), + appBar: AppBar(title: Text(widget.title)), body: Padding( padding: const EdgeInsets.all(8), child: Column( @@ -223,8 +221,9 @@ class _GroundingPageState extends State { Expanded( child: TextField( controller: _latController, - decoration: - const InputDecoration(labelText: 'Latitude'), + decoration: const InputDecoration( + labelText: 'Latitude', + ), keyboardType: const TextInputType.numberWithOptions( decimal: true, signed: true, @@ -235,8 +234,9 @@ class _GroundingPageState extends State { Expanded( child: TextField( controller: _lngController, - decoration: - const InputDecoration(labelText: 'Longitude'), + decoration: const InputDecoration( + labelText: 'Longitude', + ), keyboardType: const TextInputType.numberWithOptions( decimal: true, signed: true, @@ -261,10 +261,7 @@ class _GroundingPageState extends State { ), ), Padding( - padding: const EdgeInsets.symmetric( - vertical: 25, - horizontal: 15, - ), + padding: const EdgeInsets.symmetric(vertical: 25, horizontal: 15), child: Row( children: [ Expanded( diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart index 8511cb6c72af..4f63d8faf789 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/image_generation_page.dart @@ -106,7 +106,8 @@ class _ImageGenerationPageState extends State { setState(() { _messages.add( MessageData( - text: (textResponse ?? '') + + text: + (textResponse ?? '') + (imageBytes != null ? '\nGenerated Image:' : 'No picture generated'), @@ -132,9 +133,7 @@ class _ImageGenerationPageState extends State { builder: (context) { return AlertDialog( title: const Text('Something went wrong'), - content: SingleChildScrollView( - child: SelectableText(message), - ), + content: SingleChildScrollView(child: SelectableText(message)), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), @@ -149,9 +148,7 @@ class _ImageGenerationPageState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), + appBar: AppBar(title: Text(widget.title)), body: Padding( padding: const EdgeInsets.all(8), child: Column( @@ -194,9 +191,7 @@ class _ImageGenerationPageState extends State { ), ), items: [ - const DropdownMenuItem( - child: Text('Default'), - ), + const DropdownMenuItem(child: Text('Default')), ...ImageAspectRatio.values.map( (e) => DropdownMenuItem( value: e, @@ -224,9 +219,7 @@ class _ImageGenerationPageState extends State { ), ), items: [ - const DropdownMenuItem( - child: Text('Default'), - ), + const DropdownMenuItem(child: Text('Default')), ...ImageSize.values.map( (e) => DropdownMenuItem( value: e, diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/integration_test_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/integration_test_page.dart index 172b7a96cdf6..aae62339018f 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/integration_test_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/integration_test_page.dart @@ -56,8 +56,8 @@ class TestItem { required this.name, required this.description, required this.run, - }) : googleAIResult = TestResult.pending(), - agentPlatformResult = TestResult.pending(); + }) : googleAIResult = TestResult.pending(), + agentPlatformResult = TestResult.pending(); } class TestLogger { @@ -91,8 +91,9 @@ class _IntegrationTestPageState extends State { 'Verifies simple stateless text generation with a precise answer target using gemini-3.1-flash-lite.', run: (provider, logger) async { logger.log('Initializing model gemini-3.1-flash-lite...'); - final model = - provider.generativeModel(model: 'gemini-3.1-flash-lite'); + final model = provider.generativeModel( + model: 'gemini-3.1-flash-lite', + ); const prompt = "Reply with exactly the word 'SUCCESS' in uppercase."; logger.log('Sending prompt: "$prompt"'); final response = await model.generateContent([Content.text(prompt)]); @@ -161,7 +162,8 @@ class _IntegrationTestPageState extends State { final response = await model.generateContent([Content.text(prompt)]); logger.log('Response received: "${response.text}"'); final responseText = response.text?.toLowerCase() ?? ''; - final containsKnightTerms = responseText.contains('thou') || + final containsKnightTerms = + responseText.contains('thou') || responseText.contains('thee') || responseText.contains('sir') || responseText.contains('knight') || @@ -192,8 +194,9 @@ class _IntegrationTestPageState extends State { 'Verifies stateful conversation preservation across turns via ChatSession.', run: (provider, logger) async { logger.log('Initializing model and starting ChatSession...'); - final model = - provider.generativeModel(model: 'gemini-3.1-flash-lite'); + final model = provider.generativeModel( + model: 'gemini-3.1-flash-lite', + ); final chat = model.startChat(); const prompt1 = 'My secret agent name is Agent Orange.'; @@ -236,8 +239,9 @@ class _IntegrationTestPageState extends State { name: 'getSuperHeroPower', description: 'Returns the superpower of a given superhero by name.', parameters: { - 'heroName': - Schema.string(description: 'The name of the superhero.'), + 'heroName': Schema.string( + description: 'The name of the superhero.', + ), }, callable: (args) async { final hero = args['heroName'] as String?; @@ -292,8 +296,9 @@ class _IntegrationTestPageState extends State { 'getSuperHeroPower', 'Returns the superpower of a given superhero by name.', parameters: { - 'heroName': - Schema.string(description: 'The name of the superhero.'), + 'heroName': Schema.string( + description: 'The name of the superhero.', + ), }, ); @@ -337,8 +342,9 @@ class _IntegrationTestPageState extends State { ); final manualResponse = FunctionResponse(call.name, {'power': power}); - logger - .log('Sending second request with history + FunctionResponse...'); + logger.log( + 'Sending second request with history + FunctionResponse...', + ); final nextResponse = await model.generateContent([ Content.text(prompt), response.candidates.first.content, @@ -461,8 +467,9 @@ class _IntegrationTestPageState extends State { 'Verifies generateContentStream works and aggregates chunks correctly.', run: (provider, logger) async { logger.log('Initializing model for streaming...'); - final model = - provider.generativeModel(model: 'gemini-3.1-flash-lite'); + final model = provider.generativeModel( + model: 'gemini-3.1-flash-lite', + ); const prompt = 'Write a 2-paragraph poem about a computer.'; logger.log('Starting prompt stream: "$prompt"'); @@ -506,8 +513,9 @@ class _IntegrationTestPageState extends State { final catBytes = await rootBundle.load('assets/images/cat.jpg'); logger.log('Initializing model for token counting...'); - final model = - provider.generativeModel(model: 'gemini-3.1-flash-lite'); + final model = provider.generativeModel( + model: 'gemini-3.1-flash-lite', + ); final content = [ Content.multi([ @@ -606,8 +614,9 @@ class _IntegrationTestPageState extends State { logger.log('Sending multimodal output prompt: "$prompt"'); final response = await model.generateContent([Content.text(prompt)]); - final imageParts = response.inlineDataParts - .where((p) => p.mimeType.startsWith('image/')); + final imageParts = response.inlineDataParts.where( + (p) => p.mimeType.startsWith('image/'), + ); logger.log('Response text: "${response.text}"'); logger.log('Image parts returned: ${imageParts.length}'); @@ -637,17 +646,22 @@ class _IntegrationTestPageState extends State { } Future _runTestItem(TestItem item, bool isAgentPlatform) async { - final provider = - isAgentPlatform ? FirebaseAI.agentPlatform() : FirebaseAI.googleAI(); + final provider = isAgentPlatform + ? FirebaseAI.agentPlatform() + : FirebaseAI.googleAI(); final logger = TestLogger(); setState(() { if (isAgentPlatform) { - item.agentPlatformResult = - TestResult(status: TestStatus.running, logs: 'Running...'); + item.agentPlatformResult = TestResult( + status: TestStatus.running, + logs: 'Running...', + ); } else { - item.googleAIResult = - TestResult(status: TestStatus.running, logs: 'Running...'); + item.googleAIResult = TestResult( + status: TestStatus.running, + logs: 'Running...', + ); } }); @@ -891,10 +905,12 @@ class _IntegrationTestPageState extends State { @override Widget build(BuildContext context) { - final googleAIResults = - _testCases.map((item) => item.googleAIResult).toList(); - final vertexAIResults = - _testCases.map((item) => item.agentPlatformResult).toList(); + final googleAIResults = _testCases + .map((item) => item.googleAIResult) + .toList(); + final vertexAIResults = _testCases + .map((item) => item.agentPlatformResult) + .toList(); return Scaffold( appBar: AppBar( @@ -954,8 +970,10 @@ class _IntegrationTestPageState extends State { itemBuilder: (context, index) { final item = _testCases[index]; return Card( - margin: - const EdgeInsets.symmetric(horizontal: 12, vertical: 6), + margin: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), child: ExpansionTile( leading: CircleAvatar( backgroundColor: Colors.grey.shade800, diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/server_template_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/server_template_page.dart index d38bdb9fe1eb..6488d97ae768 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/server_template_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/server_template_page.dart @@ -96,7 +96,8 @@ class _ServerTemplatePageState extends State { optionalProperties: ['zipCode'], ), 'date': JSONSchema.string( - description: 'The date for which to get the weather. ' + description: + 'The date for which to get the weather. ' 'Date must be in the format: YYYY-MM-DD.', ), 'unit': JSONSchema.enumString( @@ -373,14 +374,17 @@ class _ServerTemplatePageState extends State { var response = await _templateGenerativeModel // ignore: experimental_member_use ?.generateContent( - 'cj-googlemaps', - inputs: {'question': message}, - toolConfig: TemplateToolConfig( - retrievalConfig: RetrievalConfig( - latLng: LatLng(latitude: 37.422, longitude: -122.084), // Googleplex - ), - ), - ); + 'cj-googlemaps', + inputs: {'question': message}, + toolConfig: TemplateToolConfig( + retrievalConfig: RetrievalConfig( + latLng: LatLng( + latitude: 37.422, + longitude: -122.084, + ), // Googleplex + ), + ), + ); final candidate = response?.candidates.first; if (candidate == null) { @@ -446,10 +450,10 @@ class _ServerTemplatePageState extends State { ); // Respond to the function call - var functionResponse = - await _chatFunctionOverrideSession?.sendMessage( - Content.functionResponse(functionCall.name, functionResult), - ); + var functionResponse = await _chatFunctionOverrideSession + ?.sendMessage( + Content.functionResponse(functionCall.name, functionResult), + ); _messages.add( MessageData(text: functionResponse?.text, fromUser: false), ); diff --git a/packages/firebase_ai/firebase_ai/example/lib/pages/tts_page.dart b/packages/firebase_ai/firebase_ai/example/lib/pages/tts_page.dart index ee00af84b4fd..f683cf5af17f 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/pages/tts_page.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/pages/tts_page.dart @@ -51,14 +51,16 @@ class _TTSPageState extends State { String _selectedVoice = 'Kore'; // Multi Speaker Controllers - final TextEditingController _speaker1NameController = - TextEditingController(text: 'Joe'); + final TextEditingController _speaker1NameController = TextEditingController( + text: 'Joe', + ); final TextEditingController _speaker1LineController = TextEditingController( text: "How's it going today Jane?", ); String _speaker1Voice = 'Kore'; - final TextEditingController _speaker2NameController = - TextEditingController(text: 'Jane'); + final TextEditingController _speaker2NameController = TextEditingController( + text: 'Jane', + ); final TextEditingController _speaker2LineController = TextEditingController( text: 'Not too bad, how about you?', ); @@ -101,9 +103,7 @@ class _TTSPageState extends State { builder: (context) { return AlertDialog( title: const Text('Something went wrong'), - content: SingleChildScrollView( - child: SelectableText(message), - ), + content: SingleChildScrollView(child: SelectableText(message)), actions: [ TextButton( onPressed: () { @@ -239,8 +239,9 @@ class _TTSPageState extends State { } // Play audio and start visualizer - final duration = - Duration(milliseconds: (audioBytes.length / 48.0).round()); + final duration = Duration( + milliseconds: (audioBytes.length / 48.0).round(), + ); await _startPlayback(duration: duration); _audioOutput.addDataToAudioStream(audioBytes); _schedulePlaybackCompletion(audioBytes.length); @@ -270,8 +271,9 @@ class _TTSPageState extends State { try { final (:model, :prompt) = _setupModelAndPrompt(); - final responseStream = - model.generateContentStream([Content.text(prompt)]); + final responseStream = model.generateContentStream([ + Content.text(prompt), + ]); final textBuffer = StringBuffer(); int totalAudioBytes = 0; @@ -346,10 +348,7 @@ class _TTSPageState extends State { border: OutlineInputBorder(), ), items: _availableVoices.map((voice) { - return DropdownMenuItem( - value: voice, - child: Text(voice), - ); + return DropdownMenuItem(value: voice, child: Text(voice)); }).toList(), onChanged: (value) { if (value != null) { @@ -376,10 +375,7 @@ class _TTSPageState extends State { margin: const EdgeInsets.symmetric(vertical: 8), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), - side: BorderSide( - color: accentColor.withAlpha(80), - width: 1.5, - ), + side: BorderSide(color: accentColor.withAlpha(80), width: 1.5), ), child: Padding( padding: const EdgeInsets.all(16), @@ -425,10 +421,7 @@ class _TTSPageState extends State { border: OutlineInputBorder(), ), items: _availableVoices.map((voice) { - return DropdownMenuItem( - value: voice, - child: Text(voice), - ); + return DropdownMenuItem(value: voice, child: Text(voice)); }).toList(), onChanged: onVoiceChanged, ), diff --git a/packages/firebase_ai/firebase_ai/example/lib/utils/audio_input.dart b/packages/firebase_ai/firebase_ai/example/lib/utils/audio_input.dart index 9a768d64be9e..85e954dbf822 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/utils/audio_input.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/utils/audio_input.dart @@ -143,10 +143,10 @@ class AudioInput extends ChangeNotifier { _amplitudeSubscription = _recorder .onAmplitudeChanged(const Duration(milliseconds: 100)) .listen((amp) { - _amplitudeStreamController?.add( - wf.Amplitude(current: amp.current, max: amp.max), - ); - }); + _amplitudeStreamController?.add( + wf.Amplitude(current: amp.current, max: amp.max), + ); + }); amplitudeStream = _amplitudeStreamController?.stream; isRecording = true; diff --git a/packages/firebase_ai/firebase_ai/example/lib/utils/video_input.dart b/packages/firebase_ai/firebase_ai/example/lib/utils/video_input.dart index a04f961b6f9e..f0df684f31d9 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/utils/video_input.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/utils/video_input.dart @@ -111,9 +111,9 @@ class VideoInput extends ChangeNotifier { Stream startStreamingImages() { final bool isInitialized = !kIsWeb && defaultTargetPlatform == TargetPlatform.macOS - ? _cameraController != null - : (_cameraController as CameraController?)?.value.isInitialized ?? - false; + ? _cameraController != null + : (_cameraController as CameraController?)?.value.isInitialized ?? + false; if (_cameraController == null || !isInitialized) { throw ErrorSummary('Unable to start image stream'); @@ -124,11 +124,11 @@ class VideoInput extends ChangeNotifier { _captureTimer = Timer.periodic( const Duration(seconds: 1), // Capture images at 1 frame per second (timer) async { - final bool currentIsInitialized = !kIsWeb && - defaultTargetPlatform == TargetPlatform.macOS + final bool currentIsInitialized = + !kIsWeb && defaultTargetPlatform == TargetPlatform.macOS ? _cameraController != null : (_cameraController as CameraController?)?.value.isInitialized ?? - false; + false; if (_cameraController == null || !currentIsInitialized || diff --git a/packages/firebase_ai/firebase_ai/example/lib/widgets/camera_previews.dart b/packages/firebase_ai/firebase_ai/example/lib/widgets/camera_previews.dart index 5aa42d1c8c81..ef5ce0d08aae 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/widgets/camera_previews.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/widgets/camera_previews.dart @@ -42,15 +42,11 @@ class SquareCameraPreview extends StatelessWidget { child: Container( width: 352, // Adjusted from 350 to be a multiple of 4 height: 352, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(16), - ), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(16)), child: AspectRatio( aspectRatio: 1, child: ClipRRect( - borderRadius: const BorderRadius.all( - Radius.circular(16), - ), + borderRadius: const BorderRadius.all(Radius.circular(16)), // The camera preview is often not a square. To fill the 1:1 aspect // ratio, we scale the preview to cover the area and clip it. child: Transform.scale( diff --git a/packages/firebase_ai/firebase_ai/example/lib/widgets/message_widget.dart b/packages/firebase_ai/firebase_ai/example/lib/widgets/message_widget.dart index 6a7ee665791e..2d79b9841679 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/widgets/message_widget.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/widgets/message_widget.dart @@ -60,8 +60,9 @@ class MessageWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Row( - mainAxisAlignment: - isFromUser ? MainAxisAlignment.end : MainAxisAlignment.start, + mainAxisAlignment: isFromUser + ? MainAxisAlignment.end + : MainAxisAlignment.start, children: [ Flexible( child: Container( @@ -70,14 +71,11 @@ class MessageWidget extends StatelessWidget { color: isThought ? Theme.of(context).colorScheme.secondaryContainer : isFromUser - ? Theme.of(context).colorScheme.primaryContainer - : Theme.of(context).colorScheme.surfaceContainerHighest, + ? Theme.of(context).colorScheme.primaryContainer + : Theme.of(context).colorScheme.surfaceContainerHighest, borderRadius: BorderRadius.circular(18), ), - padding: const EdgeInsets.symmetric( - vertical: 15, - horizontal: 20, - ), + padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 20), margin: const EdgeInsets.only(bottom: 8), child: Column( children: [ diff --git a/packages/firebase_ai/firebase_ai/example/lib/widgets/sound_waves.dart b/packages/firebase_ai/firebase_ai/example/lib/widgets/sound_waves.dart index 7f969e172cb3..e46dfba3b43f 100644 --- a/packages/firebase_ai/firebase_ai/example/lib/widgets/sound_waves.dart +++ b/packages/firebase_ai/firebase_ai/example/lib/widgets/sound_waves.dart @@ -81,8 +81,8 @@ class NestedCirclesPainter extends CustomPainter { // Configure the paint properties (same for both circles) final Paint paint = Paint() - ..color = - color.withValues(alpha: 0.7) // Make circles slightly transparent + ..color = color + .withValues(alpha: 0.7) // Make circles slightly transparent ..strokeWidth = strokeWidth ..style = PaintingStyle.stroke; // Draw the outline diff --git a/packages/firebase_ai/firebase_ai/example/pubspec.yaml b/packages/firebase_ai/firebase_ai/example/pubspec.yaml index 4d8804b09a6d..a3d598bf4b2a 100644 --- a/packages/firebase_ai/firebase_ai/example/pubspec.yaml +++ b/packages/firebase_ai/firebase_ai/example/pubspec.yaml @@ -8,8 +8,8 @@ version: 1.0.0+1 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions diff --git a/packages/firebase_ai/firebase_ai/example/test_driver/integration_test.dart b/packages/firebase_ai/firebase_ai/example/test_driver/integration_test.dart index 691723cbbfe1..9ccbcc26ab97 100644 --- a/packages/firebase_ai/firebase_ai/example/test_driver/integration_test.dart +++ b/packages/firebase_ai/firebase_ai/example/test_driver/integration_test.dart @@ -7,28 +7,32 @@ import 'dart:io'; import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver( - writeResponseOnFailure: true, - responseDataCallback: (Map? data) async { - final results = - (data?['testResults'] as Map?)?.cast() ?? - const {}; - var passed = 0; - var failed = 0; - for (final entry in results.entries) { - final ok = entry.value == 'success'; - ok ? passed++ : failed++; - // ignore: avoid_print - print('${ok ? '✅' : '❌'} ${entry.key}'); - } - // ignore: avoid_print - print('Web e2e summary: $passed passed, $failed failed, ' - '${results.length} total'); - if (results.isEmpty) { - // ignore: avoid_print - print('[E] No tests reported by the app - treating as ' - 'infrastructure failure.'); - exit(1); - } - await writeResponseData(data); - }, + writeResponseOnFailure: true, + responseDataCallback: (Map? data) async { + final results = + (data?['testResults'] as Map?)?.cast() ?? + const {}; + var passed = 0; + var failed = 0; + for (final entry in results.entries) { + final ok = entry.value == 'success'; + ok ? passed++ : failed++; + // ignore: avoid_print + print('${ok ? '✅' : '❌'} ${entry.key}'); + } + // ignore: avoid_print + print( + 'Web e2e summary: $passed passed, $failed failed, ' + '${results.length} total', ); + if (results.isEmpty) { + // ignore: avoid_print + print( + '[E] No tests reported by the app - treating as ' + 'infrastructure failure.', + ); + exit(1); + } + await writeResponseData(data); + }, +); diff --git a/packages/firebase_ai/firebase_ai/lib/src/api.dart b/packages/firebase_ai/firebase_ai/lib/src/api.dart index 296638c92d2a..ecabf1c12aee 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/api.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/api.dart @@ -22,8 +22,11 @@ import 'tool.dart' show Tool, ToolConfig; /// Response for Count Tokens final class CountTokensResponse { // ignore: public_member_api_docs - CountTokensResponse(this.totalTokens, - {this.totalBillableCharacters, this.promptTokensDetails}); + CountTokensResponse( + this.totalTokens, { + this.totalBillableCharacters, + this.promptTokensDetails, + }); /// The number of tokens that the `model` tokenizes the `prompt` into. /// @@ -45,8 +48,11 @@ final class CountTokensResponse { /// Response from the model; supports multiple candidates. final class GenerateContentResponse { // ignore: public_member_api_docs - GenerateContentResponse(this.candidates, this.promptFeedback, - {this.usageMetadata}); + GenerateContentResponse( + this.candidates, + this.promptFeedback, { + this.usageMetadata, + }); /// Candidate responses from the model. final List candidates; @@ -71,23 +77,22 @@ final class GenerateContentResponse { String? get text { return switch (candidates) { [] => switch (promptFeedback) { - PromptFeedback( - :final blockReason, - :final blockReasonMessage, - ) => - // TODO: Add a specific subtype for this exception? - throw FirebaseAIException('Response was blocked' - '${blockReason != null ? ' due to $blockReason' : ''}' - '${blockReasonMessage != null ? ': $blockReasonMessage' : ''}'), - _ => null, - }, + PromptFeedback(:final blockReason, :final blockReasonMessage) => + // TODO: Add a specific subtype for this exception? + throw FirebaseAIException( + 'Response was blocked' + '${blockReason != null ? ' due to $blockReason' : ''}' + '${blockReasonMessage != null ? ': $blockReasonMessage' : ''}', + ), + _ => null, + }, [ Candidate( finishReason: (FinishReason.recitation || FinishReason.safety) && final finishReason, :final finishMessage, ), - ... + ..., ] => throw FirebaseAIException( // ignore: prefer_interpolation_to_compose_strings @@ -100,10 +105,10 @@ final class GenerateContentResponse { [ Candidate( content: Content( - parts: [TextPart(isThought: final isThought, :final text)] - ) + parts: [TextPart(isThought: final isThought, :final text)], + ), ), - ... + ..., ] when isThought != true => text, @@ -124,9 +129,9 @@ final class GenerateContentResponse { /// candidate has no [FunctionCall] parts. There is no error thrown if the /// prompt or response were blocked. Iterable get functionCalls => - candidates.firstOrNull?.content.parts - .whereType() - .where((p) => p.isThought != true) ?? + candidates.firstOrNull?.content.parts.whereType().where( + (p) => p.isThought != true, + ) ?? const []; /// The inline data parts of the first candidate in [candidates], if any. @@ -135,9 +140,9 @@ final class GenerateContentResponse { /// candidate has no [InlineDataPart] parts. There is no error thrown if the /// prompt or response were blocked. Iterable get inlineDataParts => - candidates.firstOrNull?.content.parts - .whereType() - .where((p) => p.isThought != true) ?? + candidates.firstOrNull?.content.parts.whereType().where( + (p) => p.isThought != true, + ) ?? const []; /// The thought summary of the first candidate in [candidates], if any. @@ -234,9 +239,15 @@ final class UsageMetadata { /// Response candidate generated from a [GenerativeModel]. final class Candidate { // ignore: public_member_api_docs - Candidate(this.content, this.safetyRatings, this.citationMetadata, - this.finishReason, this.finishMessage, - {this.groundingMetadata, this.urlContextMetadata}); + Candidate( + this.content, + this.safetyRatings, + this.citationMetadata, + this.finishReason, + this.finishMessage, { + this.groundingMetadata, + this.urlContextMetadata, + }); /// Generated content returned from the model. final Content content; @@ -286,7 +297,8 @@ final class Candidate { suffix = ''; } throw FirebaseAIException( - 'Candidate was blocked due to $finishReason$suffix'); + 'Candidate was blocked due to $finishReason$suffix', + ); } return switch (content.parts) { // Special case for a single TextPart to avoid iterable chain. @@ -302,11 +314,12 @@ final class Candidate { /// the exact location of text or data that grounding information refers to. final class Segment { // ignore: public_member_api_docs - Segment( - {required this.partIndex, - required this.startIndex, - required this.endIndex, - required this.text}); + Segment({ + required this.partIndex, + required this.startIndex, + required this.endIndex, + required this.text, + }); /// The zero-based index of the [Part] object within the `parts` array of its /// parent [Content] object. @@ -386,8 +399,10 @@ final class GroundingChunk { /// is supported by the retrieved grounding chunks. final class GroundingSupport { // ignore: public_member_api_docs - GroundingSupport( - {required this.segment, required this.groundingChunkIndices}); + GroundingSupport({ + required this.segment, + required this.groundingChunkIndices, + }); /// Specifies the segment of the model's response content that this /// grounding support pertains to. @@ -429,11 +444,12 @@ final class SearchEntryPoint { /// section within the Service Specific Terms). final class GroundingMetadata { // ignore: public_member_api_docs - GroundingMetadata( - {this.searchEntryPoint, - required this.groundingChunks, - required this.groundingSupports, - required this.webSearchQueries}); + GroundingMetadata({ + this.searchEntryPoint, + required this.groundingChunks, + required this.groundingSupports, + required this.webSearchQueries, + }); /// Google Search entry point for web searches. /// @@ -503,8 +519,9 @@ enum UrlRetrievalStatus { 'URL_RETRIEVAL_STATUS_ERROR' => UrlRetrievalStatus.error, 'URL_RETRIEVAL_STATUS_PAYWALL' => UrlRetrievalStatus.paywall, 'URL_RETRIEVAL_STATUS_UNSAFE' => UrlRetrievalStatus.unsafe, - _ => UrlRetrievalStatus - .unspecified, // Default to unspecified for unknown values. + _ => + UrlRetrievalStatus + .unspecified, // Default to unspecified for unknown values. }; } } @@ -546,11 +563,14 @@ final class UrlContextMetadata { /// classification is included here. final class SafetyRating { // ignore: public_member_api_docs - SafetyRating(this.category, this.probability, - {this.probabilityScore, - this.isBlocked, - this.severity, - this.severityScore}); + SafetyRating( + this.category, + this.probability, { + this.probabilityScore, + this.isBlocked, + this.severity, + this.severityScore, + }); /// The category for this rating. final HarmCategory category; @@ -965,10 +985,10 @@ final class SafetySetting { /// Convert to json format. Object toJson() => { - 'category': category.toJson(), - 'threshold': threshold.toJson(), - if (method case final method?) 'method': method.toJson(), - }; + 'category': category.toJson(), + 'threshold': threshold.toJson(), + if (method case final method?) 'method': method.toJson(), + }; } /// Probability of harm which causes content to be blocked. @@ -1004,7 +1024,9 @@ enum HarmBlockThreshold { 'BLOCK_NONE' => HarmBlockThreshold.none, 'OFF' => HarmBlockThreshold.off, _ => throw FormatException( - 'Unhandled HarmBlockThreshold format', jsonObject), + 'Unhandled HarmBlockThreshold format', + jsonObject, + ), }; } @@ -1092,12 +1114,12 @@ enum MediaResolution { /// Parse a media resolution from a JSON value. static MediaResolution parseValue(String value) => switch (value) { - 'MEDIA_RESOLUTION_LOW' => MediaResolution.low, - 'MEDIA_RESOLUTION_MEDIUM' => MediaResolution.medium, - 'MEDIA_RESOLUTION_HIGH' => MediaResolution.high, - 'MEDIA_RESOLUTION_ULTRA_HIGH' => MediaResolution.ultraHigh, - _ => MediaResolution.unspecified, - }; + 'MEDIA_RESOLUTION_LOW' => MediaResolution.low, + 'MEDIA_RESOLUTION_MEDIUM' => MediaResolution.medium, + 'MEDIA_RESOLUTION_HIGH' => MediaResolution.high, + 'MEDIA_RESOLUTION_ULTRA_HIGH' => MediaResolution.ultraHigh, + _ => MediaResolution.unspecified, + }; // ignore: public_member_api_docs String toJson() => _jsonString; @@ -1134,34 +1156,46 @@ class ThinkingConfig { /// Keep for backwards compatibility. /// [thinkingBudget] and [thinkingLevel] cannot be set at the same time. @Deprecated( - 'Use ThinkingConfig.withThinkingBudget() or ThinkingConfig.withThinkingLevel() instead.') - ThinkingConfig( - {this.thinkingBudget, this.thinkingLevel, this.includeThoughts}) - : assert( - !(thinkingBudget != null && thinkingLevel != null), - 'thinkingBudget and thinkingLevel cannot be set at the same time.', - ); + 'Use ThinkingConfig.withThinkingBudget() or ThinkingConfig.withThinkingLevel() instead.', + ) + ThinkingConfig({ + this.thinkingBudget, + this.thinkingLevel, + this.includeThoughts, + }) : assert( + !(thinkingBudget != null && thinkingLevel != null), + 'thinkingBudget and thinkingLevel cannot be set at the same time.', + ); // Private constructor - ThinkingConfig._( - {this.thinkingBudget, this.thinkingLevel, this.includeThoughts}); + ThinkingConfig._({ + this.thinkingBudget, + this.thinkingLevel, + this.includeThoughts, + }); /// Initializes [ThinkingConfig] with [thinkingBudget]. /// /// Used for Gemini models 2.5 and earlier. - factory ThinkingConfig.withThinkingBudget(int? thinkingBudget, - {bool? includeThoughts}) => - ThinkingConfig._( - thinkingBudget: thinkingBudget, includeThoughts: includeThoughts); + factory ThinkingConfig.withThinkingBudget( + int? thinkingBudget, { + bool? includeThoughts, + }) => ThinkingConfig._( + thinkingBudget: thinkingBudget, + includeThoughts: includeThoughts, + ); /// Initializes [ThinkingConfig] with [thinkingLevel]. /// /// Used for Gemini models 3.0 and newer. /// See https://ai.google.dev/gemini-api/docs/thinking#thinking-levels - factory ThinkingConfig.withThinkingLevel(ThinkingLevel? thinkingLevel, - {bool? includeThoughts}) => - ThinkingConfig._( - thinkingLevel: thinkingLevel, includeThoughts: includeThoughts); + factory ThinkingConfig.withThinkingLevel( + ThinkingLevel? thinkingLevel, { + bool? includeThoughts, + }) => ThinkingConfig._( + thinkingLevel: thinkingLevel, + includeThoughts: includeThoughts, + ); /// The number of thoughts tokens that the model should generate. /// @@ -1185,13 +1219,13 @@ class ThinkingConfig { // ignore: public_member_api_docs Map toJson() => { - if (thinkingBudget case final thinkingBudget?) - 'thinkingBudget': thinkingBudget, - if (thinkingLevel case final thinkingLevel?) - 'thinkingLevel': thinkingLevel.toJson(), - if (includeThoughts case final includeThoughts?) - 'includeThoughts': includeThoughts, - }; + if (thinkingBudget case final thinkingBudget?) + 'thinkingBudget': thinkingBudget, + if (thinkingLevel case final thinkingLevel?) + 'thinkingLevel': thinkingLevel.toJson(), + if (includeThoughts case final includeThoughts?) + 'includeThoughts': includeThoughts, + }; } /// Configuration options for model generation and outputs. @@ -1208,8 +1242,10 @@ abstract class BaseGenerationConfig { this.responseModalities, this.mediaResolution, this.speechConfig, - }) : assert(mediaResolution != MediaResolution.ultraHigh, - 'MediaResolution.ultraHigh is only supported on individual media parts.'); + }) : assert( + mediaResolution != MediaResolution.ultraHigh, + 'MediaResolution.ultraHigh is only supported on individual media parts.', + ); /// Number of generated responses to return. /// @@ -1301,25 +1337,26 @@ abstract class BaseGenerationConfig { // ignore: public_member_api_docs Map toJson() => { - if (candidateCount case final candidateCount?) - 'candidateCount': candidateCount, - if (maxOutputTokens case final maxOutputTokens?) - 'maxOutputTokens': maxOutputTokens, - if (temperature case final temperature?) 'temperature': temperature, - if (topP case final topP?) 'topP': topP, - if (topK case final topK?) 'topK': topK, - if (presencePenalty case final presencePenalty?) - 'presencePenalty': presencePenalty, - if (frequencyPenalty case final frequencyPenalty?) - 'frequencyPenalty': frequencyPenalty, - if (responseModalities case final responseModalities?) - 'responseModalities': - responseModalities.map((modality) => modality.toJson()).toList(), - if (mediaResolution case final mediaResolution?) - 'mediaResolution': mediaResolution.toJson(), - if (speechConfig case final speechConfig?) - 'speechConfig': speechConfig.toJson(), - }; + if (candidateCount case final candidateCount?) + 'candidateCount': candidateCount, + if (maxOutputTokens case final maxOutputTokens?) + 'maxOutputTokens': maxOutputTokens, + if (temperature case final temperature?) 'temperature': temperature, + if (topP case final topP?) 'topP': topP, + if (topK case final topK?) 'topK': topK, + if (presencePenalty case final presencePenalty?) + 'presencePenalty': presencePenalty, + if (frequencyPenalty case final frequencyPenalty?) + 'frequencyPenalty': frequencyPenalty, + if (responseModalities case final responseModalities?) + 'responseModalities': responseModalities + .map((modality) => modality.toJson()) + .toList(), + if (mediaResolution case final mediaResolution?) + 'mediaResolution': mediaResolution.toJson(), + if (speechConfig case final speechConfig?) + 'speechConfig': speechConfig.toJson(), + }; } /// Configuration options for model generation and outputs. @@ -1342,8 +1379,10 @@ final class GenerationConfig extends BaseGenerationConfig { this.responseJsonSchema, this.thinkingConfig, this.imageConfig, - }) : assert(responseSchema == null || responseJsonSchema == null, - 'responseSchema and responseJsonSchema cannot both be set.'); + }) : assert( + responseSchema == null || responseJsonSchema == null, + 'responseSchema and responseJsonSchema cannot both be set.', + ); /// The set of character sequences (up to 5) that will stop output generation. /// @@ -1395,21 +1434,20 @@ final class GenerationConfig extends BaseGenerationConfig { @override Map toJson() => { - ...super.toJson(), - if (stopSequences case final stopSequences? - when stopSequences.isNotEmpty) - 'stopSequences': stopSequences, - if (responseMimeType case final responseMimeType?) - 'responseMimeType': responseMimeType, - if (responseSchema case final responseSchema?) - 'responseSchema': responseSchema.toJson(), - if (responseJsonSchema case final responseJsonSchema?) - 'responseJsonSchema': responseJsonSchema, - if (thinkingConfig case final thinkingConfig?) - 'thinkingConfig': thinkingConfig.toJson(), - if (imageConfig case final imageConfig?) - 'imageConfig': imageConfig.toJson(), - }; + ...super.toJson(), + if (stopSequences case final stopSequences? when stopSequences.isNotEmpty) + 'stopSequences': stopSequences, + if (responseMimeType case final responseMimeType?) + 'responseMimeType': responseMimeType, + if (responseSchema case final responseSchema?) + 'responseSchema': responseSchema.toJson(), + if (responseJsonSchema case final responseJsonSchema?) + 'responseJsonSchema': responseJsonSchema, + if (thinkingConfig case final thinkingConfig?) + 'thinkingConfig': thinkingConfig.toJson(), + if (imageConfig case final imageConfig?) + 'imageConfig': imageConfig.toJson(), + }; } /// Type of task for which the embedding will be used. @@ -1490,22 +1528,28 @@ final class AgentPlatformSerialization implements SerializationStrategy { final candidates = switch (jsonObject) { {'candidates': final List candidates} => candidates.map(_parseCandidate).toList(), - _ => [] + _ => [], }; final promptFeedback = switch (jsonObject) { - {'promptFeedback': final promptFeedback?} => - _parsePromptFeedback(promptFeedback), + {'promptFeedback': final promptFeedback?} => _parsePromptFeedback( + promptFeedback, + ), _ => null, }; final usageMetadata = switch (jsonObject) { - {'usageMetadata': final usageMetadata?} => - parseUsageMetadata(usageMetadata), - {'totalTokens': final int totalTokens} => - UsageMetadata._(totalTokenCount: totalTokens), + {'usageMetadata': final usageMetadata?} => parseUsageMetadata( + usageMetadata, + ), + {'totalTokens': final int totalTokens} => UsageMetadata._( + totalTokenCount: totalTokens, + ), _ => null, }; - return GenerateContentResponse(candidates, promptFeedback, - usageMetadata: usageMetadata); + return GenerateContentResponse( + candidates, + promptFeedback, + usageMetadata: usageMetadata, + ); } /// Parse the json to [CountTokensResponse] @@ -1579,38 +1623,40 @@ Candidate _parseCandidate(Object? jsonObject) { } return Candidate( - jsonObject.containsKey('content') - ? parseContent(jsonObject['content'] as Object) - : Content(null, []), - switch (jsonObject) { - {'safetyRatings': final List safetyRatings} => - safetyRatings.map(_parseSafetyRating).toList(), - _ => null - }, - switch (jsonObject) { - {'citationMetadata': final Object citationMetadata} => - parseCitationMetadata(citationMetadata), - _ => null - }, - switch (jsonObject) { - {'finishReason': final Object finishReason} => - FinishReason.parseValue(finishReason), - _ => null - }, - switch (jsonObject) { - {'finishMessage': final String finishMessage} => finishMessage, - _ => null - }, - groundingMetadata: switch (jsonObject) { - {'groundingMetadata': final Object groundingMetadata} => - parseGroundingMetadata(groundingMetadata), - _ => null - }, - urlContextMetadata: switch (jsonObject) { - {'urlContextMetadata': final Object urlContextMetadata} => - parseUrlContextMetadata(urlContextMetadata), - _ => null - }); + jsonObject.containsKey('content') + ? parseContent(jsonObject['content'] as Object) + : Content(null, []), + switch (jsonObject) { + {'safetyRatings': final List safetyRatings} => + safetyRatings.map(_parseSafetyRating).toList(), + _ => null, + }, + switch (jsonObject) { + {'citationMetadata': final Object citationMetadata} => + parseCitationMetadata(citationMetadata), + _ => null, + }, + switch (jsonObject) { + {'finishReason': final Object finishReason} => FinishReason.parseValue( + finishReason, + ), + _ => null, + }, + switch (jsonObject) { + {'finishMessage': final String finishMessage} => finishMessage, + _ => null, + }, + groundingMetadata: switch (jsonObject) { + {'groundingMetadata': final Object groundingMetadata} => + parseGroundingMetadata(groundingMetadata), + _ => null, + }, + urlContextMetadata: switch (jsonObject) { + {'urlContextMetadata': final Object urlContextMetadata} => + parseUrlContextMetadata(urlContextMetadata), + _ => null, + }, + ); } PromptFeedback _parsePromptFeedback(Object jsonObject) { @@ -1621,21 +1667,20 @@ PromptFeedback _parsePromptFeedback(Object jsonObject) { return PromptFeedback(null, null, []); } return switch (jsonObject) { - { - 'safetyRatings': final List safetyRatings, - } => - PromptFeedback( - switch (jsonObject) { - {'blockReason': final String blockReason} => - BlockReason.parseValue(blockReason), - _ => null, - }, - switch (jsonObject) { - {'blockReasonMessage': final String blockReasonMessage} => - blockReasonMessage, - _ => null, - }, - safetyRatings.map(_parseSafetyRating).toList()), + {'safetyRatings': final List safetyRatings} => PromptFeedback( + switch (jsonObject) { + {'blockReason': final String blockReason} => BlockReason.parseValue( + blockReason, + ), + _ => null, + }, + switch (jsonObject) { + {'blockReasonMessage': final String blockReasonMessage} => + blockReasonMessage, + _ => null, + }, + safetyRatings.map(_parseSafetyRating).toList(), + ), _ => throw unhandledFormat('PromptFeedback', jsonObject), }; } @@ -1681,8 +1726,8 @@ UsageMetadata parseUsageMetadata(Object jsonObject) { }; final toolUsePromptTokensDetails = switch (jsonObject) { { - 'toolUsePromptTokensDetails': final List - toolUsePromptTokensDetails + 'toolUsePromptTokensDetails': + final List toolUsePromptTokensDetails, } => toolUsePromptTokensDetails.map(_parseModalityTokenCount).toList(), _ => null, @@ -1731,14 +1776,16 @@ SafetyRating _parseSafetyRating(Object? jsonObject) { if (jsonObject.isEmpty) { return SafetyRating(HarmCategory.unknown, HarmProbability.unknown); } - return SafetyRating(HarmCategory._parseValue(jsonObject['category']), - HarmProbability._parseValue(jsonObject['probability']), - probabilityScore: jsonObject['probabilityScore'] as double?, - isBlocked: jsonObject['blocked'] as bool?, - severity: jsonObject['severity'] != null - ? HarmSeverity._parseValue(jsonObject['severity']) - : null, - severityScore: jsonObject['severityScore'] as double?); + return SafetyRating( + HarmCategory._parseValue(jsonObject['category']), + HarmProbability._parseValue(jsonObject['probability']), + probabilityScore: jsonObject['probabilityScore'] as double?, + isBlocked: jsonObject['blocked'] as bool?, + severity: jsonObject['severity'] != null + ? HarmSeverity._parseValue(jsonObject['severity']) + : null, + severityScore: jsonObject['severityScore'] as double?, + ); } /// Parses a [CitationMetadata] from a JSON object. @@ -1750,8 +1797,9 @@ CitationMetadata parseCitationMetadata(Object? jsonObject) { {'citationSources': final List citationSources} => CitationMetadata(citationSources.map(_parseCitationSource).toList()), // Vertex SDK format uses `citations` - {'citations': final List citationSources} => - CitationMetadata(citationSources.map(_parseCitationSource).toList()), + {'citations': final List citationSources} => CitationMetadata( + citationSources.map(_parseCitationSource).toList(), + ), _ => throw unhandledFormat('CitationMetadata', jsonObject), }; } @@ -1785,7 +1833,8 @@ GroundingMetadata parseGroundingMetadata(Object? jsonObject) { _parseSearchEntryPoint(searchEntryPoint), _ => null, }; - final groundingChunks = switch (jsonObject) { + final groundingChunks = + switch (jsonObject) { {'groundingChunks': final List groundingChunks} => groundingChunks.map(_parseGroundingChunk).toList(), _ => null, @@ -1793,7 +1842,8 @@ GroundingMetadata parseGroundingMetadata(Object? jsonObject) { []; // Filters out null elements, which are returned from _parseGroundingSupport when // segment is null. - final groundingSupports = switch (jsonObject) { + final groundingSupports = + switch (jsonObject) { {'groundingSupports': final List groundingSupports} => groundingSupports .map(_parseGroundingSupport) @@ -1802,7 +1852,8 @@ GroundingMetadata parseGroundingMetadata(Object? jsonObject) { _ => null, } ?? []; - final webSearchQueries = switch (jsonObject) { + final webSearchQueries = + switch (jsonObject) { {'webSearchQueries': final List? webSearchQueries} => webSearchQueries, _ => null, @@ -1810,10 +1861,11 @@ GroundingMetadata parseGroundingMetadata(Object? jsonObject) { []; return GroundingMetadata( - searchEntryPoint: searchEntryPoint, - groundingChunks: groundingChunks, - groundingSupports: groundingSupports, - webSearchQueries: webSearchQueries); + searchEntryPoint: searchEntryPoint, + groundingChunks: groundingChunks, + groundingSupports: groundingSupports, + webSearchQueries: webSearchQueries, + ); } Segment _parseSegment(Object? jsonObject) { @@ -1822,10 +1874,11 @@ Segment _parseSegment(Object? jsonObject) { } return Segment( - partIndex: (jsonObject['partIndex'] as int?) ?? 0, - startIndex: (jsonObject['startIndex'] as int?) ?? 0, - endIndex: (jsonObject['endIndex'] as int?) ?? 0, - text: (jsonObject['text'] as String?) ?? ''); + partIndex: (jsonObject['partIndex'] as int?) ?? 0, + startIndex: (jsonObject['startIndex'] as int?) ?? 0, + endIndex: (jsonObject['endIndex'] as int?) ?? 0, + text: (jsonObject['text'] as String?) ?? '', + ); } WebGroundingChunk _parseWebGroundingChunk(Object? jsonObject) { @@ -1881,9 +1934,10 @@ GroundingSupport? _parseGroundingSupport(Object? jsonObject) { } return GroundingSupport( - segment: segment, - groundingChunkIndices: - (jsonObject['groundingChunkIndices'] as List?)?.cast() ?? []); + segment: segment, + groundingChunkIndices: + (jsonObject['groundingChunkIndices'] as List?)?.cast() ?? [], + ); } SearchEntryPoint _parseSearchEntryPoint(Object? jsonObject) { @@ -1896,9 +1950,7 @@ SearchEntryPoint _parseSearchEntryPoint(Object? jsonObject) { throw unhandledFormat('SearchEntryPoint', jsonObject); } - return SearchEntryPoint( - renderedContent: renderedContent, - ); + return SearchEntryPoint(renderedContent: renderedContent); } UrlMetadata _parseUrlMetadata(Object? jsonObject) { @@ -1908,8 +1960,9 @@ UrlMetadata _parseUrlMetadata(Object? jsonObject) { final uriString = jsonObject['retrievedUrl'] as String?; return UrlMetadata( retrievedUrl: uriString != null ? Uri.parse(uriString) : null, - urlRetrievalStatus: - UrlRetrievalStatus._parseValue(jsonObject['urlRetrievalStatus']), + urlRetrievalStatus: UrlRetrievalStatus._parseValue( + jsonObject['urlRetrievalStatus'], + ), ); } @@ -1948,8 +2001,9 @@ enum CodeLanguage { return switch (jsonObject) { 'LANGUAGE_UNSPECIFIED' => CodeLanguage.unspecified, 'PYTHON' => CodeLanguage.python, - _ => CodeLanguage - .unspecified, // If backend has new change, return unspecified. + _ => + CodeLanguage + .unspecified, // If backend has new change, return unspecified. }; } } diff --git a/packages/firebase_ai/firebase_ai/lib/src/base_model.dart b/packages/firebase_ai/firebase_ai/lib/src/base_model.dart index 14430a5a98ca..2aecc89fc182 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/base_model.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/base_model.dart @@ -71,12 +71,12 @@ abstract interface class _ModelUri { } final class _AgentPlatformUri implements _ModelUri { - _AgentPlatformUri( - {required String model, - required String location, - required FirebaseApp app}) - : model = _normalizeModelName(model), - _projectUri = _agentPlatformUri(app, location); + _AgentPlatformUri({ + required String model, + required String location, + required FirebaseApp app, + }) : model = _normalizeModelName(model), + _projectUri = _agentPlatformUri(app, location); static const _baseAuthority = 'firebasevertexai.googleapis.com'; static const _apiVersion = 'v1beta'; @@ -113,17 +113,18 @@ final class _AgentPlatformUri implements _ModelUri { @override Uri taskUri(Task task) { return _projectUri.replace( - pathSegments: _projectUri.pathSegments - .followedBy([model.prefix, '${model.name}:${task.name}'])); + pathSegments: _projectUri.pathSegments.followedBy([ + model.prefix, + '${model.name}:${task.name}', + ]), + ); } } final class _GoogleAIUri implements _ModelUri { - _GoogleAIUri({ - required String model, - required FirebaseApp app, - }) : model = _normalizeModelName(model), - _baseUri = _googleAIBaseUri(app: app); + _GoogleAIUri({required String model, required FirebaseApp app}) + : model = _normalizeModelName(model), + _baseUri = _googleAIBaseUri(app: app); /// Returns the model code for a user friendly model name. /// @@ -138,10 +139,13 @@ final class _GoogleAIUri implements _ModelUri { static const _apiVersion = 'v1beta'; static const _baseAuthority = 'firebasevertexai.googleapis.com'; - static Uri _googleAIBaseUri( - {String apiVersion = _apiVersion, required FirebaseApp app}) => - Uri.https( - _baseAuthority, '$apiVersion/projects/${app.options.projectId}'); + static Uri _googleAIBaseUri({ + String apiVersion = _apiVersion, + required FirebaseApp app, + }) => Uri.https( + _baseAuthority, + '$apiVersion/projects/${app.options.projectId}', + ); final Uri _baseUri; @@ -156,8 +160,11 @@ final class _GoogleAIUri implements _ModelUri { @override Uri taskUri(Task task) => _baseUri.replace( - pathSegments: _baseUri.pathSegments - .followedBy([model.prefix, '${model.name}:${task.name}'])); + pathSegments: _baseUri.pathSegments.followedBy([ + model.prefix, + '${model.name}:${task.name}', + ]), + ); } abstract interface class _TemplateUri { @@ -168,10 +175,11 @@ abstract interface class _TemplateUri { } final class _TemplateAgentPlatformUri implements _TemplateUri { - _TemplateAgentPlatformUri( - {required String location, required FirebaseApp app}) - : _templateUri = _agentPlatformTemplateUri(app, location), - _templateName = _agentPlatformTemplateName(app, location); + _TemplateAgentPlatformUri({ + required String location, + required FirebaseApp app, + }) : _templateUri = _agentPlatformTemplateUri(app, location), + _templateName = _agentPlatformTemplateName(app, location); static const _baseAuthority = 'firebasevertexai.googleapis.com'; static const _apiVersion = 'v1beta'; @@ -201,8 +209,11 @@ final class _TemplateAgentPlatformUri implements _TemplateUri { @override Uri templateTaskUri(TemplateTask task, String templateId) { return _templateUri.replace( - pathSegments: _templateUri.pathSegments - .followedBy(['templates', '$templateId:${task.name}'])); + pathSegments: _templateUri.pathSegments.followedBy([ + 'templates', + '$templateId:${task.name}', + ]), + ); } @override @@ -211,20 +222,22 @@ final class _TemplateAgentPlatformUri implements _TemplateUri { } final class _TemplateGoogleAIUri implements _TemplateUri { - _TemplateGoogleAIUri({ - required FirebaseApp app, - }) : _templateUri = _googleAITemplateUri(app: app), - _templateName = _googleAITemplateName(app: app); + _TemplateGoogleAIUri({required FirebaseApp app}) + : _templateUri = _googleAITemplateUri(app: app), + _templateName = _googleAITemplateName(app: app); static const _baseAuthority = 'firebasevertexai.googleapis.com'; static const _apiVersion = 'v1beta'; final Uri _templateUri; final String _templateName; - static Uri _googleAITemplateUri( - {String apiVersion = _apiVersion, required FirebaseApp app}) => - Uri.https( - _baseAuthority, '$apiVersion/projects/${app.options.projectId}'); + static Uri _googleAITemplateUri({ + String apiVersion = _apiVersion, + required FirebaseApp app, + }) => Uri.https( + _baseAuthority, + '$apiVersion/projects/${app.options.projectId}', + ); static String _googleAITemplateName({required FirebaseApp app}) => 'projects/${app.options.projectId}'; @@ -238,8 +251,11 @@ final class _TemplateGoogleAIUri implements _TemplateUri { @override Uri templateTaskUri(TemplateTask task, String templateId) { return _templateUri.replace( - pathSegments: _templateUri.pathSegments - .followedBy(['templates', '$templateId:${task.name}'])); + pathSegments: _templateUri.pathSegments.followedBy([ + 'templates', + '$templateId:${task.name}', + ]), + ); } @override @@ -252,11 +268,11 @@ final class _TemplateGoogleAIUri implements _TemplateUri { /// This class provides the basic functionality for interacting with the /// Firebase AI API. It is not intended to be instantiated directly. abstract class BaseModel { - BaseModel._( - {required SerializationStrategy serializationStrategy, - required _ModelUri modelUri}) - : _serializationStrategy = serializationStrategy, - _modelUri = modelUri; + BaseModel._({ + required SerializationStrategy serializationStrategy, + required _ModelUri modelUri, + }) : _serializationStrategy = serializationStrategy, + _modelUri = modelUri; final SerializationStrategy _serializationStrategy; final _ModelUri _modelUri; @@ -324,8 +340,8 @@ abstract class BaseApiClientModel extends BaseModel { required super.serializationStrategy, required super.modelUri, required ApiClient client, - }) : _client = client, - super._(); + }) : _client = client, + super._(); final ApiClient _client; @@ -333,9 +349,11 @@ abstract class BaseApiClientModel extends BaseModel { ApiClient get client => _client; /// Make a unary request for [task] with JSON encodable [params]. - Future makeRequest(Task task, Map params, - T Function(Map) parse) => - _client.makeRequest(taskUri(task), params).then(parse); + Future makeRequest( + Task task, + Map params, + T Function(Map) parse, + ) => _client.makeRequest(taskUri(task), params).then(parse); } /// An abstract base class for models that interact with a template-based API @@ -346,12 +364,12 @@ abstract class BaseApiClientModel extends BaseModel { /// making requests and parsing the responses. abstract class BaseTemplateApiClientModel extends BaseApiClientModel { // ignore: public_member_api_docs - BaseTemplateApiClientModel( - {required super.serializationStrategy, - required super.modelUri, - required super.client, - required _TemplateUri templateUri}) - : _templateUri = templateUri; + BaseTemplateApiClientModel({ + required super.serializationStrategy, + required super.modelUri, + required super.client, + required _TemplateUri templateUri, + }) : _templateUri = templateUri; final _TemplateUri _templateUri; @@ -361,13 +379,14 @@ abstract class BaseTemplateApiClientModel extends BaseApiClientModel { /// and [inputs]. It returns a [Future] that completes with the parsed /// response. Future makeTemplateRequest( - TemplateTask task, - String templateId, - Map? inputs, - Iterable? history, - List? tools, - TemplateToolConfig? toolConfig, - T Function(Map) parse) { + TemplateTask task, + String templateId, + Map? inputs, + Iterable? history, + List? tools, + TemplateToolConfig? toolConfig, + T Function(Map) parse, + ) { Map body = {}; if (inputs != null) { body['inputs'] = _serializeTemplateInputs(inputs); @@ -391,13 +410,14 @@ abstract class BaseTemplateApiClientModel extends BaseApiClientModel { /// This method sends a request to the API with the given [task], [templateId], /// and [inputs]. It returns a [Stream] of parsed responses. Stream streamTemplateRequest( - TemplateTask task, - String templateId, - Map? inputs, - Iterable? history, - List? tools, - TemplateToolConfig? toolConfig, - T Function(Map) parse) { + TemplateTask task, + String templateId, + Map? inputs, + Iterable? history, + List? tools, + TemplateToolConfig? toolConfig, + T Function(Map) parse, + ) { Map body = {}; if (inputs != null) { body['inputs'] = _serializeTemplateInputs(inputs); @@ -411,8 +431,10 @@ abstract class BaseTemplateApiClientModel extends BaseApiClientModel { if (toolConfig != null) { body['toolConfig'] = toolConfig.toJson(); } - final response = - _client.streamRequest(templateTaskUri(task, templateId), body); + final response = _client.streamRequest( + templateTaskUri(task, templateId), + body, + ); return response.map(parse); } @@ -433,13 +455,13 @@ abstract class BaseTemplateApiClientModel extends BaseApiClientModel { Object? _serializeTemplateInputValue(Object? value) { return switch (value) { InlineDataPart(:final mimeType, :final bytes) => { - 'isInline': true, - 'mimeType': mimeType, - 'contents': base64Encode(bytes), - }, + 'isInline': true, + 'mimeType': mimeType, + 'contents': base64Encode(bytes), + }, Map() => value.map((key, nestedValue) { - return MapEntry(key, _serializeTemplateInputValue(nestedValue)); - }), + return MapEntry(key, _serializeTemplateInputValue(nestedValue)); + }), List() => value.map(_serializeTemplateInputValue).toList(growable: false), _ => value, diff --git a/packages/firebase_ai/firebase_ai/lib/src/chat.dart b/packages/firebase_ai/firebase_ai/lib/src/chat.dart index f460b3749a60..dd5cd558374a 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/chat.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/chat.dart @@ -29,25 +29,31 @@ import 'utils/mutex.dart'; /// response. The history reflects the most current state of the chat session. final class ChatSession { ChatSession._( - this._generateContent, - this._generateContentStream, - this._history, - this._safetySettings, - this._generationConfig, - List? tools, - this._maxTurns) - : _autoFunctionDeclarations = tools - ?.expand((tool) => tool.autoFunctionDeclarations) - .fold({}, (map, function) { - map?[function.name] = function; - return map; - }); - final Future Function(Iterable content, - {List? safetySettings, - GenerationConfig? generationConfig}) _generateContent; - final Stream Function(Iterable content, - {List? safetySettings, - GenerationConfig? generationConfig}) _generateContentStream; + this._generateContent, + this._generateContentStream, + this._history, + this._safetySettings, + this._generationConfig, + List? tools, + this._maxTurns, + ) : _autoFunctionDeclarations = tools + ?.expand((tool) => tool.autoFunctionDeclarations) + .fold({}, (map, function) { + map?[function.name] = function; + return map; + }); + final Future Function( + Iterable content, { + List? safetySettings, + GenerationConfig? generationConfig, + }) + _generateContent; + final Stream Function( + Iterable content, { + List? safetySettings, + GenerationConfig? generationConfig, + }) + _generateContentStream; final _mutex = Mutex(); @@ -85,9 +91,10 @@ final class ChatSession { var turn = 0; while (turn < _maxTurns) { final response = await _generateContent( - _history.followedBy(requestHistory), - safetySettings: _safetySettings, - generationConfig: _generationConfig); + _history.followedBy(requestHistory), + safetySettings: _safetySettings, + generationConfig: _generationConfig, + ); final functionCalls = response.functionCalls; @@ -95,11 +102,13 @@ final class ChatSession { // 1. We have auto-functions configured. // 2. The response actually contains function calls. // 3. ALL called functions exist in our declarations (prevents crashes). - final shouldAutoExecute = _autoFunctionDeclarations != null && + final shouldAutoExecute = + _autoFunctionDeclarations != null && _autoFunctionDeclarations.isNotEmpty && functionCalls.isNotEmpty && - functionCalls - .every((c) => _autoFunctionDeclarations.containsKey(c.name)); + functionCalls.every( + (c) => _autoFunctionDeclarations.containsKey(c.name), + ); if (!shouldAutoExecute) { // Standard handling: Update history and return the response to the user. if (response.candidates case [final candidate, ...]) { @@ -124,8 +133,9 @@ final class ChatSession { } catch (e) { result = e.toString(); } - functionResponses - .add(FunctionResponse(functionCall.name, {'result': result})); + functionResponses.add( + FunctionResponse(functionCall.name, {'result': result}), + ); } requestHistory.add(Content('function', functionResponses)); turn++; @@ -161,9 +171,10 @@ final class ChatSession { var turn = 0; while (turn < _maxTurns) { final responses = _generateContentStream( - _history.followedBy(requestHistory), - safetySettings: _safetySettings, - generationConfig: _generationConfig); + _history.followedBy(requestHistory), + safetySettings: _safetySettings, + generationConfig: _generationConfig, + ); final turnChunks = []; await for (final response in responses) { @@ -171,23 +182,28 @@ final class ChatSession { controller.add(response); } if (turnChunks.isEmpty) break; - final aggregatedContent = historyAggregate(turnChunks.map((r) { - final content = r.candidates.firstOrNull?.content; - if (content == null) { - throw Exception('No content in response candidate'); - } - return content; - }).toList()); + final aggregatedContent = historyAggregate( + turnChunks.map((r) { + final content = r.candidates.firstOrNull?.content; + if (content == null) { + throw Exception('No content in response candidate'); + } + return content; + }).toList(), + ); - final functionCalls = - aggregatedContent.parts.whereType().toList(); + final functionCalls = aggregatedContent.parts + .whereType() + .toList(); // Check if we should actually execute these functions. - final shouldAutoExecute = _autoFunctionDeclarations != null && + final shouldAutoExecute = + _autoFunctionDeclarations != null && _autoFunctionDeclarations.isNotEmpty && functionCalls.isNotEmpty && - functionCalls - .every((c) => _autoFunctionDeclarations.containsKey(c.name)); + functionCalls.every( + (c) => _autoFunctionDeclarations.containsKey(c.name), + ); if (!shouldAutoExecute) { _history.addAll(requestHistory); @@ -196,8 +212,9 @@ final class ChatSession { } requestHistory.add(aggregatedContent); - final functionResponseFutures = - functionCalls.map((functionCall) async { + final functionResponseFutures = functionCalls.map(( + functionCall, + ) async { final function = _autoFunctionDeclarations[functionCall.name]; Object? result; @@ -208,8 +225,9 @@ final class ChatSession { } return FunctionResponse(functionCall.name, {'result': result}); }); - final functionResponseParts = - await Future.wait(functionResponseFutures); + final functionResponseParts = await Future.wait( + functionResponseFutures, + ); requestHistory.add(Content.functionResponses(functionResponseParts)); turn++; } @@ -234,11 +252,18 @@ extension StartChatExtension on GenerativeModel { /// final response = await chat.sendMessage(Content.text('Hello there.')); /// print(response.text); /// ``` - ChatSession startChat( - {List? history, - List? safetySettings, - GenerationConfig? generationConfig, - int? maxTurns}) => - ChatSession._(generateContent, generateContentStream, history ?? [], - safetySettings, generationConfig, tools, maxTurns ?? 5); + ChatSession startChat({ + List? history, + List? safetySettings, + GenerationConfig? generationConfig, + int? maxTurns, + }) => ChatSession._( + generateContent, + generateContentStream, + history ?? [], + safetySettings, + generationConfig, + tools, + maxTurns ?? 5, + ); } diff --git a/packages/firebase_ai/firebase_ai/lib/src/client.dart b/packages/firebase_ai/firebase_ai/lib/src/client.dart index e8fafa092f22..585abc69faa5 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/client.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/client.dart @@ -30,7 +30,9 @@ abstract interface class ApiClient { /// Function to make a stream request. Stream> streamRequest( - Uri uri, Map body); + Uri uri, + Map body, + ); } // Encodes first by `json.encode`, then `utf8.encode`. @@ -40,31 +42,32 @@ final _utf8Json = json.fuse(utf8); /// The http implementation of ApiClient final class HttpApiClient implements ApiClient { ///Constructor - HttpApiClient( - {required String apiKey, - http.Client? httpClient, - FutureOr> Function()? requestHeaders}) - : _apiKey = apiKey, - // package:http top-level helpers (http.post, Request.send) create and - // close a Client per call, which prevents TCP/TLS connection reuse. - _httpClient = httpClient ?? http.Client(), - _requestHeaders = requestHeaders; + HttpApiClient({ + required String apiKey, + http.Client? httpClient, + FutureOr> Function()? requestHeaders, + }) : _apiKey = apiKey, + // package:http top-level helpers (http.post, Request.send) create and + // close a Client per call, which prevents TCP/TLS connection reuse. + _httpClient = httpClient ?? http.Client(), + _requestHeaders = requestHeaders; final String _apiKey; final http.Client _httpClient; final FutureOr> Function()? _requestHeaders; Future> _headers() async => { - 'x-goog-api-key': _apiKey, - 'x-goog-api-client': clientName, - 'Content-Type': 'application/json', - if (_requestHeaders case final requestHeaders?) - ...await requestHeaders(), - }; + 'x-goog-api-key': _apiKey, + 'x-goog-api-client': clientName, + 'Content-Type': 'application/json', + if (_requestHeaders case final requestHeaders?) ...await requestHeaders(), + }; @override Future> makeRequest( - Uri uri, Map body) async { + Uri uri, + Map body, + ) async { final headers = await _headers(); final response = await _httpClient.post( uri, @@ -73,7 +76,8 @@ final class HttpApiClient implements ApiClient { ); if (response.statusCode >= 500) { throw FirebaseAIException( - 'Server Error [${response.statusCode}]: ${response.body}'); + 'Server Error [${response.statusCode}]: ${response.body}', + ); } return _utf8Json.decode(response.bodyBytes)! as Map; @@ -81,7 +85,9 @@ final class HttpApiClient implements ApiClient { @override Stream> streamRequest( - Uri uri, Map body) async* { + Uri uri, + Map body, + ) async* { Uri streamUri = uri.replace(queryParameters: {'alt': 'sse'}); final request = http.Request('POST', streamUri) ..bodyBytes = _utf8Json.encode(body) @@ -94,8 +100,9 @@ final class HttpApiClient implements ApiClient { yield jsonDecode(body) as Map; return; } - final lines = - response.stream.toStringStream().transform(const LineSplitter()); + final lines = response.stream.toStringStream().transform( + const LineSplitter(), + ); await for (final line in lines) { const dataPrefix = 'data: '; if (line.startsWith(dataPrefix)) { diff --git a/packages/firebase_ai/firebase_ai/lib/src/content.dart b/packages/firebase_ai/firebase_ai/lib/src/content.dart index 64f31365b650..56aace1614a7 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/content.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/content.dart @@ -41,10 +41,13 @@ final class Content { static Content text(String text) => Content('user', [TextPart(text)]); /// Return a [Content] with [InlineDataPart]. - static Content inlineData(String mimeType, Uint8List bytes, - {MediaResolution? mediaResolution}) => - Content('user', - [InlineDataPart(mimeType, bytes, mediaResolution: mediaResolution)]); + static Content inlineData( + String mimeType, + Uint8List bytes, { + MediaResolution? mediaResolution, + }) => Content('user', [ + InlineDataPart(mimeType, bytes, mediaResolution: mediaResolution), + ]); /// Return a [Content] with multiple [Part]s. static Content multi(Iterable parts) => Content('user', [...parts]); @@ -53,9 +56,11 @@ final class Content { static Content model(Iterable parts) => Content('model', [...parts]); /// Return a [Content] with [FunctionResponse]. - static Content functionResponse(String name, Map response, - {String? id}) => - Content('function', [FunctionResponse(name, response, id: id)]); + static Content functionResponse( + String name, + Map response, { + String? id, + }) => Content('function', [FunctionResponse(name, response, id: id)]); /// Return a [Content] with multiple [FunctionResponse]. static Content functionResponses(Iterable responses) => @@ -67,22 +72,28 @@ final class Content { /// Convert the [Content] to json format. Map toJson() => { - if (role case final role?) 'role': role, - 'parts': parts.map((p) { - return p.toJson(); - }).toList(), - }; + if (role case final role?) 'role': role, + 'parts': parts.map((p) { + return p.toJson(); + }).toList(), + }; } /// Parse the [Content] from json object. Content parseContent(Object jsonObject) { return switch (jsonObject) { - {'role': final String role, 'parts': final List parts} => - Content(role, parts.map(parsePart).toList()), - {'role': final String role} => - Content(role, []), // Handle case with only role + {'role': final String role, 'parts': final List parts} => Content( + role, + parts.map(parsePart).toList(), + ), + {'role': final String role} => Content( + role, + [], + ), // Handle case with only role {'parts': final List parts} => Content( - null, parts.map(parsePart).toList()), // Handle case with only parts + null, + parts.map(parsePart).toList(), + ), // Handle case with only parts _ => throw unhandledFormat('Content', jsonObject), }; } @@ -91,9 +102,7 @@ Content parseContent(Object jsonObject) { Part parsePart(Object? jsonObject) { if (jsonObject is! Map) { log('Unhandled part format: $jsonObject'); - return UnknownPart({ - 'unhandled': jsonObject, - }); + return UnknownPart({'unhandled': jsonObject}); } final isThought = @@ -172,22 +181,28 @@ Part parsePart(Object? jsonObject) { } } return switch (jsonObject) { - {'text': final String text} => TextPart._(text, - isThought: isThought, thoughtSignature: thoughtSignature), + {'text': final String text} => TextPart._( + text, + isThought: isThought, + thoughtSignature: thoughtSignature, + ), { 'file_data': { 'file_uri': final String fileUri, 'mime_type': final String mimeType, - } + }, } => - FileData._(mimeType, fileUri, - mediaResolution: mediaResolution, - isThought: isThought, - thoughtSignature: thoughtSignature), + FileData._( + mimeType, + fileUri, + mediaResolution: mediaResolution, + isThought: isThought, + thoughtSignature: thoughtSignature, + ), _ => () { - log('unhandled part format: $jsonObject'); - return UnknownPart(jsonObject); - }(), + log('unhandled part format: $jsonObject'); + return UnknownPart(jsonObject); + }(), }; } @@ -195,7 +210,7 @@ Part parsePart(Object? jsonObject) { sealed class Part { // ignore: public_member_api_docs const Part({this.isThought, String? thoughtSignature}) - : _thoughtSignature = thoughtSignature; + : _thoughtSignature = thoughtSignature; // ignore: public_member_api_docs final bool? isThought; @@ -204,10 +219,10 @@ sealed class Part { /// Convert the [Part] content to json format. Object toJson() => { - if (isThought case final isThought?) 'thought': isThought, - if (_thoughtSignature case final thoughtSignature?) - 'thoughtSignature': thoughtSignature, - }; + if (isThought case final isThought?) 'thought': isThought, + if (_thoughtSignature case final thoughtSignature?) + 'thoughtSignature': thoughtSignature, + }; } /// A [Part] that contains unparsable data. @@ -229,30 +244,15 @@ final class UnknownPart extends Part { final class TextPart extends Part { // ignore: public_member_api_docs const TextPart(this.text, {bool? isThought}) - : super( - isThought: isThought, - thoughtSignature: null, - ); + : super(isThought: isThought, thoughtSignature: null); @visibleForTesting // ignore: public_member_api_docs - const TextPart.forTest( - this.text, { - bool? isThought, - String? thoughtSignature, - }) : super( - isThought: isThought, - thoughtSignature: thoughtSignature, - ); + const TextPart.forTest(this.text, {bool? isThought, String? thoughtSignature}) + : super(isThought: isThought, thoughtSignature: thoughtSignature); - const TextPart._( - this.text, { - bool? isThought, - String? thoughtSignature, - }) : super( - isThought: isThought, - thoughtSignature: thoughtSignature, - ); + const TextPart._(this.text, {bool? isThought, String? thoughtSignature}) + : super(isThought: isThought, thoughtSignature: thoughtSignature); /// The text content of the [Part] final String text; @@ -272,10 +272,7 @@ final class InlineDataPart extends Part { this.willContinue, this.mediaResolution, bool? isThought, - }) : super( - isThought: isThought, - thoughtSignature: null, - ); + }) : super(isThought: isThought, thoughtSignature: null); @visibleForTesting // ignore: public_member_api_docs @@ -286,10 +283,7 @@ final class InlineDataPart extends Part { this.mediaResolution, bool? isThought, String? thoughtSignature, - }) : super( - isThought: isThought, - thoughtSignature: thoughtSignature, - ); + }) : super(isThought: isThought, thoughtSignature: thoughtSignature); const InlineDataPart._( this.mimeType, @@ -298,10 +292,7 @@ final class InlineDataPart extends Part { this.mediaResolution, bool? isThought, String? thoughtSignature, - }) : super( - isThought: isThought, - thoughtSignature: thoughtSignature, - ); + }) : super(isThought: isThought, thoughtSignature: thoughtSignature); /// File type of the [InlineDataPart]. /// @@ -336,10 +327,10 @@ final class InlineDataPart extends Part { /// The representation of the data in media streaming chunk. Object toMediaChunkJson() => { - 'mimeType': mimeType, - 'data': base64Encode(bytes), - if (willContinue != null) 'willContinue': willContinue, - }; + 'mimeType': mimeType, + 'data': base64Encode(bytes), + if (willContinue != null) 'willContinue': willContinue, + }; } /// A predicted `FunctionCall` returned from the model that contains @@ -347,15 +338,8 @@ final class InlineDataPart extends Part { /// arguments and their values. final class FunctionCall extends Part { // ignore: public_member_api_docs - const FunctionCall( - this.name, - this.args, { - this.id, - bool? isThought, - }) : super( - isThought: isThought, - thoughtSignature: null, - ); + const FunctionCall(this.name, this.args, {this.id, bool? isThought}) + : super(isThought: isThought, thoughtSignature: null); @visibleForTesting // ignore: public_member_api_docs @@ -365,10 +349,7 @@ final class FunctionCall extends Part { this.id, bool? isThought, String? thoughtSignature, - }) : super( - isThought: isThought, - thoughtSignature: thoughtSignature, - ); + }) : super(isThought: isThought, thoughtSignature: thoughtSignature); const FunctionCall._( this.name, @@ -376,10 +357,7 @@ final class FunctionCall extends Part { this.id, bool? isThought, String? thoughtSignature, - }) : super( - isThought: isThought, - thoughtSignature: thoughtSignature, - ); + }) : super(isThought: isThought, thoughtSignature: thoughtSignature); /// The name of the function to call. final String name; @@ -398,11 +376,7 @@ final class FunctionCall extends Part { final superJson = super.toJson() as Map; return { ...superJson, - 'functionCall': { - 'name': name, - 'args': args, - if (id != null) 'id': id, - }, + 'functionCall': {'name': name, 'args': args, if (id != null) 'id': id}, }; } } @@ -410,15 +384,8 @@ final class FunctionCall extends Part { /// The response class for [FunctionCall] final class FunctionResponse extends Part { // ignore: public_member_api_docs - const FunctionResponse( - this.name, - this.response, { - this.id, - bool? isThought, - }) : super( - isThought: isThought, - thoughtSignature: null, - ); + const FunctionResponse(this.name, this.response, {this.id, bool? isThought}) + : super(isThought: isThought, thoughtSignature: null); /// The name of the function that was called. final String name; @@ -456,10 +423,7 @@ final class FileData extends Part { this.fileUri, { this.mediaResolution, bool? isThought, - }) : super( - isThought: isThought, - thoughtSignature: null, - ); + }) : super(isThought: isThought, thoughtSignature: null); @visibleForTesting // ignore: public_member_api_docs @@ -469,10 +433,7 @@ final class FileData extends Part { this.mediaResolution, bool? isThought, String? thoughtSignature, - }) : super( - isThought: isThought, - thoughtSignature: thoughtSignature, - ); + }) : super(isThought: isThought, thoughtSignature: thoughtSignature); const FileData._( this.mimeType, @@ -480,10 +441,7 @@ final class FileData extends Part { this.mediaResolution, bool? isThought, String? thoughtSignature, - }) : super( - isThought: isThought, - thoughtSignature: thoughtSignature, - ); + }) : super(isThought: isThought, thoughtSignature: thoughtSignature); /// File type of the [FileData]. /// @@ -517,20 +475,14 @@ final class ExecutableCodePart extends Part { required this.language, required this.code, bool? isThought, - }) : super( - isThought: isThought, - thoughtSignature: null, - ); + }) : super(isThought: isThought, thoughtSignature: null); ExecutableCodePart._({ required this.language, required this.code, bool? isThought, String? thoughtSignature, - }) : super( - isThought: isThought, - thoughtSignature: thoughtSignature, - ); + }) : super(isThought: isThought, thoughtSignature: thoughtSignature); /// The programming language of the code. final CodeLanguage language; @@ -555,20 +507,14 @@ final class CodeExecutionResultPart extends Part { required this.outcome, required this.output, bool? isThought, - }) : super( - isThought: isThought, - thoughtSignature: null, - ); + }) : super(isThought: isThought, thoughtSignature: null); CodeExecutionResultPart._({ required this.outcome, required this.output, bool? isThought, String? thoughtSignature, - }) : super( - isThought: isThought, - thoughtSignature: thoughtSignature, - ); + }) : super(isThought: isThought, thoughtSignature: thoughtSignature); /// The result of the execution. final Outcome outcome; diff --git a/packages/firebase_ai/firebase_ai/lib/src/developer/api.dart b/packages/firebase_ai/firebase_ai/lib/src/developer/api.dart index b27eec0d325d..144f98720835 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/developer/api.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/developer/api.dart @@ -45,27 +45,26 @@ String _harmBlockThresholdToJson(HarmBlockThreshold? threshold) => HarmBlockThreshold.off => 'OFF', }; String _harmCategoryToJson(HarmCategory harmCategory) => switch (harmCategory) { - HarmCategory.unknown => 'HARM_CATEGORY_UNSPECIFIED', - HarmCategory.harassment => 'HARM_CATEGORY_HARASSMENT', - HarmCategory.hateSpeech => 'HARM_CATEGORY_HATE_SPEECH', - HarmCategory.sexuallyExplicit => 'HARM_CATEGORY_SEXUALLY_EXPLICIT', - HarmCategory.dangerousContent => 'HARM_CATEGORY_DANGEROUS_CONTENT', - HarmCategory.imageHate => 'HARM_CATEGORY_IMAGE_HATE', - HarmCategory.imageDangerousContent => - 'HARM_CATEGORY_IMAGE_DANGEROUS_CONTENT', - HarmCategory.imageHarassment => 'HARM_CATEGORY_IMAGE_HARASSMENT', - HarmCategory.imageSexuallyExplicit => - 'HARM_CATEGORY_IMAGE_SEXUALLY_EXPLICIT', - }; + HarmCategory.unknown => 'HARM_CATEGORY_UNSPECIFIED', + HarmCategory.harassment => 'HARM_CATEGORY_HARASSMENT', + HarmCategory.hateSpeech => 'HARM_CATEGORY_HATE_SPEECH', + HarmCategory.sexuallyExplicit => 'HARM_CATEGORY_SEXUALLY_EXPLICIT', + HarmCategory.dangerousContent => 'HARM_CATEGORY_DANGEROUS_CONTENT', + HarmCategory.imageHate => 'HARM_CATEGORY_IMAGE_HATE', + HarmCategory.imageDangerousContent => 'HARM_CATEGORY_IMAGE_DANGEROUS_CONTENT', + HarmCategory.imageHarassment => 'HARM_CATEGORY_IMAGE_HARASSMENT', + HarmCategory.imageSexuallyExplicit => 'HARM_CATEGORY_IMAGE_SEXUALLY_EXPLICIT', +}; Object _safetySettingToJson(SafetySetting safetySetting) { if (safetySetting.method != null) { throw ArgumentError( - 'HarmBlockMethod is not supported by google AI and must be left null.'); + 'HarmBlockMethod is not supported by google AI and must be left null.', + ); } return { 'category': _harmCategoryToJson(safetySetting.category), - 'threshold': _harmBlockThresholdToJson(safetySetting.threshold) + 'threshold': _harmBlockThresholdToJson(safetySetting.threshold), }; } @@ -77,20 +76,25 @@ final class DeveloperSerialization implements SerializationStrategy { final candidates = switch (jsonObject) { {'candidates': final List candidates} => candidates.map(_parseCandidate).toList(), - _ => [] + _ => [], }; final promptFeedback = switch (jsonObject) { - {'promptFeedback': final promptFeedback?} => - _parsePromptFeedback(promptFeedback), + {'promptFeedback': final promptFeedback?} => _parsePromptFeedback( + promptFeedback, + ), _ => null, }; final usageMetadata = switch (jsonObject) { - {'usageMetadata': final usageMetadata?} => - parseUsageMetadata(usageMetadata), + {'usageMetadata': final usageMetadata?} => parseUsageMetadata( + usageMetadata, + ), _ => null, }; - return GenerateContentResponse(candidates, promptFeedback, - usageMetadata: usageMetadata); + return GenerateContentResponse( + candidates, + promptFeedback, + usageMetadata: usageMetadata, + ); } @override @@ -134,18 +138,17 @@ final class DeveloperSerialization implements SerializationStrategy { GenerationConfig? generationConfig, List? tools, ToolConfig? toolConfig, - ) => - { - 'generateContentRequest': generateContentRequest( - contents, - model, - safetySettings, - generationConfig, - tools, - toolConfig, - null, - ) - }; + ) => { + 'generateContentRequest': generateContentRequest( + contents, + model, + safetySettings, + generationConfig, + tools, + toolConfig, + null, + ), + }; } // Developer API and Agent Platform has different _parseSafetyRating logic. @@ -161,31 +164,32 @@ Candidate _parseCandidate(Object? jsonObject) { switch (jsonObject) { {'safetyRatings': final List safetyRatings} => safetyRatings.map(_parseSafetyRating).toList(), - _ => null + _ => null, }, switch (jsonObject) { {'citationMetadata': final Object citationMetadata} => parseCitationMetadata(citationMetadata), - _ => null + _ => null, }, switch (jsonObject) { - {'finishReason': final Object finishReason} => - FinishReason.parseValue(finishReason), - _ => null + {'finishReason': final Object finishReason} => FinishReason.parseValue( + finishReason, + ), + _ => null, }, switch (jsonObject) { {'finishMessage': final String finishMessage} => finishMessage, - _ => null + _ => null, }, groundingMetadata: switch (jsonObject) { {'groundingMetadata': final Object groundingMetadata} => parseGroundingMetadata(groundingMetadata), - _ => null + _ => null, }, urlContextMetadata: switch (jsonObject) { {'urlContextMetadata': final Object urlContextMetadata} => parseUrlContextMetadata(urlContextMetadata), - _ => null + _ => null, }, ); } @@ -193,21 +197,20 @@ Candidate _parseCandidate(Object? jsonObject) { // Developer API and Agent Platform has different _parseSafetyRating logic. PromptFeedback _parsePromptFeedback(Object jsonObject) { return switch (jsonObject) { - { - 'safetyRatings': final List safetyRatings, - } => - PromptFeedback( - switch (jsonObject) { - {'blockReason': final String blockReason} => - BlockReason.parseValue(blockReason), - _ => null, - }, - switch (jsonObject) { - {'blockReasonMessage': final String blockReasonMessage} => - blockReasonMessage, - _ => null, - }, - safetyRatings.map(_parseSafetyRating).toList()), + {'safetyRatings': final List safetyRatings} => PromptFeedback( + switch (jsonObject) { + {'blockReason': final String blockReason} => BlockReason.parseValue( + blockReason, + ), + _ => null, + }, + switch (jsonObject) { + {'blockReasonMessage': final String blockReasonMessage} => + blockReasonMessage, + _ => null, + }, + safetyRatings.map(_parseSafetyRating).toList(), + ), _ => throw unhandledFormat('PromptFeedback', jsonObject), }; } @@ -220,14 +223,18 @@ SafetyRating _parseSafetyRating(Object? jsonObject) { 'blocked': final bool? isBlocked, } => SafetyRating( - _parseHarmCategory(category), _parseHarmProbability(probability), - isBlocked: isBlocked), + _parseHarmCategory(category), + _parseHarmProbability(probability), + isBlocked: isBlocked, + ), { 'category': final Object category, 'probability': final Object probability, } => SafetyRating( - _parseHarmCategory(category), _parseHarmProbability(probability)), + _parseHarmCategory(category), + _parseHarmProbability(probability), + ), _ => throw unhandledFormat('SafetyRating', jsonObject), }; } @@ -242,16 +249,14 @@ HarmProbability _parseHarmProbability(Object jsonObject) => _ => throw unhandledFormat('HarmProbability', jsonObject), }; HarmCategory _parseHarmCategory(Object jsonObject) => switch (jsonObject) { - 'HARM_CATEGORY_UNSPECIFIED' => HarmCategory.unknown, - 'HARM_CATEGORY_HARASSMENT' => HarmCategory.harassment, - 'HARM_CATEGORY_HATE_SPEECH' => HarmCategory.hateSpeech, - 'HARM_CATEGORY_SEXUALLY_EXPLICIT' => HarmCategory.sexuallyExplicit, - 'HARM_CATEGORY_DANGEROUS_CONTENT' => HarmCategory.dangerousContent, - 'HARM_CATEGORY_IMAGE_HATE' => HarmCategory.imageHate, - 'HARM_CATEGORY_IMAGE_DANGEROUS_CONTENT' => - HarmCategory.imageDangerousContent, - 'HARM_CATEGORY_IMAGE_HARASSMENT' => HarmCategory.imageHarassment, - 'HARM_CATEGORY_IMAGE_SEXUALLY_EXPLICIT' => - HarmCategory.imageSexuallyExplicit, - _ => HarmCategory.unknown, - }; + 'HARM_CATEGORY_UNSPECIFIED' => HarmCategory.unknown, + 'HARM_CATEGORY_HARASSMENT' => HarmCategory.harassment, + 'HARM_CATEGORY_HATE_SPEECH' => HarmCategory.hateSpeech, + 'HARM_CATEGORY_SEXUALLY_EXPLICIT' => HarmCategory.sexuallyExplicit, + 'HARM_CATEGORY_DANGEROUS_CONTENT' => HarmCategory.dangerousContent, + 'HARM_CATEGORY_IMAGE_HATE' => HarmCategory.imageHate, + 'HARM_CATEGORY_IMAGE_DANGEROUS_CONTENT' => HarmCategory.imageDangerousContent, + 'HARM_CATEGORY_IMAGE_HARASSMENT' => HarmCategory.imageHarassment, + 'HARM_CATEGORY_IMAGE_SEXUALLY_EXPLICIT' => HarmCategory.imageSexuallyExplicit, + _ => HarmCategory.unknown, +}; diff --git a/packages/firebase_ai/firebase_ai/lib/src/error.dart b/packages/firebase_ai/firebase_ai/lib/src/error.dart index 5f438fa4496f..fcfaf2096921 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/error.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/error.dart @@ -101,7 +101,8 @@ final class FirebaseAISdkException implements Exception { final String message; @override - String toString() => '$message\n' + String toString() => + '$message\n' 'This indicates a problem with the Firebase AI Logic SDK. ' 'Try updating to the latest version ' '(https://pub.dev/packages/firebase_ai/versions), ' @@ -152,7 +153,7 @@ FirebaseAIException parseError(Object jsonObject) { return switch (jsonObject) { { 'message': final String message, - 'details': [{'reason': 'API_KEY_INVALID'}, ...] + 'details': [{'reason': 'API_KEY_INVALID'}, ...], } => InvalidApiKey(message), {'message': UnsupportedUserLocation._message} => UnsupportedUserLocation(), @@ -168,13 +169,13 @@ FirebaseAIException parseError(Object jsonObject) { 'metadata': { 'service': 'firebasevertexai.googleapis.com', 'consumer': final String projectId, - } + }, }, - ] + ], } => ServiceApiNotEnabled(projectId), {'message': final String message} => ServerException(message), - _ => throw unhandledFormat('server error', jsonObject) + _ => throw unhandledFormat('server error', jsonObject), }; } diff --git a/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart b/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart index 188e46dc015d..d7d4b6e0d610 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/firebase_ai.dart @@ -35,8 +35,8 @@ class FirebaseAI extends FirebasePlugin { this.appCheck, this.auth, this.useLimitedUseAppCheckTokens = false, - }) : _useAgentPlatform = useAgentPlatform, - super(app.name, 'plugins.flutter.io/firebase_vertexai'); + }) : _useAgentPlatform = useAgentPlatform, + super(app.name, 'plugins.flutter.io/firebase_vertexai'); /// The [FirebaseApp] for this current [FirebaseAI] instance. FirebaseApp app; @@ -63,14 +63,17 @@ class FirebaseAI extends FirebasePlugin { /// If [app] is not provided, the default Firebase app will be used. /// If pass in [appCheck], request session will get protected from abusing. @Deprecated( - 'Use agentPlatform() instead. Note that the default location for agentPlatform is now "global" instead of "us-central1"') + 'Use agentPlatform() instead. Note that the default location for agentPlatform is now "global" instead of "us-central1"', + ) static FirebaseAI vertexAI({ FirebaseApp? app, @Deprecated( - 'Passing an explicit instance is deprecated, internal handling is now automatic.') + 'Passing an explicit instance is deprecated, internal handling is now automatic.', + ) FirebaseAppCheck? appCheck, @Deprecated( - 'Passing an explicit instance is deprecated, internal handling is now automatic.') + 'Passing an explicit instance is deprecated, internal handling is now automatic.', + ) FirebaseAuth? auth, String? location, bool? useLimitedUseAppCheckTokens, @@ -136,10 +139,12 @@ class FirebaseAI extends FirebasePlugin { static FirebaseAI googleAI({ FirebaseApp? app, @Deprecated( - 'Passing an explicit instance is deprecated, internal handling is now automatic.') + 'Passing an explicit instance is deprecated, internal handling is now automatic.', + ) FirebaseAppCheck? appCheck, @Deprecated( - 'Passing an explicit instance is deprecated, internal handling is now automatic.') + 'Passing an explicit instance is deprecated, internal handling is now automatic.', + ) FirebaseAuth? auth, bool? useLimitedUseAppCheckTokens, }) { @@ -235,11 +240,12 @@ class FirebaseAI extends FirebasePlugin { @experimental TemplateGenerativeModel templateGenerativeModel() { return createTemplateGenerativeModel( - app: app, - location: location, - useAgentPlatform: _useAgentPlatform, - useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, - auth: auth, - appCheck: appCheck); + app: app, + location: location, + useAgentPlatform: _useAgentPlatform, + useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, + auth: auth, + appCheck: appCheck, + ); } } diff --git a/packages/firebase_ai/firebase_ai/lib/src/generative_model.dart b/packages/firebase_ai/firebase_ai/lib/src/generative_model.dart index 347eaf8b589c..a1eda95288eb 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/generative_model.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/generative_model.dart @@ -46,22 +46,28 @@ final class GenerativeModel extends BaseApiClientModel { ToolConfig? toolConfig, Content? systemInstruction, http.Client? httpClient, - }) : _safetySettings = safetySettings ?? [], - _generationConfig = generationConfig, - _toolConfig = toolConfig, - _systemInstruction = systemInstruction, - super( - serializationStrategy: useAgentPlatform - ? AgentPlatformSerialization() - : DeveloperSerialization(), - modelUri: useAgentPlatform - ? _AgentPlatformUri(app: app, model: model, location: location) - : _GoogleAIUri(app: app, model: model), - client: HttpApiClient( - apiKey: app.options.apiKey, - httpClient: httpClient, - requestHeaders: BaseModel.firebaseTokens( - appCheck, auth, app, useLimitedUseAppCheckTokens))); + }) : _safetySettings = safetySettings ?? [], + _generationConfig = generationConfig, + _toolConfig = toolConfig, + _systemInstruction = systemInstruction, + super( + serializationStrategy: useAgentPlatform + ? AgentPlatformSerialization() + : DeveloperSerialization(), + modelUri: useAgentPlatform + ? _AgentPlatformUri(app: app, model: model, location: location) + : _GoogleAIUri(app: app, model: model), + client: HttpApiClient( + apiKey: app.options.apiKey, + httpClient: httpClient, + requestHeaders: BaseModel.firebaseTokens( + appCheck, + auth, + app, + useLimitedUseAppCheckTokens, + ), + ), + ); GenerativeModel._constructTestModel({ required String model, @@ -77,22 +83,29 @@ final class GenerativeModel extends BaseApiClientModel { ToolConfig? toolConfig, Content? systemInstruction, ApiClient? apiClient, - }) : _safetySettings = safetySettings ?? [], - _generationConfig = generationConfig, - _toolConfig = toolConfig, - _systemInstruction = systemInstruction, - super( - serializationStrategy: useAgentPlatform - ? AgentPlatformSerialization() - : DeveloperSerialization(), - modelUri: useAgentPlatform - ? _AgentPlatformUri(app: app, model: model, location: location) - : _GoogleAIUri(app: app, model: model), - client: apiClient ?? - HttpApiClient( - apiKey: app.options.apiKey, - requestHeaders: BaseModel.firebaseTokens( - appCheck, auth, app, useLimitedUseAppCheckTokens))); + }) : _safetySettings = safetySettings ?? [], + _generationConfig = generationConfig, + _toolConfig = toolConfig, + _systemInstruction = systemInstruction, + super( + serializationStrategy: useAgentPlatform + ? AgentPlatformSerialization() + : DeveloperSerialization(), + modelUri: useAgentPlatform + ? _AgentPlatformUri(app: app, model: model, location: location) + : _GoogleAIUri(app: app, model: model), + client: + apiClient ?? + HttpApiClient( + apiKey: app.options.apiKey, + requestHeaders: BaseModel.firebaseTokens( + appCheck, + auth, + app, + useLimitedUseAppCheckTokens, + ), + ), + ); final List _safetySettings; final GenerationConfig? _generationConfig; @@ -113,23 +126,25 @@ final class GenerativeModel extends BaseApiClientModel { /// final response = await model.generateContent([Content.text(prompt)]); /// print(response.text); /// ``` - Future generateContent(Iterable prompt, - {List? safetySettings, - GenerationConfig? generationConfig, - List? tools, - ToolConfig? toolConfig}) => - makeRequest( - Task.generateContent, - _serializationStrategy.generateContentRequest( - prompt, - model, - safetySettings ?? _safetySettings, - generationConfig ?? _generationConfig, - tools ?? this.tools, - toolConfig ?? _toolConfig, - _systemInstruction, - ), - _serializationStrategy.parseGenerateContentResponse); + Future generateContent( + Iterable prompt, { + List? safetySettings, + GenerationConfig? generationConfig, + List? tools, + ToolConfig? toolConfig, + }) => makeRequest( + Task.generateContent, + _serializationStrategy.generateContentRequest( + prompt, + model, + safetySettings ?? _safetySettings, + generationConfig ?? _generationConfig, + tools ?? this.tools, + toolConfig ?? _toolConfig, + _systemInstruction, + ), + _serializationStrategy.parseGenerateContentResponse, + ); /// Generates a stream of content responding to [prompt]. /// @@ -144,22 +159,24 @@ final class GenerativeModel extends BaseApiClientModel { /// } /// ``` Stream generateContentStream( - Iterable prompt, - {List? safetySettings, - GenerationConfig? generationConfig, - List? tools, - ToolConfig? toolConfig}) { + Iterable prompt, { + List? safetySettings, + GenerationConfig? generationConfig, + List? tools, + ToolConfig? toolConfig, + }) { final response = client.streamRequest( - taskUri(Task.streamGenerateContent), - _serializationStrategy.generateContentRequest( - prompt, - model, - safetySettings ?? _safetySettings, - generationConfig ?? _generationConfig, - tools ?? this.tools, - toolConfig ?? _toolConfig, - _systemInstruction, - )); + taskUri(Task.streamGenerateContent), + _serializationStrategy.generateContentRequest( + prompt, + model, + safetySettings ?? _safetySettings, + generationConfig ?? _generationConfig, + tools ?? this.tools, + toolConfig ?? _toolConfig, + _systemInstruction, + ), + ); return response.map(_serializationStrategy.parseGenerateContentResponse); } @@ -180,9 +197,7 @@ final class GenerativeModel extends BaseApiClientModel { /// print(response.text); /// } /// ``` - Future countTokens( - Iterable contents, - ) async { + Future countTokens(Iterable contents) async { final parameters = _serializationStrategy.countTokensRequest( contents, model, @@ -191,8 +206,11 @@ final class GenerativeModel extends BaseApiClientModel { tools, _toolConfig, ); - return makeRequest(Task.countTokens, parameters, - _serializationStrategy.parseCountTokensResponse); + return makeRequest( + Task.countTokens, + parameters, + _serializationStrategy.parseCountTokensResponse, + ); } } @@ -211,22 +229,21 @@ GenerativeModel createGenerativeModel({ ToolConfig? toolConfig, Content? systemInstruction, http.Client? httpClient, -}) => - GenerativeModel._( - model: model, - app: app, - appCheck: appCheck, - useAgentPlatform: useAgentPlatform, - useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, - auth: auth, - location: location, - safetySettings: safetySettings, - generationConfig: generationConfig, - tools: tools, - toolConfig: toolConfig, - systemInstruction: systemInstruction, - httpClient: httpClient, - ); +}) => GenerativeModel._( + model: model, + app: app, + appCheck: appCheck, + useAgentPlatform: useAgentPlatform, + useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, + auth: auth, + location: location, + safetySettings: safetySettings, + generationConfig: generationConfig, + tools: tools, + toolConfig: toolConfig, + systemInstruction: systemInstruction, + httpClient: httpClient, +); /// Creates a model with an overridden [ApiClient] for testing. /// @@ -245,18 +262,18 @@ GenerativeModel createModelWithClient({ List? safetySettings, List? tools, ToolConfig? toolConfig, -}) => - GenerativeModel._constructTestModel( - model: model, - app: app, - appCheck: appCheck, - useAgentPlatform: useAgentPlatform, - useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, - auth: auth, - location: location, - safetySettings: safetySettings, - generationConfig: generationConfig, - systemInstruction: systemInstruction, - tools: tools, - toolConfig: toolConfig, - apiClient: client); +}) => GenerativeModel._constructTestModel( + model: model, + app: app, + appCheck: appCheck, + useAgentPlatform: useAgentPlatform, + useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, + auth: auth, + location: location, + safetySettings: safetySettings, + generationConfig: generationConfig, + systemInstruction: systemInstruction, + tools: tools, + toolConfig: toolConfig, + apiClient: client, +); diff --git a/packages/firebase_ai/firebase_ai/lib/src/image_config.dart b/packages/firebase_ai/firebase_ai/lib/src/image_config.dart index 277272b82c29..ff9e9f9be709 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/image_config.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/image_config.dart @@ -25,10 +25,10 @@ final class ImageConfig { /// Convert to json format. Map toJson() => { - if (aspectRatio case final aspectRatio?) - 'aspectRatio': aspectRatio.toJson(), - if (imageSize case final imageSize?) 'imageSize': imageSize.toJson(), - }; + if (aspectRatio case final aspectRatio?) + 'aspectRatio': aspectRatio.toJson(), + if (imageSize case final imageSize?) 'imageSize': imageSize.toJson(), + }; } /// An aspect ratio for generated images. diff --git a/packages/firebase_ai/firebase_ai/lib/src/live_api.dart b/packages/firebase_ai/firebase_ai/lib/src/live_api.dart index 91a706859cde..dc9ad8e28202 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/live_api.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/live_api.dart @@ -37,8 +37,9 @@ class SlidingWindow { /// The session reduction target, i.e., how many tokens we should keep. final int? targetTokens; // ignore: public_member_api_docs - Map toJson() => - {if (targetTokens case final targetTokens?) 'targetTokens': targetTokens}; + Map toJson() => { + if (targetTokens case final targetTokens?) 'targetTokens': targetTokens, + }; } /// Enables context window compression to manage the model's context window. @@ -61,11 +62,10 @@ class ContextWindowCompressionConfig { final SlidingWindow? slidingWindow; // ignore: public_member_api_docs Map toJson() => { - if (triggerTokens case final triggerTokens?) - 'triggerTokens': triggerTokens, - if (slidingWindow case final slidingWindow?) - 'slidingWindow': slidingWindow.toJson() - }; + if (triggerTokens case final triggerTokens?) 'triggerTokens': triggerTokens, + if (slidingWindow case final slidingWindow?) + 'slidingWindow': slidingWindow.toJson(), + }; } /// Configuration for the session resumption mechanism. @@ -94,8 +94,8 @@ class SessionResumptionConfig { // ignore: public_member_api_docs Map toJson() => { - if (handle case final handle?) 'handle': handle, - }; + if (handle case final handle?) 'handle': handle, + }; } /// Configures model input behavior when generating content in the Live API via the realtime supported methods. @@ -118,13 +118,13 @@ final class RealtimeInputConfig { // ignore: public_member_api_docs Map toJson() => { - if (automaticActivityDetection case final automaticActivityDetection?) - 'automatic_activity_detection': automaticActivityDetection.toJson(), - if (activityHandling case final activityHandling?) - 'activity_handling': activityHandling.value, - if (turnCoverage case final turnCoverage?) - 'turn_coverage': turnCoverage.value, - }; + if (automaticActivityDetection case final automaticActivityDetection?) + 'automatic_activity_detection': automaticActivityDetection.toJson(), + if (activityHandling case final activityHandling?) + 'activity_handling': activityHandling.value, + if (turnCoverage case final turnCoverage?) + 'turn_coverage': turnCoverage.value, + }; } /// Configures the model's automatic detection of user activity. @@ -136,11 +136,11 @@ final class ActivityDetectionConfig { int? prefixPaddingMS, int? silenceDurationMS, }) : this._( - startSensitivity: startSensitivity, - endSensitivity: endSensitivity, - prefixPaddingMS: prefixPaddingMS, - silenceDurationMS: silenceDurationMS, - ); + startSensitivity: startSensitivity, + endSensitivity: endSensitivity, + prefixPaddingMS: prefixPaddingMS, + silenceDurationMS: silenceDurationMS, + ); ActivityDetectionConfig._({ this.startSensitivity, @@ -152,9 +152,7 @@ final class ActivityDetectionConfig { /// Disables automatic activity detection. factory ActivityDetectionConfig.disabled() { - return ActivityDetectionConfig._( - disabled: true, - ); + return ActivityDetectionConfig._(disabled: true); } /// Determines how likely the start of speech is detected. @@ -174,16 +172,16 @@ final class ActivityDetectionConfig { // ignore: public_member_api_docs Map toJson() => { - if (startSensitivity case final startSensitivity?) - 'start_of_speech_sensitivity': 'START_${startSensitivity.value}', - if (endSensitivity case final endSensitivity?) - 'end_of_speech_sensitivity': 'END_${endSensitivity.value}', - if (prefixPaddingMS case final prefixPaddingMS?) - 'prefix_padding_ms': prefixPaddingMS, - if (silenceDurationMS case final silenceDurationMS?) - 'silence_duration_ms': silenceDurationMS, - if (disabled case final disabled?) 'disabled': disabled, - }; + if (startSensitivity case final startSensitivity?) + 'start_of_speech_sensitivity': 'START_${startSensitivity.value}', + if (endSensitivity case final endSensitivity?) + 'end_of_speech_sensitivity': 'END_${endSensitivity.value}', + if (prefixPaddingMS case final prefixPaddingMS?) + 'prefix_padding_ms': prefixPaddingMS, + if (silenceDurationMS case final silenceDurationMS?) + 'silence_duration_ms': silenceDurationMS, + if (disabled case final disabled?) 'disabled': disabled, + }; } /// How a model handles user input activity. @@ -234,20 +232,21 @@ enum Sensitivity { /// Configures live generation settings. final class LiveGenerationConfig extends BaseGenerationConfig { // ignore: public_member_api_docs - LiveGenerationConfig( - {super.speechConfig, - this.inputAudioTranscription, - this.outputAudioTranscription, - this.contextWindowCompression, - this.realtimeInputConfig, - super.responseModalities, - super.maxOutputTokens, - super.temperature, - super.topP, - super.topK, - super.presencePenalty, - super.frequencyPenalty, - super.mediaResolution}); + LiveGenerationConfig({ + super.speechConfig, + this.inputAudioTranscription, + this.outputAudioTranscription, + this.contextWindowCompression, + this.realtimeInputConfig, + super.responseModalities, + super.maxOutputTokens, + super.temperature, + super.topP, + super.topK, + super.presencePenalty, + super.frequencyPenalty, + super.mediaResolution, + }); /// The transcription of the input aligns with the input audio language. final AudioTranscriptionConfig? inputAudioTranscription; @@ -263,9 +262,7 @@ final class LiveGenerationConfig extends BaseGenerationConfig { final RealtimeInputConfig? realtimeInputConfig; @override - Map toJson() => { - ...super.toJson(), - }; + Map toJson() => {...super.toJson()}; } /// An abstract class representing a message received from a live server. @@ -302,12 +299,13 @@ class LiveServerContent implements LiveServerMessage { /// [interrupted] (optional): Indicates if the generation was interrupted. /// [inputTranscription] (optional): The input transcription. /// [outputTranscription] (optional): The output transcription. - LiveServerContent( - {this.modelTurn, - this.turnComplete, - this.interrupted, - this.inputTranscription, - this.outputTranscription}); + LiveServerContent({ + this.modelTurn, + this.turnComplete, + this.interrupted, + this.inputTranscription, + this.outputTranscription, + }); // TODO(cynthia): Add accessor for media content /// The content generated by the model. @@ -392,8 +390,11 @@ class SessionResumptionUpdate implements LiveServerMessage { /// point. /// [lastConsumedClientMessageIndex] (optional): The index of the last client /// message that is included in the state represented by this update. - SessionResumptionUpdate( - {this.newHandle, this.resumable, this.lastConsumedClientMessageIndex}); + SessionResumptionUpdate({ + this.newHandle, + this.resumable, + this.lastConsumedClientMessageIndex, + }); /// The new handle that represents the state that can be resumed. Empty if /// `resumable` is false. @@ -434,50 +435,50 @@ class LiveClientRealtimeInput { /// Creates a [LiveClientRealtimeInput] with audio data. LiveClientRealtimeInput.audio(this.audio) - // ignore: deprecated_member_use_from_same_package - : mediaChunks = null, - video = null, - text = null, - activityStart = null, - activityEnd = null; + // ignore: deprecated_member_use_from_same_package + : mediaChunks = null, + video = null, + text = null, + activityStart = null, + activityEnd = null; /// Creates a [LiveClientRealtimeInput] with video data. LiveClientRealtimeInput.video(this.video) - // ignore: deprecated_member_use_from_same_package - : mediaChunks = null, - audio = null, - text = null, - activityStart = null, - activityEnd = null; + // ignore: deprecated_member_use_from_same_package + : mediaChunks = null, + audio = null, + text = null, + activityStart = null, + activityEnd = null; /// Creates a [LiveClientRealtimeInput] with text data. LiveClientRealtimeInput.text(this.text) - // ignore: deprecated_member_use_from_same_package - : mediaChunks = null, - audio = null, - video = null, - activityStart = null, - activityEnd = null; + // ignore: deprecated_member_use_from_same_package + : mediaChunks = null, + audio = null, + video = null, + activityStart = null, + activityEnd = null; /// Creates a [LiveClientRealtimeInput] with activity start signal. LiveClientRealtimeInput.activityStart() - // ignore: deprecated_member_use_from_same_package - : mediaChunks = null, - audio = null, - video = null, - text = null, - activityStart = const {}, - activityEnd = null; + // ignore: deprecated_member_use_from_same_package + : mediaChunks = null, + audio = null, + video = null, + text = null, + activityStart = const {}, + activityEnd = null; /// Creates a [LiveClientRealtimeInput] with activity end signal. LiveClientRealtimeInput.activityEnd() - // ignore: deprecated_member_use_from_same_package - : mediaChunks = null, - audio = null, - video = null, - text = null, - activityStart = null, - activityEnd = const {}; + // ignore: deprecated_member_use_from_same_package + : mediaChunks = null, + audio = null, + video = null, + text = null, + activityStart = null, + activityEnd = const {}; /// The list of media chunks. @Deprecated('Use audio, video, or text instead') @@ -500,18 +501,18 @@ class LiveClientRealtimeInput { // ignore: public_member_api_docs Map toJson() => { - 'realtime_input': { - if (mediaChunks != null) - 'media_chunks': - // ignore: deprecated_member_use_from_same_package - mediaChunks?.map((e) => e.toMediaChunkJson()).toList(), - if (audio != null) 'audio': audio!.toMediaChunkJson(), - if (video != null) 'video': video!.toMediaChunkJson(), - if (text != null) 'text': text, - if (activityStart != null) 'activity_start': activityStart, - if (activityEnd != null) 'activity_end': activityEnd, - }, - }; + 'realtime_input': { + if (mediaChunks != null) + 'media_chunks': + // ignore: deprecated_member_use_from_same_package + mediaChunks?.map((e) => e.toMediaChunkJson()).toList(), + if (audio != null) 'audio': audio!.toMediaChunkJson(), + if (video != null) 'video': video!.toMediaChunkJson(), + if (text != null) 'text': text, + if (activityStart != null) 'activity_start': activityStart, + if (activityEnd != null) 'activity_end': activityEnd, + }, + }; } /// Represents content from the client in a live stream. @@ -534,11 +535,11 @@ class LiveClientContent { // ignore: public_member_api_docs Map toJson() => { - 'client_content': { - 'turns': turns?.map((e) => e.toJson()).toList(), - 'turn_complete': turnComplete, - } - }; + 'client_content': { + 'turns': turns?.map((e) => e.toJson()).toList(), + 'turn_complete': turnComplete, + }, + }; } /// Represents a tool response from the client in a live stream. @@ -552,16 +553,18 @@ class LiveClientToolResponse { final List? functionResponses; // ignore: public_member_api_docs Map toJson() => { - 'toolResponse': { - 'functionResponses': functionResponses - ?.map((e) => { - 'name': e.name, - 'response': e.response, - if (e.id != null) 'id': e.id, - }) - .toList(), - }, - }; + 'toolResponse': { + 'functionResponses': functionResponses + ?.map( + (e) => { + 'name': e.name, + 'response': e.response, + if (e.id != null) 'id': e.id, + }, + ) + .toList(), + }, + }; } /// Parses a JSON object received from the live server into a [LiveServerResponse]. @@ -662,10 +665,7 @@ LiveServerMessage _parseServerMessage(Object jsonObject) { } else if (json.containsKey('toolCallCancellation')) { final toolCancelData = json['toolCallCancellation'] as Map; final Map> toolCancelJson = toolCancelData.map( - (key, value) => MapEntry( - key as String, - (value as List).cast(), - ), + (key, value) => MapEntry(key as String, (value as List).cast()), ); return LiveServerToolCallCancellation(functionIds: toolCancelJson['ids']); } else if (json.containsKey('setupComplete')) { diff --git a/packages/firebase_ai/firebase_ai/lib/src/live_model.dart b/packages/firebase_ai/firebase_ai/lib/src/live_model.dart index 0bb7aba55a26..03ba9d759781 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/live_model.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/live_model.dart @@ -30,39 +30,32 @@ const _apiUrlSuffixGoogleAI = 'GenerativeService/BidiGenerateContent'; /// is in Public Preview, which means that the feature is not subject to any SLA /// or deprecation policy and could change in backwards-incompatible ways. final class LiveGenerativeModel extends BaseModel { - LiveGenerativeModel._( - {required String model, - required String location, - required FirebaseApp app, - required bool useAgentPlatform, - bool? useLimitedUseAppCheckTokens, - FirebaseAppCheck? appCheck, - FirebaseAuth? auth, - LiveGenerationConfig? liveGenerationConfig, - List? tools, - Content? systemInstruction}) - : _app = app, - _location = location, - _useAgentPlatform = useAgentPlatform, - _appCheck = appCheck, - _auth = auth, - _liveGenerationConfig = liveGenerationConfig, - _tools = tools, - _systemInstruction = systemInstruction, - _useLimitedUseAppCheckTokens = useLimitedUseAppCheckTokens, - super._( - serializationStrategy: AgentPlatformSerialization(), - modelUri: useAgentPlatform - ? _AgentPlatformUri( - model: model, - app: app, - location: location, - ) - : _GoogleAIUri( - model: model, - app: app, - ), - ); + LiveGenerativeModel._({ + required String model, + required String location, + required FirebaseApp app, + required bool useAgentPlatform, + bool? useLimitedUseAppCheckTokens, + FirebaseAppCheck? appCheck, + FirebaseAuth? auth, + LiveGenerationConfig? liveGenerationConfig, + List? tools, + Content? systemInstruction, + }) : _app = app, + _location = location, + _useAgentPlatform = useAgentPlatform, + _appCheck = appCheck, + _auth = auth, + _liveGenerationConfig = liveGenerationConfig, + _tools = tools, + _systemInstruction = systemInstruction, + _useLimitedUseAppCheckTokens = useLimitedUseAppCheckTokens, + super._( + serializationStrategy: AgentPlatformSerialization(), + modelUri: useAgentPlatform + ? _AgentPlatformUri(model: model, app: app, location: location) + : _GoogleAIUri(model: model, app: app), + ); final FirebaseApp _app; final String _location; @@ -74,14 +67,17 @@ final class LiveGenerativeModel extends BaseModel { final Content? _systemInstruction; final bool? _useLimitedUseAppCheckTokens; - String _agentPlatformUri() => 'wss://${_modelUri.baseAuthority}/' + String _agentPlatformUri() => + 'wss://${_modelUri.baseAuthority}/' '$_apiUrl.${_modelUri.apiVersion}.$_apiUrlSuffixAgentPlatform/' '$_location?key=${_app.options.apiKey}'; - String _agentPlatformModelString() => 'projects/${_app.options.projectId}/' + String _agentPlatformModelString() => + 'projects/${_app.options.projectId}/' 'locations/$_location/publishers/google/models/${model.name}'; - String _googleAIUri() => 'wss://${_modelUri.baseAuthority}/' + String _googleAIUri() => + 'wss://${_modelUri.baseAuthority}/' '$_apiUrl.${_modelUri.apiVersion}.$_apiUrlSuffixGoogleAI?key=${_app.options.apiKey}'; String _googleAIModelString() => @@ -96,8 +92,9 @@ final class LiveGenerativeModel extends BaseModel { /// /// Returns a [Future] that resolves to an [LiveSession] object upon successful /// connection. - Future connect( - {SessionResumptionConfig? sessionResumption}) async { + Future connect({ + SessionResumptionConfig? sessionResumption, + }) async { final uri = _useAgentPlatform ? _agentPlatformUri() : _googleAIUri(); final modelString = _useAgentPlatform ? _agentPlatformModelString() @@ -134,16 +131,15 @@ LiveGenerativeModel createLiveGenerativeModel({ LiveGenerationConfig? liveGenerationConfig, List? tools, Content? systemInstruction, -}) => - LiveGenerativeModel._( - model: model, - app: app, - appCheck: appCheck, - auth: auth, - location: location, - useAgentPlatform: useAgentPlatform, - useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, - liveGenerationConfig: liveGenerationConfig, - tools: tools, - systemInstruction: systemInstruction, - ); +}) => LiveGenerativeModel._( + model: model, + app: app, + appCheck: appCheck, + auth: auth, + location: location, + useAgentPlatform: useAgentPlatform, + useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, + liveGenerationConfig: liveGenerationConfig, + tools: tools, + systemInstruction: systemInstruction, +); diff --git a/packages/firebase_ai/firebase_ai/lib/src/live_session.dart b/packages/firebase_ai/firebase_ai/lib/src/live_session.dart index d82a566de6c4..93cd8f7c7d07 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/live_session.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/live_session.dart @@ -37,25 +37,20 @@ class LiveSession { Content? systemInstruction, List? tools, LiveGenerationConfig? liveGenerationConfig, - }) : _uri = uri, - _headers = headers, - _modelString = modelString, - _systemInstruction = systemInstruction, - _tools = tools, - _liveGenerationConfig = liveGenerationConfig, - _messageController = StreamController.broadcast() { + }) : _uri = uri, + _headers = headers, + _modelString = modelString, + _systemInstruction = systemInstruction, + _tools = tools, + _liveGenerationConfig = liveGenerationConfig, + _messageController = StreamController.broadcast() { _listenToWebSocket(); } /// Internal constructor for testing. @visibleForTesting factory LiveSession.forTesting(WebSocketChannel ws) { - return LiveSession._( - ws, - uri: '', - headers: {}, - modelString: '', - ); + return LiveSession._(ws, uri: '', headers: {}, modelString: ''); } /// Establishes a connection to a live generation service. @@ -127,11 +122,13 @@ class LiveSession { if (liveGenerationConfig != null) ...{ 'generation_config': liveGenerationConfig.toJson(), if (liveGenerationConfig.inputAudioTranscription != null) - 'input_audio_transcription': - liveGenerationConfig.inputAudioTranscription!.toJson(), + 'input_audio_transcription': liveGenerationConfig + .inputAudioTranscription! + .toJson(), if (liveGenerationConfig.outputAudioTranscription != null) - 'output_audio_transcription': - liveGenerationConfig.outputAudioTranscription!.toJson(), + 'output_audio_transcription': liveGenerationConfig + .outputAudioTranscription! + .toJson(), if (liveGenerationConfig.contextWindowCompression case final contextWindowCompression?) 'contextWindowCompression': contextWindowCompression.toJson(), @@ -139,7 +136,7 @@ class LiveSession { case final realtimeInputConfig?) 'realtime_input_config': realtimeInputConfig.toJson(), }, - } + }, }; final request = jsonEncode(setupJson); @@ -156,8 +153,9 @@ class LiveSession { _wsSubscription = _ws.stream.listen( (message) { try { - final String jsonString = - message is String ? message : utf8.decode(message as List); + final String jsonString = message is String + ? message + : utf8.decode(message as List); var response = json.decode(jsonString); if (!_messageController.isClosed) { @@ -167,8 +165,10 @@ class LiveSession { if (!_messageController.isClosed && _messageController.hasListener) { _messageController.addError(e); } else { - log('live_session: Dropped parse error because no listeners', - error: e); + log( + 'live_session: Dropped parse error because no listeners', + error: e, + ); } } }, @@ -176,8 +176,10 @@ class LiveSession { if (!_messageController.isClosed && _messageController.hasListener) { _messageController.addError(error); } else { - log('live_session: Dropped stream error because no listeners', - error: error); + log( + 'live_session: Dropped stream error because no listeners', + error: error, + ); } }, onDone: () { @@ -196,18 +198,28 @@ class LiveSession { /// /// [sessionResumption] (optional): The configuration for session resumption, /// such as the handle to the previous session state to restore. - Future resumeSession( - {SessionResumptionConfig? sessionResumption}) async { + Future resumeSession({ + SessionResumptionConfig? sessionResumption, + }) async { try { - await _wsSubscription.cancel().timeout(const Duration(seconds: 2), - onTimeout: () { - log('live_session.resumeSession: WebSocket subscription cancel timed out.', - error: TimeoutException('Cancel timed out')); - }); - await _ws.sink.close().timeout(const Duration(seconds: 2), onTimeout: () { - log('live_session.resumeSession: WebSocket close timed out.', - error: TimeoutException('Close timed out')); - }); + await _wsSubscription.cancel().timeout( + const Duration(seconds: 2), + onTimeout: () { + log( + 'live_session.resumeSession: WebSocket subscription cancel timed out.', + error: TimeoutException('Cancel timed out'), + ); + }, + ); + await _ws.sink.close().timeout( + const Duration(seconds: 2), + onTimeout: () { + log( + 'live_session.resumeSession: WebSocket close timed out.', + error: TimeoutException('Close timed out'), + ); + }, + ); _ws = await _performWebSocketSetup( uri: _uri, @@ -230,10 +242,7 @@ class LiveSession { /// /// [input] (optional): The content to send. /// [turnComplete] (optional): Indicates if the turn is complete. Defaults to false. - Future send({ - Content? input, - bool turnComplete = false, - }) async { + Future send({Content? input, bool turnComplete = false}) async { _checkWsStatus(); var clientMessage = input != null ? LiveClientContent(turns: [input], turnComplete: turnComplete) @@ -246,9 +255,11 @@ class LiveSession { /// /// [functionResponses] (optional): The list of function responses. Future sendToolResponse( - List? functionResponses) async { - final toolResponse = - LiveClientToolResponse(functionResponses: functionResponses); + List? functionResponses, + ) async { + final toolResponse = LiveClientToolResponse( + functionResponses: functionResponses, + ); _checkWsStatus(); var clientJson = jsonEncode(toolResponse.toJson()); _ws.sink.add(clientJson); @@ -327,7 +338,8 @@ class LiveSession { /// /// [mediaChunks]: The list of media chunks to send. @Deprecated( - 'Use sendAudioRealtime, sendVideoRealtime, or sendTextRealtime instead') + 'Use sendAudioRealtime, sendVideoRealtime, or sendTextRealtime instead', + ) Future sendMediaChunks({ required List mediaChunks, }) async { @@ -361,8 +373,9 @@ class LiveSession { Future _sendMediaChunk(InlineDataPart chunk) async { var clientMessage = LiveClientRealtimeInput( - // ignore: deprecated_member_use_from_same_package - mediaChunks: [chunk]); // Create a list with the single chunk + // ignore: deprecated_member_use_from_same_package + mediaChunks: [chunk], + ); // Create a list with the single chunk var clientJson = jsonEncode(clientMessage.toJson()); _ws.sink.add(clientJson); } @@ -383,18 +396,27 @@ class LiveSession { /// Closes the WebSocket connection. Future close() async { try { - await _wsSubscription.cancel().timeout(const Duration(seconds: 1), - onTimeout: () { - log('live_session.close: cancel timed out', - error: TimeoutException('Cancel timed out')); - }); + await _wsSubscription.cancel().timeout( + const Duration(seconds: 1), + onTimeout: () { + log( + 'live_session.close: cancel timed out', + error: TimeoutException('Cancel timed out'), + ); + }, + ); if (!_messageController.isClosed) { await _messageController.close(); } - await _ws.sink.close().timeout(const Duration(seconds: 1), onTimeout: () { - log('live_session.close: sink close timed out', - error: TimeoutException('Sink close timed out')); - }); + await _ws.sink.close().timeout( + const Duration(seconds: 1), + onTimeout: () { + log( + 'live_session.close: sink close timed out', + error: TimeoutException('Sink close timed out'), + ); + }, + ); } catch (e) { log('live_session.close: error during close', error: e); } diff --git a/packages/firebase_ai/firebase_ai/lib/src/platform_header_helper.dart b/packages/firebase_ai/firebase_ai/lib/src/platform_header_helper.dart index 9f0d115756de..480eead62dcc 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/platform_header_helper.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/platform_header_helper.dart @@ -40,8 +40,9 @@ Future> getPlatformSecurityHeaders() async { if (_cachedHeaders != null) return _cachedHeaders!; try { - final result = await platformHeaderChannel - .invokeMapMethod('getPlatformHeaders'); + final result = await platformHeaderChannel.invokeMapMethod( + 'getPlatformHeaders', + ); _cachedHeaders = result ?? const {}; } catch (_) { _cachedHeaders = const {}; diff --git a/packages/firebase_ai/firebase_ai/lib/src/schema.dart b/packages/firebase_ai/firebase_ai/lib/src/schema.dart index 7ed783e47b3d..1302acd377e5 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/schema.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/schema.dart @@ -46,14 +46,14 @@ final class Schema { String? title, bool? nullable, }) : this( - SchemaType.object, - properties: properties, - optionalProperties: optionalProperties, - propertyOrdering: propertyOrdering, - description: description, - title: title, - nullable: nullable, - ); + SchemaType.object, + properties: properties, + optionalProperties: optionalProperties, + propertyOrdering: propertyOrdering, + description: description, + title: title, + nullable: nullable, + ); /// Construct a schema for an array of values with a specified type. Schema.array({ @@ -64,26 +64,23 @@ final class Schema { int? minItems, int? maxItems, }) : this( - SchemaType.array, - description: description, - title: title, - nullable: nullable, - items: items, - minItems: minItems, - maxItems: maxItems, - ); + SchemaType.array, + description: description, + title: title, + nullable: nullable, + items: items, + minItems: minItems, + maxItems: maxItems, + ); /// Construct a schema for bool value. - Schema.boolean({ - String? description, - String? title, - bool? nullable, - }) : this( - SchemaType.boolean, - description: description, - title: title, - nullable: nullable, - ); + Schema.boolean({String? description, String? title, bool? nullable}) + : this( + SchemaType.boolean, + description: description, + title: title, + nullable: nullable, + ); /// Construct a schema for an integer number. /// @@ -96,14 +93,14 @@ final class Schema { int? minimum, int? maximum, }) : this( - SchemaType.integer, - description: description, - title: title, - nullable: nullable, - format: format, - minimum: minimum?.toDouble(), - maximum: maximum?.toDouble(), - ); + SchemaType.integer, + description: description, + title: title, + nullable: nullable, + format: format, + minimum: minimum?.toDouble(), + maximum: maximum?.toDouble(), + ); /// Construct a schema for a non-integer number. /// @@ -116,14 +113,14 @@ final class Schema { double? minimum, double? maximum, }) : this( - SchemaType.number, - description: description, - title: title, - nullable: nullable, - format: format, - minimum: minimum, - maximum: maximum, - ); + SchemaType.number, + description: description, + title: title, + nullable: nullable, + format: format, + minimum: minimum, + maximum: maximum, + ); /// Construct a schema for String value with enumerated possible values. Schema.enumString({ @@ -132,13 +129,13 @@ final class Schema { String? title, bool? nullable, }) : this( - SchemaType.string, - enumValues: enumValues, - description: description, - title: title, - nullable: nullable, - format: 'enum', - ); + SchemaType.string, + enumValues: enumValues, + description: description, + title: title, + nullable: nullable, + format: 'enum', + ); /// Construct a schema for a String value. Schema.string({ @@ -147,12 +144,12 @@ final class Schema { bool? nullable, String? format, }) : this( - SchemaType.string, - description: description, - title: title, - nullable: nullable, - format: format, - ); + SchemaType.string, + description: description, + title: title, + nullable: nullable, + format: format, + ); /// Construct a schema representing a value that must conform to /// *any* (one or more) of the provided sub-schemas. @@ -173,12 +170,11 @@ final class Schema { /// ]) /// ``` /// The generated data could be decoded based on which schema it matches. - Schema.anyOf({ - required List schemas, - }) : this( - SchemaType.anyOf, // The type will be ignored in toJson - anyOf: schemas, - ); + Schema.anyOf({required List schemas}) + : this( + SchemaType.anyOf, // The type will be ignored in toJson + anyOf: schemas, + ); /// The type of this value. SchemaType type; @@ -259,35 +255,34 @@ final class Schema { /// Convert to json object. Map toJson() => { - if (type != SchemaType.anyOf) - 'type': type.toJson(), // Omit the field while type is anyOf - if (format case final format?) 'format': format, - if (description case final description?) 'description': description, - if (title case final title?) 'title': title, - if (nullable case final nullable?) 'nullable': nullable, - if (enumValues case final enumValues?) 'enum': enumValues, - if (items case final items?) 'items': items.toJson(), - if (minItems case final minItems?) 'minItems': minItems, - if (maxItems case final maxItems?) 'maxItems': maxItems, - if (minimum case final minimum?) 'minimum': minimum, - if (maximum case final maximum?) 'maximum': maximum, - if (properties case final properties?) - 'properties': { - for (final MapEntry(:key, :value) in properties.entries) - key: value.toJson() - }, - // Calculate required properties based on optionalProperties - if (properties != null) - 'required': optionalProperties != null - ? properties!.keys - .where((key) => !optionalProperties!.contains(key)) - .toList() - : properties!.keys.toList(), - if (propertyOrdering case final propertyOrdering?) - 'propertyOrdering': propertyOrdering, - if (anyOf case final anyOf?) - 'anyOf': anyOf.map((e) => e.toJson()).toList(), - }; + if (type != SchemaType.anyOf) + 'type': type.toJson(), // Omit the field while type is anyOf + if (format case final format?) 'format': format, + if (description case final description?) 'description': description, + if (title case final title?) 'title': title, + if (nullable case final nullable?) 'nullable': nullable, + if (enumValues case final enumValues?) 'enum': enumValues, + if (items case final items?) 'items': items.toJson(), + if (minItems case final minItems?) 'minItems': minItems, + if (maxItems case final maxItems?) 'maxItems': maxItems, + if (minimum case final minimum?) 'minimum': minimum, + if (maximum case final maximum?) 'maximum': maximum, + if (properties case final properties?) + 'properties': { + for (final MapEntry(:key, :value) in properties.entries) + key: value.toJson(), + }, + // Calculate required properties based on optionalProperties + if (properties != null) + 'required': optionalProperties != null + ? properties!.keys + .where((key) => !optionalProperties!.contains(key)) + .toList() + : properties!.keys.toList(), + if (propertyOrdering case final propertyOrdering?) + 'propertyOrdering': propertyOrdering, + if (anyOf case final anyOf?) 'anyOf': anyOf.map((e) => e.toJson()).toList(), + }; } /// The definition of a JSON Schema data type. @@ -313,11 +308,7 @@ final class JSONSchema extends Schema { List? anyOf, this.ref, this.defs, - }) : super( - items: items, - properties: properties, - anyOf: anyOf, - ); + }) : super(items: items, properties: properties, anyOf: anyOf); /// Construct a schema for an object with one or more properties. JSONSchema.object({ @@ -329,15 +320,15 @@ final class JSONSchema extends Schema { bool? nullable, Map? defs, }) : this( - SchemaType.object, - properties: properties, - optionalProperties: optionalProperties, - propertyOrdering: propertyOrdering, - description: description, - title: title, - nullable: nullable, - defs: defs, - ); + SchemaType.object, + properties: properties, + optionalProperties: optionalProperties, + propertyOrdering: propertyOrdering, + description: description, + title: title, + nullable: nullable, + defs: defs, + ); /// Construct a schema for an array of values with a specified type. JSONSchema.array({ @@ -348,26 +339,23 @@ final class JSONSchema extends Schema { int? minItems, int? maxItems, }) : this( - SchemaType.array, - description: description, - title: title, - nullable: nullable, - items: items, - minItems: minItems, - maxItems: maxItems, - ); + SchemaType.array, + description: description, + title: title, + nullable: nullable, + items: items, + minItems: minItems, + maxItems: maxItems, + ); /// Construct a schema for bool value. - JSONSchema.boolean({ - String? description, - String? title, - bool? nullable, - }) : this( - SchemaType.boolean, - description: description, - title: title, - nullable: nullable, - ); + JSONSchema.boolean({String? description, String? title, bool? nullable}) + : this( + SchemaType.boolean, + description: description, + title: title, + nullable: nullable, + ); /// Construct a schema for an integer number. /// @@ -379,13 +367,13 @@ final class JSONSchema extends Schema { int? minimum, int? maximum, }) : this( - SchemaType.integer, - description: description, - title: title, - nullable: nullable, - minimum: minimum?.toDouble(), - maximum: maximum?.toDouble(), - ); + SchemaType.integer, + description: description, + title: title, + nullable: nullable, + minimum: minimum?.toDouble(), + maximum: maximum?.toDouble(), + ); /// Construct a schema for a non-integer number. /// @@ -397,13 +385,13 @@ final class JSONSchema extends Schema { double? minimum, double? maximum, }) : this( - SchemaType.number, - description: description, - title: title, - nullable: nullable, - minimum: minimum, - maximum: maximum, - ); + SchemaType.number, + description: description, + title: title, + nullable: nullable, + minimum: minimum, + maximum: maximum, + ); /// Construct a schema for String value with enumerated possible values. JSONSchema.enumString({ @@ -412,13 +400,13 @@ final class JSONSchema extends Schema { String? title, bool? nullable, }) : this( - SchemaType.string, - enumValues: enumValues, - description: description, - title: title, - nullable: nullable, - format: 'enum', - ); + SchemaType.string, + enumValues: enumValues, + description: description, + title: title, + nullable: nullable, + format: 'enum', + ); /// Construct a schema for a String value. JSONSchema.string({ @@ -427,12 +415,12 @@ final class JSONSchema extends Schema { bool? nullable, String? format, }) : this( - SchemaType.string, - description: description, - title: title, - nullable: nullable, - format: format, - ); + SchemaType.string, + description: description, + title: title, + nullable: nullable, + format: format, + ); /// Construct a schema representing a value that must conform to /// *any* (one or more) of the provided sub-schemas. @@ -453,19 +441,14 @@ final class JSONSchema extends Schema { /// ]) /// ``` /// The generated data could be decoded based on which schema it matches. - JSONSchema.anyOf({ - required List schemas, - }) : this( - SchemaType.anyOf, // The type will be ignored in toJson - anyOf: schemas, - ); + JSONSchema.anyOf({required List schemas}) + : this( + SchemaType.anyOf, // The type will be ignored in toJson + anyOf: schemas, + ); /// Construct a schema referencing another schema. - JSONSchema.ref(String ref) - : this( - SchemaType.ref, - ref: ref, - ); + JSONSchema.ref(String ref) : this(SchemaType.ref, ref: ref); /// JSONSchema for the elements if this is a [SchemaType.array]. @override @@ -501,38 +484,36 @@ final class JSONSchema extends Schema { /// Reference: https://ai.google.dev/api/caching#FunctionDeclaration @override Map toJson() => { - if (type != SchemaType.anyOf && type != SchemaType.ref) - 'type': nullable == true ? [type.name, 'null'] : type.name, - if (ref case final ref?) r'$ref': ref, - if (defs case final defs?) - r'$defs': { - for (final MapEntry(:key, :value) in defs.entries) - key: value.toJson() - }, - if (format case final format?) 'format': format, - if (description case final description?) 'description': description, - if (title case final title?) 'title': title, - if (enumValues case final enumValues?) 'enum': enumValues, - if (items case final items?) 'items': items.toJson(), - if (minItems case final minItems?) 'minItems': minItems, - if (maxItems case final maxItems?) 'maxItems': maxItems, - if (minimum case final minimum?) 'minimum': minimum, - if (maximum case final maximum?) 'maximum': maximum, - if (properties case final properties?) - 'properties': { - for (final MapEntry(:key, :value) in properties.entries) - key: value.toJson() - }, - // Calculate required properties based on optionalProperties - if (properties != null) - 'required': optionalProperties != null - ? properties!.keys - .where((key) => !optionalProperties!.contains(key)) - .toList() - : properties!.keys.toList(), - if (anyOf case final anyOf?) - 'anyOf': anyOf.map((e) => e.toJson()).toList(), - }; + if (type != SchemaType.anyOf && type != SchemaType.ref) + 'type': nullable == true ? [type.name, 'null'] : type.name, + if (ref case final ref?) r'$ref': ref, + if (defs case final defs?) + r'$defs': { + for (final MapEntry(:key, :value) in defs.entries) key: value.toJson(), + }, + if (format case final format?) 'format': format, + if (description case final description?) 'description': description, + if (title case final title?) 'title': title, + if (enumValues case final enumValues?) 'enum': enumValues, + if (items case final items?) 'items': items.toJson(), + if (minItems case final minItems?) 'minItems': minItems, + if (maxItems case final maxItems?) 'maxItems': maxItems, + if (minimum case final minimum?) 'minimum': minimum, + if (maximum case final maximum?) 'maximum': maximum, + if (properties case final properties?) + 'properties': { + for (final MapEntry(:key, :value) in properties.entries) + key: value.toJson(), + }, + // Calculate required properties based on optionalProperties + if (properties != null) + 'required': optionalProperties != null + ? properties!.keys + .where((key) => !optionalProperties!.contains(key)) + .toList() + : properties!.keys.toList(), + if (anyOf case final anyOf?) 'anyOf': anyOf.map((e) => e.toJson()).toList(), + }; } /// The value type of a [Schema]. @@ -563,13 +544,13 @@ enum SchemaType { /// Convert to json object. String toJson() => switch (this) { - string => 'STRING', - number => 'NUMBER', - integer => 'INTEGER', - boolean => 'BOOLEAN', - array => 'ARRAY', - object => 'OBJECT', - ref => 'null', - anyOf => 'null', - }; + string => 'STRING', + number => 'NUMBER', + integer => 'INTEGER', + boolean => 'BOOLEAN', + array => 'ARRAY', + object => 'OBJECT', + ref => 'null', + anyOf => 'null', + }; } diff --git a/packages/firebase_ai/firebase_ai/lib/src/server_template/template_chat.dart b/packages/firebase_ai/firebase_ai/lib/src/server_template/template_chat.dart index 2efa63689dba..bcad46ecdcf5 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/server_template/template_chat.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/server_template/template_chat.dart @@ -37,23 +37,29 @@ final class TemplateChatSession { this._toolConfig, this._maxTurns, ) : _autoFunctions = _tools - ?.expand((tool) => tool.templateAutoFunctionDeclarations) - .fold({}, (map, function) { - map?[function.name] = function; - return map; - }); + ?.expand((tool) => tool.templateAutoFunctionDeclarations) + .fold({}, (map, function) { + map?[function.name] = function; + return map; + }); final Future Function( - Iterable content, String templateId, - {required Map inputs, - List? tools, - TemplateToolConfig? toolConfig}) _templateHistoryGenerateContent; + Iterable content, + String templateId, { + required Map inputs, + List? tools, + TemplateToolConfig? toolConfig, + }) + _templateHistoryGenerateContent; final Stream Function( - Iterable content, String templateId, - {required Map inputs, - List? tools, - TemplateToolConfig? toolConfig}) _templateHistoryGenerateContentStream; + Iterable content, + String templateId, { + required Map inputs, + List? tools, + TemplateToolConfig? toolConfig, + }) + _templateHistoryGenerateContentStream; final String _templateId; final Map _inputs; @@ -96,7 +102,8 @@ final class TemplateChatSession { ); final functionCalls = response.functionCalls; - final shouldAutoExecute = _autoFunctions != null && + final shouldAutoExecute = + _autoFunctions != null && _autoFunctions.isNotEmpty && functionCalls.isNotEmpty && functionCalls.every((c) => _autoFunctions.containsKey(c.name)); @@ -125,8 +132,9 @@ final class TemplateChatSession { } catch (e) { result = e.toString(); } - functionResponses - .add(FunctionResponse(functionCall.name, {'result': result})); + functionResponses.add( + FunctionResponse(functionCall.name, {'result': result}), + ); } requestHistory.add(Content('function', functionResponses)); turn++; @@ -169,18 +177,22 @@ final class TemplateChatSession { controller.add(response); } if (turnChunks.isEmpty) break; - final aggregatedContent = historyAggregate(turnChunks.map((r) { - final content = r.candidates.firstOrNull?.content; - if (content == null) { - throw Exception('No content in response candidate'); - } - return content; - }).toList()); + final aggregatedContent = historyAggregate( + turnChunks.map((r) { + final content = r.candidates.firstOrNull?.content; + if (content == null) { + throw Exception('No content in response candidate'); + } + return content; + }).toList(), + ); - final functionCalls = - aggregatedContent.parts.whereType().toList(); + final functionCalls = aggregatedContent.parts + .whereType() + .toList(); - final shouldAutoExecute = _autoFunctions != null && + final shouldAutoExecute = + _autoFunctions != null && _autoFunctions.isNotEmpty && functionCalls.isNotEmpty && functionCalls.every((c) => _autoFunctions.containsKey(c.name)); @@ -192,8 +204,9 @@ final class TemplateChatSession { } requestHistory.add(aggregatedContent); - final functionResponseFutures = - functionCalls.map((functionCall) async { + final functionResponseFutures = functionCalls.map(( + functionCall, + ) async { final function = _autoFunctions[functionCall.name]; Object? result; @@ -204,8 +217,9 @@ final class TemplateChatSession { } return FunctionResponse(functionCall.name, {'result': result}); }); - final functionResponseParts = - await Future.wait(functionResponseFutures); + final functionResponseParts = await Future.wait( + functionResponseFutures, + ); requestHistory.add(Content.functionResponses(functionResponseParts)); turn++; } @@ -230,19 +244,21 @@ extension StartTemplateChatExtension on TemplateGenerativeModel { /// final response = await chat.sendMessage(Content.text('Hello there.')); /// print(response.text); /// ``` - TemplateChatSession startChat(String templateId, - {required Map inputs, - List? history, - List? tools, - TemplateToolConfig? toolConfig, - int? maxTurns}) => - TemplateChatSession._( - templateGenerateContentWithHistory, - templateGenerateContentWithHistoryStream, - templateId, - inputs, - history ?? [], - tools ?? [], - toolConfig, - maxTurns ?? 5); + TemplateChatSession startChat( + String templateId, { + required Map inputs, + List? history, + List? tools, + TemplateToolConfig? toolConfig, + int? maxTurns, + }) => TemplateChatSession._( + templateGenerateContentWithHistory, + templateGenerateContentWithHistoryStream, + templateId, + inputs, + history ?? [], + tools ?? [], + toolConfig, + maxTurns ?? 5, + ); } diff --git a/packages/firebase_ai/firebase_ai/lib/src/server_template/template_generative_model.dart b/packages/firebase_ai/firebase_ai/lib/src/server_template/template_generative_model.dart index 2cfab6fc1046..dea9588936eb 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/server_template/template_generative_model.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/server_template/template_generative_model.dart @@ -24,20 +24,21 @@ final class TemplateGenerativeModel extends BaseTemplateApiClientModel { required bool useAgentPlatform, http.Client? httpClient, }) : super( - serializationStrategy: useAgentPlatform - ? AgentPlatformSerialization() - : DeveloperSerialization(), - modelUri: useAgentPlatform - ? _AgentPlatformUri(app: app, model: '', location: location) - : _GoogleAIUri(app: app, model: ''), - client: HttpApiClient( - apiKey: app.options.apiKey, - httpClient: httpClient, - requestHeaders: BaseModel.firebaseTokens(null, null, app, false)), - templateUri: useAgentPlatform - ? _TemplateAgentPlatformUri(app: app, location: location) - : _TemplateGoogleAIUri(app: app), - ); + serializationStrategy: useAgentPlatform + ? AgentPlatformSerialization() + : DeveloperSerialization(), + modelUri: useAgentPlatform + ? _AgentPlatformUri(app: app, model: '', location: location) + : _GoogleAIUri(app: app, model: ''), + client: HttpApiClient( + apiKey: app.options.apiKey, + httpClient: httpClient, + requestHeaders: BaseModel.firebaseTokens(null, null, app, false), + ), + templateUri: useAgentPlatform + ? _TemplateAgentPlatformUri(app: app, location: location) + : _TemplateGoogleAIUri(app: app), + ); TemplateGenerativeModel._({ required String location, @@ -48,88 +49,104 @@ final class TemplateGenerativeModel extends BaseTemplateApiClientModel { FirebaseAuth? auth, http.Client? httpClient, }) : super( - serializationStrategy: useAgentPlatform - ? AgentPlatformSerialization() - : DeveloperSerialization(), - modelUri: useAgentPlatform - ? _AgentPlatformUri(app: app, model: '', location: location) - : _GoogleAIUri(app: app, model: ''), - client: HttpApiClient( - apiKey: app.options.apiKey, - httpClient: httpClient, - requestHeaders: BaseModel.firebaseTokens( - appCheck, auth, app, useLimitedUseAppCheckTokens)), - templateUri: useAgentPlatform - ? _TemplateAgentPlatformUri(app: app, location: location) - : _TemplateGoogleAIUri(app: app), - ); + serializationStrategy: useAgentPlatform + ? AgentPlatformSerialization() + : DeveloperSerialization(), + modelUri: useAgentPlatform + ? _AgentPlatformUri(app: app, model: '', location: location) + : _GoogleAIUri(app: app, model: ''), + client: HttpApiClient( + apiKey: app.options.apiKey, + httpClient: httpClient, + requestHeaders: BaseModel.firebaseTokens( + appCheck, + auth, + app, + useLimitedUseAppCheckTokens, + ), + ), + templateUri: useAgentPlatform + ? _TemplateAgentPlatformUri(app: app, location: location) + : _TemplateGoogleAIUri(app: app), + ); /// Generates content from a template with the given [templateId] and [inputs]. /// /// Sends a "templateGenerateContent" API request for the configured model. @experimental - Future generateContent(String templateId, - {required Map inputs, - TemplateToolConfig? toolConfig}) => - makeTemplateRequest( - TemplateTask.templateGenerateContent, - templateId, - inputs, - null, // history - null, // tools - toolConfig, - _serializationStrategy.parseGenerateContentResponse); + Future generateContent( + String templateId, { + required Map inputs, + TemplateToolConfig? toolConfig, + }) => makeTemplateRequest( + TemplateTask.templateGenerateContent, + templateId, + inputs, + null, // history + null, // tools + toolConfig, + _serializationStrategy.parseGenerateContentResponse, + ); /// Generates a stream of content responding to [templateId] and [inputs]. /// /// Sends a "templateStreamGenerateContent" API request for the server template, /// and waits for the response. @experimental - Stream generateContentStream(String templateId, - {required Map inputs, TemplateToolConfig? toolConfig}) { + Stream generateContentStream( + String templateId, { + required Map inputs, + TemplateToolConfig? toolConfig, + }) { return streamTemplateRequest( - TemplateTask.templateStreamGenerateContent, - templateId, - inputs, - null, // history - null, // tools - toolConfig, - _serializationStrategy.parseGenerateContentResponse); + TemplateTask.templateStreamGenerateContent, + templateId, + inputs, + null, // history + null, // tools + toolConfig, + _serializationStrategy.parseGenerateContentResponse, + ); } /// Generates content from a template with the given [templateId], [inputs] and /// [history]. @experimental Future templateGenerateContentWithHistory( - Iterable history, String templateId, - {required Map inputs, - List? tools, - TemplateToolConfig? toolConfig}) => - makeTemplateRequest( - TemplateTask.templateGenerateContent, - templateId, - inputs, - history, - tools, - toolConfig, - _serializationStrategy.parseGenerateContentResponse); + Iterable history, + String templateId, { + required Map inputs, + List? tools, + TemplateToolConfig? toolConfig, + }) => makeTemplateRequest( + TemplateTask.templateGenerateContent, + templateId, + inputs, + history, + tools, + toolConfig, + _serializationStrategy.parseGenerateContentResponse, + ); /// Generates a stream of content from a template with the given [templateId], /// [inputs] and [history]. @experimental Stream templateGenerateContentWithHistoryStream( - Iterable history, String templateId, - {required Map inputs, - List? tools, - TemplateToolConfig? toolConfig}) { + Iterable history, + String templateId, { + required Map inputs, + List? tools, + TemplateToolConfig? toolConfig, + }) { return streamTemplateRequest( - TemplateTask.templateStreamGenerateContent, - templateId, - inputs, - history, - tools, - toolConfig, - _serializationStrategy.parseGenerateContentResponse); + TemplateTask.templateStreamGenerateContent, + templateId, + inputs, + history, + tools, + toolConfig, + _serializationStrategy.parseGenerateContentResponse, + ); } } @@ -143,15 +160,14 @@ TemplateGenerativeModel createTemplateGenerativeModel({ bool? useLimitedUseAppCheckTokens, FirebaseAppCheck? appCheck, FirebaseAuth? auth, -}) => - TemplateGenerativeModel._( - app: app, - appCheck: appCheck, - useAgentPlatform: useAgentPlatform, - useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, - auth: auth, - location: location, - ); +}) => TemplateGenerativeModel._( + app: app, + appCheck: appCheck, + useAgentPlatform: useAgentPlatform, + useLimitedUseAppCheckTokens: useLimitedUseAppCheckTokens, + auth: auth, + location: location, +); /// Returns a [TemplateGenerativeModel] for test case. @experimental @@ -161,10 +177,9 @@ TemplateGenerativeModel createTestTemplateGenerativeModel({ required String location, required bool useAgentPlatform, required http.Client client, -}) => - TemplateGenerativeModel._test( - app: app, - useAgentPlatform: useAgentPlatform, - location: location, - httpClient: client, - ); +}) => TemplateGenerativeModel._test( + app: app, + useAgentPlatform: useAgentPlatform, + location: location, + httpClient: client, +); diff --git a/packages/firebase_ai/firebase_ai/lib/src/server_template/template_tool.dart b/packages/firebase_ai/firebase_ai/lib/src/server_template/template_tool.dart index 603875020c3b..119a542e79cc 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/server_template/template_tool.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/server_template/template_tool.dart @@ -23,7 +23,8 @@ final class TemplateTool { /// Returns a [TemplateTool] instance with list of [TemplateFunctionDeclaration]. static TemplateTool functionDeclarations( - List functionDeclarations) { + List functionDeclarations, + ) { return TemplateTool._(functionDeclarations); } @@ -40,25 +41,28 @@ final class TemplateTool { /// Convert to json object. Map toJson() => { - if (_functionDeclarations case final functionDeclarations? - when functionDeclarations.isNotEmpty) - 'templateFunctions': functionDeclarations - .map((f) => f.hasSchema ? f.toJson() : null) - .where((f) => f != null) - .toList(), - }; + if (_functionDeclarations case final functionDeclarations? + when functionDeclarations.isNotEmpty) + 'templateFunctions': functionDeclarations + .map((f) => f.hasSchema ? f.toJson() : null) + .where((f) => f != null) + .toList(), + }; } /// A function declaration for a template tool. class TemplateFunctionDeclaration { // ignore: public_member_api_docs - TemplateFunctionDeclaration(this.name, - {Map? parameters, - List optionalParameters = const []}) - : _schemaObject = parameters != null - ? JSONSchema.object( - properties: parameters, optionalProperties: optionalParameters) - : null; + TemplateFunctionDeclaration( + this.name, { + Map? parameters, + List optionalParameters = const [], + }) : _schemaObject = parameters != null + ? JSONSchema.object( + properties: parameters, + optionalProperties: optionalParameters, + ) + : null; /// The name of the function. /// @@ -73,40 +77,43 @@ class TemplateFunctionDeclaration { /// Convert to json object. Map toJson() => { - 'name': name, - if (_schemaObject case final schemaObject?) - 'inputSchema': schemaObject.toJson(), - }; + 'name': name, + if (_schemaObject case final schemaObject?) + 'inputSchema': schemaObject.toJson(), + }; } /// A function declaration for a template tool that can be called by the model. final class TemplateAutoFunctionDeclaration extends TemplateFunctionDeclaration { // ignore: public_member_api_docs - TemplateAutoFunctionDeclaration( - {required String name, - required this.callable, - Map? parameters, - List optionalParameters = const []}) - : super(name, - parameters: parameters, optionalParameters: optionalParameters); + TemplateAutoFunctionDeclaration({ + required String name, + required this.callable, + Map? parameters, + List optionalParameters = const [], + }) : super( + name, + parameters: parameters, + optionalParameters: optionalParameters, + ); /// The callable function that this declaration represents. final FutureOr> Function(Map args) - callable; + callable; } /// Config for template tools to use with server prompts. final class TemplateToolConfig { // ignore: public_member_api_docs TemplateToolConfig({RetrievalConfig? retrievalConfig}) - : _retrievalConfig = retrievalConfig; + : _retrievalConfig = retrievalConfig; final RetrievalConfig? _retrievalConfig; /// Convert to json object. Map toJson() => { - if (_retrievalConfig case final retrievalConfig?) - 'retrievalConfig': retrievalConfig.toJson(), - }; + if (_retrievalConfig case final retrievalConfig?) + 'retrievalConfig': retrievalConfig.toJson(), + }; } diff --git a/packages/firebase_ai/firebase_ai/lib/src/speech_config.dart b/packages/firebase_ai/firebase_ai/lib/src/speech_config.dart index 483c23f354e5..e316f15605ce 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/speech_config.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/speech_config.dart @@ -18,14 +18,15 @@ import 'package:meta/meta.dart'; class SpeechConfig { /// Constructs a [SpeechConfig] for a single-speaker setup. SpeechConfig({this.voiceName, this.languageCode}) - : multiSpeakerVoiceConfig = null; + : multiSpeakerVoiceConfig = null; /// Constructs a [SpeechConfig] for a multi-speaker setup. /// /// This feature is in Public Preview. - SpeechConfig.multiSpeaker( - {required this.multiSpeakerVoiceConfig, this.languageCode}) - : voiceName = null; + SpeechConfig.multiSpeaker({ + required this.multiSpeakerVoiceConfig, + this.languageCode, + }) : voiceName = null; /// The voice name to use for a single-speaker setup. final String? voiceName; @@ -39,15 +40,14 @@ class SpeechConfig { /// Convert to json format. @internal Map toJson() => { - if (voiceName != null) - 'voice_config': VoiceConfig( - prebuiltVoiceConfig: PrebuiltVoiceConfig(voiceName: voiceName), - ).toJson(), - if (multiSpeakerVoiceConfig case final multiSpeakerVoiceConfig?) - 'multi_speaker_voice_config': multiSpeakerVoiceConfig.toJson(), - if (languageCode case final languageCode?) - 'language_code': languageCode, - }; + if (voiceName != null) + 'voice_config': VoiceConfig( + prebuiltVoiceConfig: PrebuiltVoiceConfig(voiceName: voiceName), + ).toJson(), + if (multiSpeakerVoiceConfig case final multiSpeakerVoiceConfig?) + 'multi_speaker_voice_config': multiSpeakerVoiceConfig.toJson(), + if (languageCode case final languageCode?) 'language_code': languageCode, + }; } /// Configuration for a multi-speaker audio generation setup. @@ -62,9 +62,10 @@ class MultiSpeakerVoiceConfig { /// Convert to json format. Map toJson() => { - 'speaker_voice_configs': - speakerVoiceConfigs.map((e) => e.toJson()).toList(), - }; + 'speaker_voice_configs': speakerVoiceConfigs + .map((e) => e.toJson()) + .toList(), + }; } /// Configures a participating speaker within a multi-speaker setup. @@ -82,11 +83,11 @@ class SpeakerVoiceConfig { /// Convert to json format. Map toJson() => { - 'speaker': speaker, - 'voice_config': VoiceConfig( - prebuiltVoiceConfig: PrebuiltVoiceConfig(voiceName: voiceName), - ).toJson(), - }; + 'speaker': speaker, + 'voice_config': VoiceConfig( + prebuiltVoiceConfig: PrebuiltVoiceConfig(voiceName: voiceName), + ).toJson(), + }; } /// Configuration for a prebuilt voice. @@ -98,8 +99,9 @@ class PrebuiltVoiceConfig { final String? voiceName; /// Convert to json format. - Map toJson() => - {if (voiceName case final voiceName?) 'voice_name': voiceName}; + Map toJson() => { + if (voiceName case final voiceName?) 'voice_name': voiceName, + }; } /// Configuration for the voice to be used in speech synthesis. @@ -112,7 +114,7 @@ class VoiceConfig { /// Convert to json format. Map toJson() => { - if (prebuiltVoiceConfig case final prebuiltVoiceConfig?) - 'prebuilt_voice_config': prebuiltVoiceConfig.toJson() - }; + if (prebuiltVoiceConfig case final prebuiltVoiceConfig?) + 'prebuilt_voice_config': prebuiltVoiceConfig.toJson(), + }; } diff --git a/packages/firebase_ai/firebase_ai/lib/src/tool.dart b/packages/firebase_ai/firebase_ai/lib/src/tool.dart index 195db5f81836..ecf13924bc21 100644 --- a/packages/firebase_ai/firebase_ai/lib/src/tool.dart +++ b/packages/firebase_ai/firebase_ai/lib/src/tool.dart @@ -23,12 +23,18 @@ import 'schema.dart'; /// knowledge and scope of the model. final class Tool { // ignore: public_member_api_docs - Tool._(this._functionDeclarations, this._googleSearch, this._codeExecution, - this._urlContext, this._googleMaps); + Tool._( + this._functionDeclarations, + this._googleSearch, + this._codeExecution, + this._urlContext, + this._googleMaps, + ); /// Returns a [Tool] instance with list of [FunctionDeclaration]. static Tool functionDeclarations( - List functionDeclarations) { + List functionDeclarations, + ) { return Tool._(functionDeclarations, null, null, null, null); } @@ -54,8 +60,9 @@ final class Tool { } /// Returns a [Tool] instance that enables the model to use Code Execution. - static Tool codeExecution( - {CodeExecution codeExecution = const CodeExecution()}) { + static Tool codeExecution({ + CodeExecution codeExecution = const CodeExecution(), + }) { return Tool._(null, null, codeExecution, null, null); } @@ -132,18 +139,17 @@ final class Tool { /// Convert to json object. Map toJson() => { - if (_functionDeclarations case final _functionDeclarations?) - 'functionDeclarations': - _functionDeclarations.map((f) => f.toJson()).toList(), - if (_googleSearch case final _googleSearch?) - 'googleSearch': _googleSearch.toJson(), - if (_codeExecution case final _codeExecution?) - 'codeExecution': _codeExecution.toJson(), - if (_urlContext case final _urlContext?) - 'urlContext': _urlContext.toJson(), - if (_googleMaps case final _googleMaps?) - 'googleMaps': _googleMaps.toJson(), - }; + if (_functionDeclarations case final _functionDeclarations?) + 'functionDeclarations': _functionDeclarations + .map((f) => f.toJson()) + .toList(), + if (_googleSearch case final _googleSearch?) + 'googleSearch': _googleSearch.toJson(), + if (_codeExecution case final _codeExecution?) + 'codeExecution': _codeExecution.toJson(), + if (_urlContext case final _urlContext?) 'urlContext': _urlContext.toJson(), + if (_googleMaps case final _googleMaps?) 'googleMaps': _googleMaps.toJson(), + }; } /// A tool that allows the generative model to connect to Google Search to @@ -214,15 +220,20 @@ final class CodeExecution { /// as a `Tool` by the model and executed by the client. class FunctionDeclaration { // ignore: public_member_api_docs - FunctionDeclaration(this.name, this.description, - {required Map parameters, - List optionalParameters = const []}) - : _schemaObject = parameters.values.any((s) => s is JSONSchema) - ? JSONSchema.object( - properties: parameters.cast(), - optionalProperties: optionalParameters) - : Schema.object( - properties: parameters, optionalProperties: optionalParameters); + FunctionDeclaration( + this.name, + this.description, { + required Map parameters, + List optionalParameters = const [], + }) : _schemaObject = parameters.values.any((s) => s is JSONSchema) + ? JSONSchema.object( + properties: parameters.cast(), + optionalProperties: optionalParameters, + ) + : Schema.object( + properties: parameters, + optionalProperties: optionalParameters, + ); /// The name of the function. /// @@ -237,13 +248,13 @@ class FunctionDeclaration { /// Convert to json object. Map toJson() => { - 'name': name, - 'description': description, - if (_schemaObject is JSONSchema) - 'parametersJsonSchema': _schemaObject.toJson() - else - 'parameters': _schemaObject.toJson(), - }; + 'name': name, + 'description': description, + if (_schemaObject is JSONSchema) + 'parametersJsonSchema': _schemaObject.toJson() + else + 'parameters': _schemaObject.toJson(), + }; } /// A [FunctionDeclaration] for auto function calling. @@ -261,12 +272,16 @@ final class AutoFunctionDeclaration extends FunctionDeclaration { required Map parameters, List optionalParameters = const [], required this.callable, - }) : super(name, description, - parameters: parameters, optionalParameters: optionalParameters); + }) : super( + name, + description, + parameters: parameters, + optionalParameters: optionalParameters, + ); /// The callable function that this declaration represents. final FutureOr> Function(Map args) - callable; + callable; } /// Config for tools to use with model. @@ -282,11 +297,10 @@ final class ToolConfig { /// Convert to json object. Map toJson() => { - if (functionCallingConfig case final config?) - 'functionCallingConfig': config.toJson(), - if (retrievalConfig case final config?) - 'retrievalConfig': config.toJson(), - }; + if (functionCallingConfig case final config?) + 'functionCallingConfig': config.toJson(), + if (retrievalConfig case final config?) 'retrievalConfig': config.toJson(), + }; } /// An object that represents a latitude/longitude pair. @@ -302,9 +316,9 @@ final class LatLng { /// Convert to json object. Map toJson() => { - 'latitude': latitude, - 'longitude': longitude, - }; + 'latitude': latitude, + 'longitude': longitude, + }; } /// The configuration that specifies information which can be used by tools @@ -321,9 +335,9 @@ final class RetrievalConfig { /// Convert to json object. Map toJson() => { - if (latLng case final latLng?) 'latLng': latLng.toJson(), - if (languageCode case final languageCode?) 'languageCode': languageCode, - }; + if (latLng case final latLng?) 'latLng': latLng.toJson(), + if (languageCode case final languageCode?) 'languageCode': languageCode, + }; } /// Configuration specifying how the model should use the functions provided as @@ -354,8 +368,9 @@ final class FunctionCallingConfig { /// Returns a [FunctionCallingConfig] instance with mode of [FunctionCallingMode.any]. static FunctionCallingConfig any(Set allowedFunctionNames) { return FunctionCallingConfig._( - mode: FunctionCallingMode.any, - allowedFunctionNames: allowedFunctionNames); + mode: FunctionCallingMode.any, + allowedFunctionNames: allowedFunctionNames, + ); } /// Returns a [FunctionCallingConfig] instance with mode of [FunctionCallingMode.none]. @@ -365,10 +380,10 @@ final class FunctionCallingConfig { /// Convert to json object. Object toJson() => { - if (mode case final mode?) 'mode': mode.toJson(), - if (allowedFunctionNames case final allowedFunctionNames?) - 'allowedFunctionNames': allowedFunctionNames.toList(), - }; + if (mode case final mode?) 'mode': mode.toJson(), + if (allowedFunctionNames case final allowedFunctionNames?) + 'allowedFunctionNames': allowedFunctionNames.toList(), + }; } /// The mode in which the model should use the functions provided as tools. @@ -390,8 +405,8 @@ enum FunctionCallingMode { /// Convert to json object. String toJson() => switch (this) { - auto => 'AUTO', - any => 'ANY', - none => 'NONE', - }; + auto => 'AUTO', + any => 'ANY', + none => 'NONE', + }; } diff --git a/packages/firebase_ai/firebase_ai/pubspec.yaml b/packages/firebase_ai/firebase_ai/pubspec.yaml index 0fbaadda838b..42c740e65923 100644 --- a/packages/firebase_ai/firebase_ai/pubspec.yaml +++ b/packages/firebase_ai/firebase_ai/pubspec.yaml @@ -17,7 +17,7 @@ platforms: web: environment: - sdk: '^3.6.0' + sdk: '^3.10.0' flutter: ">=3.16.0" dependencies: diff --git a/packages/firebase_ai/firebase_ai/test/api_test.dart b/packages/firebase_ai/firebase_ai/test/api_test.dart index ff65ed0405f4..ad0d30208354 100644 --- a/packages/firebase_ai/firebase_ai/test/api_test.dart +++ b/packages/firebase_ai/firebase_ai/test/api_test.dart @@ -47,19 +47,35 @@ void main() { final textContent = Content.text('Hello'); - final candidateWithText = - Candidate(textContent, null, null, FinishReason.stop, null); + final candidateWithText = Candidate( + textContent, + null, + null, + FinishReason.stop, + null, + ); final candidateWithMultipleTextParts = Candidate( - Content('model', [const TextPart('Hello'), const TextPart(' World')]), - null, - null, - FinishReason.stop, - null); + Content('model', [const TextPart('Hello'), const TextPart(' World')]), + null, + null, + FinishReason.stop, + null, + ); final candidateFinishedSafety = Candidate( - textContent, null, null, FinishReason.safety, 'Safety concern'); + textContent, + null, + null, + FinishReason.safety, + 'Safety concern', + ); final candidateFinishedRecitation = Candidate( - textContent, null, null, FinishReason.recitation, 'Recited content'); + textContent, + null, + null, + FinishReason.recitation, + 'Recited content', + ); group('.text getter', () { test('returns null if no candidates and no prompt feedback', () { @@ -68,67 +84,107 @@ void main() { }); test( - 'throws FirebaseAIException if prompt was blocked without message or reason', - () { - final feedback = PromptFeedback(BlockReason.safety, null, []); - final response = GenerateContentResponse([], feedback); - expect( + 'throws FirebaseAIException if prompt was blocked without message or reason', + () { + final feedback = PromptFeedback(BlockReason.safety, null, []); + final response = GenerateContentResponse([], feedback); + expect( () => response.text, - throwsA(isA().having((e) => e.message, - 'message', 'Response was blocked due to safety'))); - }); + throwsA( + isA().having( + (e) => e.message, + 'message', + 'Response was blocked due to safety', + ), + ), + ); + }, + ); test( - 'throws FirebaseAIException if prompt was blocked with reason and message', - () { - final feedback = - PromptFeedback(BlockReason.other, 'Custom block message', []); - final response = GenerateContentResponse([], feedback); - expect( + 'throws FirebaseAIException if prompt was blocked with reason and message', + () { + final feedback = PromptFeedback( + BlockReason.other, + 'Custom block message', + [], + ); + final response = GenerateContentResponse([], feedback); + expect( () => response.text, - throwsA(isA().having( + throwsA( + isA().having( (e) => e.message, 'message', - 'Response was blocked due to other: Custom block message'))); - }); + 'Response was blocked due to other: Custom block message', + ), + ), + ); + }, + ); test( - 'throws FirebaseAIException if first candidate finished due to safety', - () { - final response = - GenerateContentResponse([candidateFinishedSafety], null); - expect( + 'throws FirebaseAIException if first candidate finished due to safety', + () { + final response = GenerateContentResponse([ + candidateFinishedSafety, + ], null); + expect( () => response.text, - throwsA(isA().having( + throwsA( + isA().having( (e) => e.message, 'message', - 'Candidate was blocked due to safety: Safety concern'))); - }); + 'Candidate was blocked due to safety: Safety concern', + ), + ), + ); + }, + ); test( - 'throws FirebaseAIException if first candidate finished due to safety without message', - () { - final candidateFinishedSafetyNoMsg = - Candidate(textContent, null, null, FinishReason.safety, ''); - final response = - GenerateContentResponse([candidateFinishedSafetyNoMsg], null); - expect( + 'throws FirebaseAIException if first candidate finished due to safety without message', + () { + final candidateFinishedSafetyNoMsg = Candidate( + textContent, + null, + null, + FinishReason.safety, + '', + ); + final response = GenerateContentResponse([ + candidateFinishedSafetyNoMsg, + ], null); + expect( () => response.text, - throwsA(isA().having((e) => e.message, - 'message', 'Candidate was blocked due to safety'))); - }); + throwsA( + isA().having( + (e) => e.message, + 'message', + 'Candidate was blocked due to safety', + ), + ), + ); + }, + ); test( - 'throws FirebaseAIException if first candidate finished due to recitation', - () { - final response = - GenerateContentResponse([candidateFinishedRecitation], null); - expect( + 'throws FirebaseAIException if first candidate finished due to recitation', + () { + final response = GenerateContentResponse([ + candidateFinishedRecitation, + ], null); + expect( () => response.text, - throwsA(isA().having( + throwsA( + isA().having( (e) => e.message, 'message', - 'Candidate was blocked due to recitation: Recited content'))); - }); + 'Candidate was blocked due to recitation: Recited content', + ), + ), + ); + }, + ); test('returns text from single TextPart in first candidate', () { final response = GenerateContentResponse([candidateWithText], null); @@ -136,8 +192,9 @@ void main() { }); test('concatenates text from multiple TextParts in first candidate', () { - final response = - GenerateContentResponse([candidateWithMultipleTextParts], null); + final response = GenerateContentResponse([ + candidateWithMultipleTextParts, + ], null); expect(response.text, 'Hello World'); }); }); @@ -148,20 +205,19 @@ void main() { expect(response.functionCalls, isEmpty); }); - test('returns empty list if first candidate has no FunctionCall parts', - () { - final response = GenerateContentResponse([candidateWithText], null); - expect(response.functionCalls, isEmpty); - }); + test( + 'returns empty list if first candidate has no FunctionCall parts', + () { + final response = GenerateContentResponse([candidateWithText], null); + expect(response.functionCalls, isEmpty); + }, + ); }); test('constructor initializes fields correctly', () { final candidates = [candidateWithText]; final feedback = PromptFeedback(null, null, []); - final response = GenerateContentResponse( - candidates, - feedback, - ); + final response = GenerateContentResponse(candidates, feedback); expect(response.candidates, same(candidates)); expect(response.promptFeedback, same(feedback)); @@ -171,7 +227,7 @@ void main() { group('PromptFeedback', () { test('constructor initializes fields correctly', () { final ratings = [ - SafetyRating(HarmCategory.dangerousContent, HarmProbability.high) + SafetyRating(HarmCategory.dangerousContent, HarmProbability.high), ]; final feedback = PromptFeedback(BlockReason.safety, 'Blocked', ratings); expect(feedback.blockReason, BlockReason.safety); @@ -183,71 +239,126 @@ void main() { group('Candidate', () { final textContent = Content.text('Test text'); group('.text getter', () { - test('throws FirebaseAIException if finishReason is safety with message', - () { - final candidate = Candidate(textContent, null, null, - FinishReason.safety, 'Safety block message'); - expect( + test( + 'throws FirebaseAIException if finishReason is safety with message', + () { + final candidate = Candidate( + textContent, + null, + null, + FinishReason.safety, + 'Safety block message', + ); + expect( () => candidate.text, - throwsA(isA().having( + throwsA( + isA().having( (e) => e.message, 'message', - 'Candidate was blocked due to safety: Safety block message'))); - }); + 'Candidate was blocked due to safety: Safety block message', + ), + ), + ); + }, + ); test( - 'throws FirebaseAIException if finishReason is safety without message', - () { - final candidate = Candidate( - textContent, null, null, FinishReason.safety, ''); // Empty message - expect( + 'throws FirebaseAIException if finishReason is safety without message', + () { + final candidate = Candidate( + textContent, + null, + null, + FinishReason.safety, + '', + ); // Empty message + expect( () => candidate.text, - throwsA(isA().having((e) => e.message, - 'message', 'Candidate was blocked due to safety'))); - }); + throwsA( + isA().having( + (e) => e.message, + 'message', + 'Candidate was blocked due to safety', + ), + ), + ); + }, + ); test( - 'throws FirebaseAIException if finishReason is recitation with message', - () { - final candidate = Candidate(textContent, null, null, - FinishReason.recitation, 'Recitation block message'); - expect( + 'throws FirebaseAIException if finishReason is recitation with message', + () { + final candidate = Candidate( + textContent, + null, + null, + FinishReason.recitation, + 'Recitation block message', + ); + expect( () => candidate.text, - throwsA(isA().having( + throwsA( + isA().having( (e) => e.message, 'message', - 'Candidate was blocked due to recitation: Recitation block message'))); - }); + 'Candidate was blocked due to recitation: Recitation block message', + ), + ), + ); + }, + ); test('returns text from single TextPart', () { - final candidate = - Candidate(textContent, null, null, FinishReason.stop, null); + final candidate = Candidate( + textContent, + null, + null, + FinishReason.stop, + null, + ); expect(candidate.text, 'Test text'); }); test('concatenates text from multiple TextParts', () { - final multiPartContent = Content( - 'model', [const TextPart('Part 1'), const TextPart('. Part 2')]); - final candidate = - Candidate(multiPartContent, null, null, FinishReason.stop, null); + final multiPartContent = Content('model', [ + const TextPart('Part 1'), + const TextPart('. Part 2'), + ]); + final candidate = Candidate( + multiPartContent, + null, + null, + FinishReason.stop, + null, + ); expect(candidate.text, 'Part 1. Part 2'); }); test('returns text if finishReason is other non-blocking reason', () { - final candidate = - Candidate(textContent, null, null, FinishReason.maxTokens, null); + final candidate = Candidate( + textContent, + null, + null, + FinishReason.maxTokens, + null, + ); expect(candidate.text, 'Test text'); }); }); test('constructor initializes fields correctly', () { final content = Content.text('Hello'); final ratings = [ - SafetyRating(HarmCategory.harassment, HarmProbability.low) + SafetyRating(HarmCategory.harassment, HarmProbability.low), ]; final citationMeta = CitationMetadata([]); final urlContextMetadata = UrlContextMetadata(urlMetadata: []); final candidate = Candidate( - content, ratings, citationMeta, FinishReason.stop, 'Finished', - urlContextMetadata: urlContextMetadata); + content, + ratings, + citationMeta, + FinishReason.stop, + 'Finished', + urlContextMetadata: urlContextMetadata, + ); expect(candidate.content, same(content)); expect(candidate.safetyRatings, same(ratings)); @@ -261,11 +372,13 @@ void main() { group('SafetyRating', () { test('constructor initializes fields correctly', () { final rating = SafetyRating( - HarmCategory.hateSpeech, HarmProbability.medium, - probabilityScore: 0.6, - isBlocked: true, - severity: HarmSeverity.high, - severityScore: 0.9); + HarmCategory.hateSpeech, + HarmProbability.medium, + probabilityScore: 0.6, + isBlocked: true, + severity: HarmSeverity.high, + severityScore: 0.9, + ); expect(rating.category, HarmCategory.hateSpeech); expect(rating.probability, HarmProbability.medium); expect(rating.probabilityScore, 0.6); @@ -286,17 +399,27 @@ void main() { expect(HarmCategory.unknown.toJson(), 'UNKNOWN'); expect(HarmCategory.harassment.toJson(), 'HARM_CATEGORY_HARASSMENT'); expect(HarmCategory.hateSpeech.toJson(), 'HARM_CATEGORY_HATE_SPEECH'); - expect(HarmCategory.sexuallyExplicit.toJson(), - 'HARM_CATEGORY_SEXUALLY_EXPLICIT'); - expect(HarmCategory.dangerousContent.toJson(), - 'HARM_CATEGORY_DANGEROUS_CONTENT'); + expect( + HarmCategory.sexuallyExplicit.toJson(), + 'HARM_CATEGORY_SEXUALLY_EXPLICIT', + ); + expect( + HarmCategory.dangerousContent.toJson(), + 'HARM_CATEGORY_DANGEROUS_CONTENT', + ); expect(HarmCategory.imageHate.toJson(), 'HARM_CATEGORY_IMAGE_HATE'); - expect(HarmCategory.imageDangerousContent.toJson(), - 'HARM_CATEGORY_IMAGE_DANGEROUS_CONTENT'); - expect(HarmCategory.imageHarassment.toJson(), - 'HARM_CATEGORY_IMAGE_HARASSMENT'); - expect(HarmCategory.imageSexuallyExplicit.toJson(), - 'HARM_CATEGORY_IMAGE_SEXUALLY_EXPLICIT'); + expect( + HarmCategory.imageDangerousContent.toJson(), + 'HARM_CATEGORY_IMAGE_DANGEROUS_CONTENT', + ); + expect( + HarmCategory.imageHarassment.toJson(), + 'HARM_CATEGORY_IMAGE_HARASSMENT', + ); + expect( + HarmCategory.imageSexuallyExplicit.toJson(), + 'HARM_CATEGORY_IMAGE_SEXUALLY_EXPLICIT', + ); }); test('HarmProbability toJson and toString', () { @@ -321,22 +444,28 @@ void main() { expect(FinishReason.maxTokens.toJson(), 'MAX_TOKENS'); expect(FinishReason.safety.toJson(), 'SAFETY'); expect(FinishReason.recitation.toJson(), 'RECITATION'); - expect(FinishReason.malformedFunctionCall.toJson(), - 'MALFORMED_FUNCTION_CALL'); + expect( + FinishReason.malformedFunctionCall.toJson(), + 'MALFORMED_FUNCTION_CALL', + ); expect(FinishReason.blocklist.toJson(), 'BLOCKLIST'); expect(FinishReason.prohibitedContent.toJson(), 'PROHIBITED_CONTENT'); expect(FinishReason.spii.toJson(), 'SPII'); expect(FinishReason.imageSafety.toJson(), 'IMAGE_SAFETY'); - expect(FinishReason.imageProhibitedContent.toJson(), - 'IMAGE_PROHIBITED_CONTENT'); + expect( + FinishReason.imageProhibitedContent.toJson(), + 'IMAGE_PROHIBITED_CONTENT', + ); expect(FinishReason.imageOther.toJson(), 'IMAGE_OTHER'); expect(FinishReason.noImage.toJson(), 'NO_IMAGE'); expect(FinishReason.imageRecitation.toJson(), 'IMAGE_RECITATION'); expect(FinishReason.language.toJson(), 'LANGUAGE'); expect(FinishReason.unexpectedToolCall.toJson(), 'UNEXPECTED_TOOL_CALL'); expect(FinishReason.tooManyToolCalls.toJson(), 'TOO_MANY_TOOL_CALLS'); - expect(FinishReason.missingThoughtSignature.toJson(), - 'MISSING_THOUGHT_SIGNATURE'); + expect( + FinishReason.missingThoughtSignature.toJson(), + 'MISSING_THOUGHT_SIGNATURE', + ); expect(FinishReason.malformedResponse.toJson(), 'MALFORMED_RESPONSE'); expect(FinishReason.other.toJson(), 'OTHER'); }); @@ -346,28 +475,44 @@ void main() { expect(FinishReason.parseValue('MAX_TOKENS'), FinishReason.maxTokens); expect(FinishReason.parseValue('SAFETY'), FinishReason.safety); expect(FinishReason.parseValue('RECITATION'), FinishReason.recitation); - expect(FinishReason.parseValue('MALFORMED_FUNCTION_CALL'), - FinishReason.malformedFunctionCall); + expect( + FinishReason.parseValue('MALFORMED_FUNCTION_CALL'), + FinishReason.malformedFunctionCall, + ); expect(FinishReason.parseValue('BLOCKLIST'), FinishReason.blocklist); - expect(FinishReason.parseValue('PROHIBITED_CONTENT'), - FinishReason.prohibitedContent); + expect( + FinishReason.parseValue('PROHIBITED_CONTENT'), + FinishReason.prohibitedContent, + ); expect(FinishReason.parseValue('SPII'), FinishReason.spii); expect(FinishReason.parseValue('IMAGE_SAFETY'), FinishReason.imageSafety); - expect(FinishReason.parseValue('IMAGE_PROHIBITED_CONTENT'), - FinishReason.imageProhibitedContent); + expect( + FinishReason.parseValue('IMAGE_PROHIBITED_CONTENT'), + FinishReason.imageProhibitedContent, + ); expect(FinishReason.parseValue('IMAGE_OTHER'), FinishReason.imageOther); expect(FinishReason.parseValue('NO_IMAGE'), FinishReason.noImage); - expect(FinishReason.parseValue('IMAGE_RECITATION'), - FinishReason.imageRecitation); + expect( + FinishReason.parseValue('IMAGE_RECITATION'), + FinishReason.imageRecitation, + ); expect(FinishReason.parseValue('LANGUAGE'), FinishReason.language); - expect(FinishReason.parseValue('UNEXPECTED_TOOL_CALL'), - FinishReason.unexpectedToolCall); - expect(FinishReason.parseValue('TOO_MANY_TOOL_CALLS'), - FinishReason.tooManyToolCalls); - expect(FinishReason.parseValue('MISSING_THOUGHT_SIGNATURE'), - FinishReason.missingThoughtSignature); - expect(FinishReason.parseValue('MALFORMED_RESPONSE'), - FinishReason.malformedResponse); + expect( + FinishReason.parseValue('UNEXPECTED_TOOL_CALL'), + FinishReason.unexpectedToolCall, + ); + expect( + FinishReason.parseValue('TOO_MANY_TOOL_CALLS'), + FinishReason.tooManyToolCalls, + ); + expect( + FinishReason.parseValue('MISSING_THOUGHT_SIGNATURE'), + FinishReason.missingThoughtSignature, + ); + expect( + FinishReason.parseValue('MALFORMED_RESPONSE'), + FinishReason.malformedResponse, + ); expect(FinishReason.parseValue('OTHER'), FinishReason.other); expect(FinishReason.parseValue('UNSPECIFIED'), FinishReason.unknown); }); @@ -392,8 +537,10 @@ void main() { test('HarmBlockMethod toJson and toString', () { expect(HarmBlockMethod.severity.toJson(), 'SEVERITY'); expect(HarmBlockMethod.probability.toJson(), 'PROBABILITY'); - expect(HarmBlockMethod.unspecified.toJson(), - 'HARM_BLOCK_METHOD_UNSPECIFIED'); + expect( + HarmBlockMethod.unspecified.toJson(), + 'HARM_BLOCK_METHOD_UNSPECIFIED', + ); }); test('TaskType toJson and toString', () { @@ -433,8 +580,11 @@ void main() { group('SafetySetting', () { test('toJson with all fields', () { - final setting = SafetySetting(HarmCategory.dangerousContent, - HarmBlockThreshold.medium, HarmBlockMethod.severity); + final setting = SafetySetting( + HarmCategory.dangerousContent, + HarmBlockThreshold.medium, + HarmBlockMethod.severity, + ); expect(setting.toJson(), { 'category': 'HARM_CATEGORY_DANGEROUS_CONTENT', 'threshold': 'BLOCK_MEDIUM_AND_ABOVE', @@ -444,8 +594,11 @@ void main() { test('toJson with method null (default to probability in spirit)', () { // The toJson implementation will omit method if null - final setting = - SafetySetting(HarmCategory.harassment, HarmBlockThreshold.low, null); + final setting = SafetySetting( + HarmCategory.harassment, + HarmBlockThreshold.low, + null, + ); expect(setting.toJson(), { 'category': 'HARM_CATEGORY_HARASSMENT', 'threshold': 'BLOCK_LOW_AND_ABOVE', @@ -458,8 +611,9 @@ void main() { final searchEntryPoint = SearchEntryPoint(renderedContent: '
'); final groundingChunk = GroundingChunk(web: WebGroundingChunk(uri: 'uri')); final groundingSupports = GroundingSupport( - segment: Segment(startIndex: 0, partIndex: 0, endIndex: 1, text: ''), - groundingChunkIndices: [0]); + segment: Segment(startIndex: 0, partIndex: 0, endIndex: 1, text: ''), + groundingChunkIndices: [0], + ); final metadata = GroundingMetadata( searchEntryPoint: searchEntryPoint, groundingChunks: [groundingChunk], @@ -478,15 +632,18 @@ void main() { test('UrlMetadata constructor', () { final uri = Uri.parse('http://example.com/page'); final metadata = UrlMetadata( - retrievedUrl: uri, urlRetrievalStatus: UrlRetrievalStatus.success); + retrievedUrl: uri, + urlRetrievalStatus: UrlRetrievalStatus.success, + ); expect(metadata.retrievedUrl, uri); expect(metadata.urlRetrievalStatus, UrlRetrievalStatus.success); }); test('UrlContextMetadata constructor', () { final urlMetadata = UrlMetadata( - retrievedUrl: Uri.parse('http://example.com'), - urlRetrievalStatus: UrlRetrievalStatus.success); + retrievedUrl: Uri.parse('http://example.com'), + urlRetrievalStatus: UrlRetrievalStatus.success, + ); final contextMetadata = UrlContextMetadata(urlMetadata: [urlMetadata]); expect(contextMetadata.urlMetadata, hasLength(1)); expect(contextMetadata.urlMetadata.first, same(urlMetadata)); @@ -499,31 +656,20 @@ void main() { aspectRatio: ImageAspectRatio.portrait9x16, imageSize: ImageSize.size2K, ); - expect(config.toJson(), { - 'aspectRatio': '9:16', - 'imageSize': '2K', - }); + expect(config.toJson(), {'aspectRatio': '9:16', 'imageSize': '2K'}); }); test('toJson with some fields null', () { - const config = ImageConfig( - aspectRatio: ImageAspectRatio.landscape16x9, - ); - expect(config.toJson(), { - 'aspectRatio': '16:9', - }); + const config = ImageConfig(aspectRatio: ImageAspectRatio.landscape16x9); + expect(config.toJson(), {'aspectRatio': '16:9'}); }); }); group('GenerationConfig & BaseGenerationConfig', () { test('GenerationConfig serializes mediaResolution', () { - final config = GenerationConfig( - mediaResolution: MediaResolution.high, - ); + final config = GenerationConfig(mediaResolution: MediaResolution.high); - expect(config.toJson(), { - 'mediaResolution': 'MEDIA_RESOLUTION_HIGH', - }); + expect(config.toJson(), {'mediaResolution': 'MEDIA_RESOLUTION_HIGH'}); }); test('GenerationConfig rejects ultraHigh mediaResolution', () { @@ -537,7 +683,9 @@ void main() { final schema = Schema.object(properties: {}); final thinkingConfig = ThinkingConfig(thinkingBudget: 100); const imageConfig = ImageConfig( - aspectRatio: ImageAspectRatio.square1x1, imageSize: ImageSize.size1K); + aspectRatio: ImageAspectRatio.square1x1, + imageSize: ImageSize.size1K, + ); final config = GenerationConfig( candidateCount: 1, stopSequences: ['\n', 'stop'], @@ -566,10 +714,7 @@ void main() { 'responseSchema': schema.toJson(), 'mediaResolution': 'MEDIA_RESOLUTION_MEDIUM', 'thinkingConfig': {'thinkingBudget': 100}, - 'imageConfig': { - 'aspectRatio': '1:1', - 'imageSize': '1K', - }, + 'imageConfig': {'aspectRatio': '1:1', 'imageSize': '1K'}, }); }); @@ -577,9 +722,9 @@ void main() { final jsonSchema = { 'type': 'object', 'properties': { - 'recipeName': {'type': 'string'} + 'recipeName': {'type': 'string'}, }, - 'required': ['recipeName'] + 'required': ['recipeName'], }; final config = GenerationConfig( responseMimeType: 'application/json', @@ -593,17 +738,21 @@ void main() { }); test( - 'throws assertion if both responseSchema and responseJsonSchema are provided', - () { - final schema = Schema.object(properties: {}); - final jsonSchema = - (json.decode('{"type": "string", "title": "MyString"}') as Map) - .cast(); - expect( + 'throws assertion if both responseSchema and responseJsonSchema are provided', + () { + final schema = Schema.object(properties: {}); + final jsonSchema = + (json.decode('{"type": "string", "title": "MyString"}') as Map) + .cast(); + expect( () => GenerationConfig( - responseSchema: schema, responseJsonSchema: jsonSchema), - throwsA(isA())); - }); + responseSchema: schema, + responseJsonSchema: jsonSchema, + ), + throwsA(isA()), + ); + }, + ); test('GenerationConfig toJson with empty stopSequences (omitted)', () { final config = GenerationConfig(stopSequences: []); @@ -635,11 +784,15 @@ void main() { }); test('toJson with thinkingLevel set', () { - final config = ThinkingConfig.withThinkingLevel(ThinkingLevel.high, - includeThoughts: true); + final config = ThinkingConfig.withThinkingLevel( + ThinkingLevel.high, + includeThoughts: true, + ); - expect( - config.toJson(), {'thinkingLevel': 'HIGH', 'includeThoughts': true}); + expect(config.toJson(), { + 'thinkingLevel': 'HIGH', + 'includeThoughts': true, + }); }); test('toJson with includeThoughts set', () { @@ -681,8 +834,10 @@ void main() { }); test('withThinkingBudget factory initializes correctly', () { - final config = - ThinkingConfig.withThinkingBudget(789, includeThoughts: false); + final config = ThinkingConfig.withThinkingBudget( + 789, + includeThoughts: false, + ); expect(config.thinkingBudget, 789); expect(config.thinkingLevel, isNull); @@ -690,8 +845,10 @@ void main() { }); test('withThinkingLevel factory initializes correctly', () { - final config = ThinkingConfig.withThinkingLevel(ThinkingLevel.medium, - includeThoughts: true); + final config = ThinkingConfig.withThinkingLevel( + ThinkingLevel.medium, + includeThoughts: true, + ); expect(config.thinkingBudget, isNull); expect(config.thinkingLevel, ThinkingLevel.medium); @@ -699,13 +856,17 @@ void main() { }); test( - 'deprecated constructor throws AssertionError if both thinkingBudget and thinkingLevel are provided', - () { - expect( + 'deprecated constructor throws AssertionError if both thinkingBudget and thinkingLevel are provided', + () { + expect( () => ThinkingConfig( - thinkingBudget: 100, thinkingLevel: ThinkingLevel.high), - throwsA(isA())); - }); + thinkingBudget: 100, + thinkingLevel: ThinkingLevel.high, + ), + throwsA(isA()), + ); + }, + ); }); group('Parsing Functions', () { @@ -714,54 +875,64 @@ void main() { final json = { 'totalTokens': 120, 'promptTokensDetails': [ - { - 'modality': 'TEXT', - }, - {'modality': 'IMAGE', 'tokenCount': 20} - ] + {'modality': 'TEXT'}, + {'modality': 'IMAGE', 'tokenCount': 20}, + ], }; - final response = - AgentPlatformSerialization().parseCountTokensResponse(json); + final response = AgentPlatformSerialization().parseCountTokensResponse( + json, + ); expect(response.totalTokens, 120); expect(response.promptTokensDetails, isNotNull); expect(response.promptTokensDetails, hasLength(2)); expect(response.promptTokensDetails![0].modality, ContentModality.text); expect(response.promptTokensDetails![0].tokenCount, 0); expect( - response.promptTokensDetails![1].modality, ContentModality.image); + response.promptTokensDetails![1].modality, + ContentModality.image, + ); expect(response.promptTokensDetails![1].tokenCount, 20); }); test('parses valid JSON with minimal fields (only totalTokens)', () { final json = {'totalTokens': 50}; - final response = - AgentPlatformSerialization().parseCountTokensResponse(json); + final response = AgentPlatformSerialization().parseCountTokensResponse( + json, + ); expect(response.totalTokens, 50); expect(response.promptTokensDetails, isNull); }); test('throws FirebaseAIException if JSON contains error field', () { final json = { - 'error': {'code': 400, 'message': 'Invalid request'} + 'error': {'code': 400, 'message': 'Invalid request'}, }; expect( - () => AgentPlatformSerialization().parseCountTokensResponse(json), - throwsA(isA())); + () => AgentPlatformSerialization().parseCountTokensResponse(json), + throwsA(isA()), + ); }); test('throws FormatException for invalid JSON structure (not a Map)', () { const json = 'not_a_map'; expect( - () => AgentPlatformSerialization().parseCountTokensResponse(json), - throwsA(isA().having( - (e) => e.message, 'message', contains('CountTokensResponse')))); + () => AgentPlatformSerialization().parseCountTokensResponse(json), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('CountTokensResponse'), + ), + ), + ); }); test('throws if totalTokens is missing', () { final json = {'totalBillableCharacters': 100}; expect( - () => AgentPlatformSerialization().parseCountTokensResponse(json), - throwsA(anything)); // More specific error expected + () => AgentPlatformSerialization().parseCountTokensResponse(json), + throwsA(anything), + ); // More specific error expected }); }); @@ -770,16 +941,16 @@ void main() { 'content': { 'role': 'model', 'parts': [ - {'text': 'Hello world'} - ] + {'text': 'Hello world'}, + ], }, 'finishReason': 'STOP', 'safetyRatings': [ { 'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT', - 'probability': 'NEGLIGIBLE' - } - ] + 'probability': 'NEGLIGIBLE', + }, + ], }; test('parses valid JSON with candidates and promptFeedback', () { @@ -794,24 +965,24 @@ void main() { 'probability': 'HIGH', 'blocked': true, 'severity': 'HARM_SEVERITY_HIGH', - 'severityScore': 0.95 - } - ] + 'severityScore': 0.95, + }, + ], }, 'usageMetadata': { 'promptTokenCount': 10, 'candidatesTokenCount': 20, 'totalTokenCount': 30, 'promptTokensDetails': [ - {'modality': 'TEXT', 'tokenCount': 10} + {'modality': 'TEXT', 'tokenCount': 10}, ], 'candidatesTokensDetails': [ - {'modality': 'TEXT', 'tokenCount': 20} + {'modality': 'TEXT', 'tokenCount': 20}, ], - } + }, }; - final response = - AgentPlatformSerialization().parseGenerateContentResponse(json); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(json); expect(response.candidates, hasLength(1)); expect(response.candidates.first.text, 'Hello world'); expect(response.candidates.first.finishReason, FinishReason.stop); @@ -820,18 +991,28 @@ void main() { expect(response.promptFeedback, isNotNull); expect(response.promptFeedback!.blockReason, BlockReason.safety); - expect(response.promptFeedback!.blockReasonMessage, - 'Prompt was too spicy.'); + expect( + response.promptFeedback!.blockReasonMessage, + 'Prompt was too spicy.', + ); expect(response.promptFeedback!.safetyRatings, hasLength(1)); - expect(response.promptFeedback!.safetyRatings.first.category, - HarmCategory.dangerousContent); - expect(response.promptFeedback!.safetyRatings.first.probability, - HarmProbability.high); + expect( + response.promptFeedback!.safetyRatings.first.category, + HarmCategory.dangerousContent, + ); + expect( + response.promptFeedback!.safetyRatings.first.probability, + HarmProbability.high, + ); expect(response.promptFeedback!.safetyRatings.first.isBlocked, true); - expect(response.promptFeedback!.safetyRatings.first.severity, - HarmSeverity.high); expect( - response.promptFeedback!.safetyRatings.first.severityScore, 0.95); + response.promptFeedback!.safetyRatings.first.severity, + HarmSeverity.high, + ); + expect( + response.promptFeedback!.safetyRatings.first.severityScore, + 0.95, + ); expect(response.usageMetadata, isNotNull); expect(response.usageMetadata!.promptTokenCount, 10); @@ -848,33 +1029,33 @@ void main() { 'content': { 'role': 'model', 'parts': [ - {'text': ''} - ] + {'text': ''}, + ], }, 'finishReason': 'STOP', 'safetyRatings': [ { 'category': 'HARM_CATEGORY_IMAGE_DANGEROUS_CONTENT', - 'probability': 'NEGLIGIBLE' + 'probability': 'NEGLIGIBLE', }, { 'category': 'HARM_CATEGORY_IMAGE_SEXUALLY_EXPLICIT', - 'probability': 'NEGLIGIBLE' + 'probability': 'NEGLIGIBLE', }, { 'category': 'HARM_CATEGORY_IMAGE_HATE', - 'probability': 'NEGLIGIBLE' + 'probability': 'NEGLIGIBLE', }, { 'category': 'HARM_CATEGORY_IMAGE_HARASSMENT', - 'probability': 'NEGLIGIBLE' + 'probability': 'NEGLIGIBLE', }, - ] - } - ] + ], + }, + ], }; - final response = - AgentPlatformSerialization().parseGenerateContentResponse(json); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(json); final ratings = response.candidates.first.safetyRatings!; expect(ratings.map((r) => r.category), [ HarmCategory.imageDangerousContent, @@ -891,23 +1072,25 @@ void main() { 'content': { 'role': 'model', 'parts': [ - {'text': ''} - ] + {'text': ''}, + ], }, 'finishReason': 'STOP', 'safetyRatings': [ { 'category': 'HARM_CATEGORY_SOMETHING_NEW', - 'probability': 'NEGLIGIBLE' - } - ] - } - ] + 'probability': 'NEGLIGIBLE', + }, + ], + }, + ], }; - final response = - AgentPlatformSerialization().parseGenerateContentResponse(json); - expect(response.candidates.first.safetyRatings!.first.category, - HarmCategory.unknown); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(json); + expect( + response.candidates.first.safetyRatings!.first.category, + HarmCategory.unknown, + ); }); group('usageMetadata parsing', () { @@ -918,11 +1101,11 @@ void main() { 'candidatesTokenCount': 20, 'totalTokenCount': 30, 'thoughtsTokenCount': 5, - 'toolUsePromptTokenCount': 12 - } + 'toolUsePromptTokenCount': 12, + }, }; - final response = - AgentPlatformSerialization().parseGenerateContentResponse(json); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(json); expect(response.usageMetadata, isNotNull); expect(response.usageMetadata!.promptTokenCount, 10); expect(response.usageMetadata!.candidatesTokenCount, 20); @@ -937,10 +1120,10 @@ void main() { 'promptTokenCount': 10, 'candidatesTokenCount': 20, 'totalTokenCount': 30, - } + }, }; - final response = - AgentPlatformSerialization().parseGenerateContentResponse(json); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(json); expect(response.usageMetadata, isNotNull); expect(response.usageMetadata!.thoughtsTokenCount, isNull); }); @@ -953,8 +1136,8 @@ void main() { { 'content': { 'parts': [ - {'text': 'This is a grounded response.'} - ] + {'text': 'This is a grounded response.'}, + ], }, 'finishReason': 'STOP', 'groundingMetadata': { @@ -965,22 +1148,22 @@ void main() { 'web': { 'uri': 'http://example.com/1', 'title': 'Example Page 1', - } - } + }, + }, ], 'groundingSupports': [ { 'segment': { 'startIndex': 5, 'endIndex': 13, - 'text': 'grounded' + 'text': 'grounded', }, 'groundingChunkIndices': [0], - } - ] - } - } - ] + }, + ], + }, + }, + ], }; final response = AgentPlatformSerialization() @@ -988,10 +1171,14 @@ void main() { final groundingMetadata = response.candidates.first.groundingMetadata; expect(groundingMetadata, isNotNull); - expect(groundingMetadata!.webSearchQueries, - equals(['query1', 'query2'])); - expect(groundingMetadata.searchEntryPoint?.renderedContent, - '
'); + expect( + groundingMetadata!.webSearchQueries, + equals(['query1', 'query2']), + ); + expect( + groundingMetadata.searchEntryPoint?.renderedContent, + '
', + ); final groundingChunk = groundingMetadata.groundingChunks.first; expect(groundingChunk.web?.uri, 'http://example.com/1'); @@ -1012,8 +1199,8 @@ void main() { { 'content': { 'parts': [ - {'text': 'This is a grounded response.'} - ] + {'text': 'This is a grounded response.'}, + ], }, 'finishReason': 'STOP', 'groundingMetadata': { @@ -1033,13 +1220,13 @@ void main() { 'startIndex': 5, 'partIndex': 0, 'endIndex': 13, - 'text': 'grounded' + 'text': 'grounded', }, - } - ] - } - } - ] + }, + ], + }, + }, + ], }; final response = AgentPlatformSerialization() @@ -1047,8 +1234,10 @@ void main() { final groundingMetadata = response.candidates.first.groundingMetadata; expect(groundingMetadata, isNotNull); - expect(groundingMetadata!.webSearchQueries, - equals(['query1', 'query2'])); + expect( + groundingMetadata!.webSearchQueries, + equals(['query1', 'query2']), + ); expect(groundingMetadata.searchEntryPoint, isNull); expect(groundingMetadata.groundingChunks[0].web, isNull); @@ -1059,234 +1248,290 @@ void main() { expect(groundingMetadata.groundingChunks[1].web?.domain, isNull); expect( - groundingMetadata.groundingSupports, - hasLength( - 1)); // GroundingSupport's without a segment are filtered out + groundingMetadata.groundingSupports, + hasLength(1), + ); // GroundingSupport's without a segment are filtered out final firstSupport = groundingMetadata.groundingSupports[0]; expect(firstSupport.segment, isNotNull); expect(firstSupport.groundingChunkIndices, isNotEmpty); }); test( - 'throws FormatException if renderedContent is missing in searchEntryPoint', - () { - final jsonResponse = { - 'candidates': [ - { - 'content': { - 'parts': [ - {'text': 'This is a grounded response.'} - ] + 'throws FormatException if renderedContent is missing in searchEntryPoint', + () { + final jsonResponse = { + 'candidates': [ + { + 'content': { + 'parts': [ + {'text': 'This is a grounded response.'}, + ], + }, + 'finishReason': 'STOP', + 'groundingMetadata': {'searchEntryPoint': {}}, }, - 'finishReason': 'STOP', - 'groundingMetadata': {'searchEntryPoint': {}} - } - ] - }; - - expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(jsonResponse), - throwsA(isA().having( - (e) => e.message, 'message', contains('SearchEntryPoint')))); - }); + ], + }; + + expect( + () => AgentPlatformSerialization().parseGenerateContentResponse( + jsonResponse, + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('SearchEntryPoint'), + ), + ), + ); + }, + ); test( - 'parses groundingMetadata with all optional fields null/missing and empty lists', - () { - final jsonResponse = { - 'candidates': [ - { - 'content': { - 'parts': [ - {'text': 'Test'} - ] + 'parses groundingMetadata with all optional fields null/missing and empty lists', + () { + final jsonResponse = { + 'candidates': [ + { + 'content': { + 'parts': [ + {'text': 'Test'}, + ], + }, + 'finishReason': 'STOP', + 'groundingMetadata': { + // searchEntryPoint is missing + // groundingChunks is missing (defaults to []) + // groundingSupports is missing (defaults to []) + // webSearchQueries is missing (defaults to []) + }, }, - 'finishReason': 'STOP', - 'groundingMetadata': { - // searchEntryPoint is missing - // groundingChunks is missing (defaults to []) - // groundingSupports is missing (defaults to []) - // webSearchQueries is missing (defaults to []) - } - } - ] - }; - final response = AgentPlatformSerialization() - .parseGenerateContentResponse(jsonResponse); - final groundingMetadata = response.candidates.first.groundingMetadata; - - expect(groundingMetadata, isNotNull); - expect(groundingMetadata!.searchEntryPoint, isNull); - expect(groundingMetadata.groundingChunks, isEmpty); - expect(groundingMetadata.groundingSupports, isEmpty); - expect(groundingMetadata.webSearchQueries, isEmpty); - }); + ], + }; + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(jsonResponse); + final groundingMetadata = + response.candidates.first.groundingMetadata; + + expect(groundingMetadata, isNotNull); + expect(groundingMetadata!.searchEntryPoint, isNull); + expect(groundingMetadata.groundingChunks, isEmpty); + expect(groundingMetadata.groundingSupports, isEmpty); + expect(groundingMetadata.webSearchQueries, isEmpty); + }, + ); test('throws FormatException for invalid item in groundingChunks', () { final json = { 'candidates': [ { 'groundingMetadata': { - 'groundingChunks': ['not_a_map'] - } - } - ] + 'groundingChunks': ['not_a_map'], + }, + }, + ], }; expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(json), - throwsA(isA().having( - (e) => e.message, 'message', contains('GroundingChunk')))); + () => + AgentPlatformSerialization().parseGenerateContentResponse(json), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('GroundingChunk'), + ), + ), + ); }); - test('throws FormatException for invalid item in groundingSupports', - () { - final json = { - 'candidates': [ - { - 'groundingMetadata': { - 'groundingSupports': ['not_a_map'] - } - } - ] - }; - expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(json), - throwsA(isA().having( - (e) => e.message, 'message', contains('GroundingSupport')))); - }); + test( + 'throws FormatException for invalid item in groundingSupports', + () { + final json = { + 'candidates': [ + { + 'groundingMetadata': { + 'groundingSupports': ['not_a_map'], + }, + }, + ], + }; + expect( + () => AgentPlatformSerialization().parseGenerateContentResponse( + json, + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('GroundingSupport'), + ), + ), + ); + }, + ); - test('throws FormatException for invalid searchEntryPoint structure', - () { - final json = { - 'candidates': [ - { - 'groundingMetadata': {'searchEntryPoint': 'not_a_map'} - } - ] - }; - expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(json), - throwsA(isA().having( - (e) => e.message, 'message', contains('SearchEntryPoint')))); - }); + test( + 'throws FormatException for invalid searchEntryPoint structure', + () { + final json = { + 'candidates': [ + { + 'groundingMetadata': {'searchEntryPoint': 'not_a_map'}, + }, + ], + }; + expect( + () => AgentPlatformSerialization().parseGenerateContentResponse( + json, + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('SearchEntryPoint'), + ), + ), + ); + }, + ); test( - 'throws FormatException for invalid segment structure in groundingSupports', - () { - final json = { - 'candidates': [ - { - 'groundingMetadata': { - 'groundingSupports': [ - {'segment': 'not_a_map'} - ] - } - } - ] - }; - expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(json), - throwsA(isA() - .having((e) => e.message, 'message', contains('Segment')))); - }); + 'throws FormatException for invalid segment structure in groundingSupports', + () { + final json = { + 'candidates': [ + { + 'groundingMetadata': { + 'groundingSupports': [ + {'segment': 'not_a_map'}, + ], + }, + }, + ], + }; + expect( + () => AgentPlatformSerialization().parseGenerateContentResponse( + json, + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('Segment'), + ), + ), + ); + }, + ); test( - 'throws FormatException for invalid web structure in groundingChunk', - () { - final json = { - 'candidates': [ - { - 'groundingMetadata': { - 'groundingChunks': [ - {'web': 'not_a_map'} - ] - } - } - ] - }; - expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(json), - throwsA(isA().having( - (e) => e.message, 'message', contains('WebGroundingChunk')))); - }); + 'throws FormatException for invalid web structure in groundingChunk', + () { + final json = { + 'candidates': [ + { + 'groundingMetadata': { + 'groundingChunks': [ + {'web': 'not_a_map'}, + ], + }, + }, + ], + }; + expect( + () => AgentPlatformSerialization().parseGenerateContentResponse( + json, + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('WebGroundingChunk'), + ), + ), + ); + }, + ); test('parses malformedFunctionCall finishReason', () { final jsonResponse = { 'candidates': [ - {'finishReason': 'MALFORMED_FUNCTION_CALL'} - ] + {'finishReason': 'MALFORMED_FUNCTION_CALL'}, + ], }; final response = AgentPlatformSerialization() .parseGenerateContentResponse(jsonResponse); - expect(response.candidates.first.finishReason, - FinishReason.malformedFunctionCall); + expect( + response.candidates.first.finishReason, + FinishReason.malformedFunctionCall, + ); }); test('parses unexpectedToolCall finishReason', () { final jsonResponse = { 'candidates': [ - {'finishReason': 'UNEXPECTED_TOOL_CALL'} - ] + {'finishReason': 'UNEXPECTED_TOOL_CALL'}, + ], }; final response = AgentPlatformSerialization() .parseGenerateContentResponse(jsonResponse); - expect(response.candidates.first.finishReason, - FinishReason.unexpectedToolCall); + expect( + response.candidates.first.finishReason, + FinishReason.unexpectedToolCall, + ); }); test( - 'parses groundingSupports and filters out entries without a segment', - () { - final jsonResponse = { - 'candidates': [ - { - 'content': { - 'parts': [ - {'text': 'Test'} - ] - }, - 'finishReason': 'STOP', - 'groundingMetadata': { - 'groundingSupports': [ - // Valid entry - { - 'segment': { - 'startIndex': 0, - 'endIndex': 4, - 'text': 'Test' + 'parses groundingSupports and filters out entries without a segment', + () { + final jsonResponse = { + 'candidates': [ + { + 'content': { + 'parts': [ + {'text': 'Test'}, + ], + }, + 'finishReason': 'STOP', + 'groundingMetadata': { + 'groundingSupports': [ + // Valid entry + { + 'segment': { + 'startIndex': 0, + 'endIndex': 4, + 'text': 'Test', + }, + 'groundingChunkIndices': [0], }, - 'groundingChunkIndices': [0] - }, - // Invalid entry - missing segment - { - 'groundingChunkIndices': [1] - }, - // Invalid entry - empty object - {} - ] - } - } - ] - }; + // Invalid entry - missing segment + { + 'groundingChunkIndices': [1], + }, + // Invalid entry - empty object + {}, + ], + }, + }, + ], + }; - final response = AgentPlatformSerialization() - .parseGenerateContentResponse(jsonResponse); - final groundingMetadata = response.candidates.first.groundingMetadata; + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(jsonResponse); + final groundingMetadata = + response.candidates.first.groundingMetadata; - expect(groundingMetadata, isNotNull); - // The invalid entries should be filtered out. - expect(groundingMetadata!.groundingSupports, hasLength(1)); + expect(groundingMetadata, isNotNull); + // The invalid entries should be filtered out. + expect(groundingMetadata!.groundingSupports, hasLength(1)); - final validSupport = groundingMetadata.groundingSupports.first; - expect(validSupport.segment.text, 'Test'); - expect(validSupport.groundingChunkIndices, [0]); - }); + final validSupport = groundingMetadata.groundingSupports.first; + expect(validSupport.segment.text, 'Test'); + expect(validSupport.groundingChunkIndices, [0]); + }, + ); }); group('UrlContextMetadata parsing', () { @@ -1296,20 +1541,20 @@ void main() { { 'content': { 'parts': [ - {'text': 'Some text'} - ] + {'text': 'Some text'}, + ], }, 'finishReason': 'STOP', 'urlContextMetadata': { 'urlMetadata': [ { 'retrievedUrl': 'https://example.com', - 'urlRetrievalStatus': 'URL_RETRIEVAL_STATUS_SUCCESS' - } - ] - } - } - ] + 'urlRetrievalStatus': 'URL_RETRIEVAL_STATUS_SUCCESS', + }, + ], + }, + }, + ], }; final response = AgentPlatformSerialization() .parseGenerateContentResponse(jsonResponse); @@ -1323,48 +1568,58 @@ void main() { }); test( - 'parses valid response with full url context metadata and list of url metadata', - () { - final jsonResponse = { - 'candidates': [ - { - 'content': { - 'parts': [ - {'text': 'Some text'} - ] + 'parses valid response with full url context metadata and list of url metadata', + () { + final jsonResponse = { + 'candidates': [ + { + 'content': { + 'parts': [ + {'text': 'Some text'}, + ], + }, + 'finishReason': 'STOP', + 'urlContextMetadata': { + 'urlMetadata': [ + { + 'retrievedUrl': 'https://example.com', + 'urlRetrievalStatus': 'URL_RETRIEVAL_STATUS_SUCCESS', + }, + { + 'retrievedUrl': 'https://foo.com', + 'urlRetrievalStatus': 'URL_RETRIEVAL_STATUS_ERROR', + }, + ], + }, }, - 'finishReason': 'STOP', - 'urlContextMetadata': { - 'urlMetadata': [ - { - 'retrievedUrl': 'https://example.com', - 'urlRetrievalStatus': 'URL_RETRIEVAL_STATUS_SUCCESS' - }, - { - 'retrievedUrl': 'https://foo.com', - 'urlRetrievalStatus': 'URL_RETRIEVAL_STATUS_ERROR' - } - ] - } - } - ] - }; - final response = AgentPlatformSerialization() - .parseGenerateContentResponse(jsonResponse); - final urlContextMetadata = - response.candidates.first.urlContextMetadata; - expect(urlContextMetadata, isNotNull); - expect(urlContextMetadata!.urlMetadata, hasLength(2)); - final firstUrlMetadata = urlContextMetadata.urlMetadata.first; - expect( - firstUrlMetadata.retrievedUrl, Uri.parse('https://example.com')); - expect( - firstUrlMetadata.urlRetrievalStatus, UrlRetrievalStatus.success); - final secondUrlMetadata = urlContextMetadata.urlMetadata[1]; - expect(secondUrlMetadata.retrievedUrl, Uri.parse('https://foo.com')); - expect( - secondUrlMetadata.urlRetrievalStatus, UrlRetrievalStatus.error); - }); + ], + }; + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(jsonResponse); + final urlContextMetadata = + response.candidates.first.urlContextMetadata; + expect(urlContextMetadata, isNotNull); + expect(urlContextMetadata!.urlMetadata, hasLength(2)); + final firstUrlMetadata = urlContextMetadata.urlMetadata.first; + expect( + firstUrlMetadata.retrievedUrl, + Uri.parse('https://example.com'), + ); + expect( + firstUrlMetadata.urlRetrievalStatus, + UrlRetrievalStatus.success, + ); + final secondUrlMetadata = urlContextMetadata.urlMetadata[1]; + expect( + secondUrlMetadata.retrievedUrl, + Uri.parse('https://foo.com'), + ); + expect( + secondUrlMetadata.urlRetrievalStatus, + UrlRetrievalStatus.error, + ); + }, + ); test('parses response with missing retrievedUrl', () { final jsonResponse = { @@ -1372,11 +1627,11 @@ void main() { { 'urlContextMetadata': { 'urlMetadata': [ - {'urlRetrievalStatus': 'URL_RETRIEVAL_STATUS_ERROR'} - ] - } - } - ] + {'urlRetrievalStatus': 'URL_RETRIEVAL_STATUS_ERROR'}, + ], + }, + }, + ], }; final response = AgentPlatformSerialization() .parseGenerateContentResponse(jsonResponse); @@ -1390,9 +1645,9 @@ void main() { final jsonResponse = { 'candidates': [ { - 'urlContextMetadata': {'urlMetadata': []} - } - ] + 'urlContextMetadata': {'urlMetadata': []}, + }, + ], }; final response = AgentPlatformSerialization() .parseGenerateContentResponse(jsonResponse); @@ -1405,8 +1660,8 @@ void main() { test('handles missing urlContextMetadata field', () { final jsonResponse = { 'candidates': [ - {'finishReason': 'STOP'} - ] + {'finishReason': 'STOP'}, + ], }; final response = AgentPlatformSerialization() .parseGenerateContentResponse(jsonResponse); @@ -1417,14 +1672,21 @@ void main() { test('throws for invalid urlContextMetadata structure', () { final jsonResponse = { 'candidates': [ - {'urlContextMetadata': 'not_a_map'} - ] + {'urlContextMetadata': 'not_a_map'}, + ], }; expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(jsonResponse), - throwsA(isA().having((e) => e.message, - 'message', contains('UrlContextMetadata')))); + () => AgentPlatformSerialization().parseGenerateContentResponse( + jsonResponse, + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('UrlContextMetadata'), + ), + ), + ); }); test('throws for invalid urlMetadata item in list', () { @@ -1432,23 +1694,30 @@ void main() { 'candidates': [ { 'urlContextMetadata': { - 'urlMetadata': ['not_a_map'] - } - } - ] + 'urlMetadata': ['not_a_map'], + }, + }, + ], }; expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(jsonResponse), - throwsA(isA().having( - (e) => e.message, 'message', contains('UrlMetadata')))); + () => AgentPlatformSerialization().parseGenerateContentResponse( + jsonResponse, + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('UrlMetadata'), + ), + ), + ); }); }); test('parses JSON with no candidates (empty list)', () { final json = {'candidates': []}; - final response = - AgentPlatformSerialization().parseGenerateContentResponse(json); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(json); expect(response.candidates, isEmpty); expect(response.promptFeedback, isNull); expect(response.usageMetadata, isNull); @@ -1457,8 +1726,8 @@ void main() { test('parses JSON with null candidates (treated as empty)', () { // The code defaults to [] if 'candidates' key is missing final json = {'promptFeedback': null}; - final response = - AgentPlatformSerialization().parseGenerateContentResponse(json); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(json); expect(response.candidates, isEmpty); expect(response.promptFeedback, isNull); }); @@ -1469,15 +1738,15 @@ void main() { { 'content': { 'parts': [ - {'text': 'Minimal'} - ] - } + {'text': 'Minimal'}, + ], + }, // Missing finishReason, safetyRatings, citationMetadata, finishMessage - } - ] + }, + ], }; - final response = - AgentPlatformSerialization().parseGenerateContentResponse(json); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(json); expect(response.candidates, hasLength(1)); expect(response.candidates.first.text, 'Minimal'); expect(response.candidates.first.finishReason, isNull); @@ -1494,20 +1763,18 @@ void main() { 'candidatesTokenCount': 20, 'totalTokenCount': 30, 'promptTokensDetails': [ - {'modality': 'TEXT', 'tokenCount': 10} + {'modality': 'TEXT', 'tokenCount': 10}, ], 'candidatesTokensDetails': [ - { - 'modality': 'TEXT', - } + {'modality': 'TEXT'}, ], 'toolUsePromptTokensDetails': [ - {'modality': 'TEXT', 'tokenCount': 12} + {'modality': 'TEXT', 'tokenCount': 12}, ], - } + }, }; - final response = - AgentPlatformSerialization().parseGenerateContentResponse(json); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(json); expect(response.candidates, hasLength(1)); expect(response.candidates.first.text, 'Hello world'); expect(response.candidates.first.finishReason, FinishReason.stop); @@ -1519,25 +1786,35 @@ void main() { expect(response.usageMetadata!.candidatesTokenCount, 20); expect(response.usageMetadata!.totalTokenCount, 30); expect(response.usageMetadata!.promptTokensDetails, hasLength(1)); - expect(response.usageMetadata!.promptTokensDetails!.first.modality, - ContentModality.text); expect( - response.usageMetadata!.promptTokensDetails!.first.tokenCount, 10); + response.usageMetadata!.promptTokensDetails!.first.modality, + ContentModality.text, + ); + expect( + response.usageMetadata!.promptTokensDetails!.first.tokenCount, + 10, + ); expect(response.usageMetadata!.candidatesTokensDetails, hasLength(1)); - expect(response.usageMetadata!.candidatesTokensDetails!.first.modality, - ContentModality.text); expect( - response.usageMetadata!.candidatesTokensDetails!.first.tokenCount, - 0); + response.usageMetadata!.candidatesTokensDetails!.first.modality, + ContentModality.text, + ); + expect( + response.usageMetadata!.candidatesTokensDetails!.first.tokenCount, + 0, + ); expect( - response.usageMetadata!.toolUsePromptTokensDetails, hasLength(1)); + response.usageMetadata!.toolUsePromptTokensDetails, + hasLength(1), + ); expect( - response.usageMetadata!.toolUsePromptTokensDetails!.first.modality, - ContentModality.text); + response.usageMetadata!.toolUsePromptTokensDetails!.first.modality, + ContentModality.text, + ); expect( - response - .usageMetadata!.toolUsePromptTokensDetails!.first.tokenCount, - 12); + response.usageMetadata!.toolUsePromptTokensDetails!.first.tokenCount, + 12, + ); }); test('parses citationMetadata with "citationSources"', () { @@ -1546,8 +1823,8 @@ void main() { { 'content': { 'parts': [ - {'text': 'Cited text'} - ] + {'text': 'Cited text'}, + ], }, 'citationMetadata': { 'citationSources': [ @@ -1555,20 +1832,22 @@ void main() { 'startIndex': 0, 'endIndex': 5, 'uri': 'http://example.com/source1', - 'license': 'CC-BY' - } - ] - } - } - ] + 'license': 'CC-BY', + }, + ], + }, + }, + ], }; - final response = - AgentPlatformSerialization().parseGenerateContentResponse(json); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(json); final candidate = response.candidates.first; expect(candidate.citationMetadata, isNotNull); expect(candidate.citationMetadata!.citations, hasLength(1)); - expect(candidate.citationMetadata!.citations.first.uri.toString(), - 'http://example.com/source1'); + expect( + candidate.citationMetadata!.citations.first.uri.toString(), + 'http://example.com/source1', + ); }); test('parses citationMetadata with "citations" (Vertex SDK format)', () { final json = { @@ -1576,8 +1855,8 @@ void main() { { 'content': { 'parts': [ - {'text': 'Cited text'} - ] + {'text': 'Cited text'}, + ], }, 'citationMetadata': { 'citations': [ @@ -1586,121 +1865,173 @@ void main() { 'startIndex': 0, 'endIndex': 5, 'uri': 'http://example.com/source2', - 'license': 'MIT' - } - ] - } - } - ] + 'license': 'MIT', + }, + ], + }, + }, + ], }; - final response = - AgentPlatformSerialization().parseGenerateContentResponse(json); + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(json); final candidate = response.candidates.first; expect(candidate.citationMetadata, isNotNull); expect(candidate.citationMetadata!.citations, hasLength(1)); - expect(candidate.citationMetadata!.citations.first.uri.toString(), - 'http://example.com/source2'); + expect( + candidate.citationMetadata!.citations.first.uri.toString(), + 'http://example.com/source2', + ); expect(candidate.citationMetadata!.citations.first.license, 'MIT'); }); test('throws FirebaseAIException if JSON contains error field', () { final json = { - 'error': {'code': 500, 'message': 'Internal server error'} + 'error': {'code': 500, 'message': 'Internal server error'}, }; expect( - () => - AgentPlatformSerialization().parseGenerateContentResponse(json), - throwsA(isA())); + () => AgentPlatformSerialization().parseGenerateContentResponse(json), + throwsA(isA()), + ); }); - test('handles missing content in candidate gracefully (empty content)', - () { - final json = { - 'candidates': [ - { - // No 'content' field - 'finishReason': 'STOP', - } - ] - }; - final response = - AgentPlatformSerialization().parseGenerateContentResponse(json); - expect(response.candidates, hasLength(1)); - expect(response.candidates.first.content.parts, isEmpty); - expect(response.candidates.first.text, isNull); - }); - test('throws FormatException for invalid candidate structure (not a Map)', - () { - final jsonResponse = { - 'candidates': ['not_a_map_candidate'] - }; - expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(jsonResponse), - throwsA(isA() - .having((e) => e.message, 'message', contains('Candidate')))); - }); + test( + 'handles missing content in candidate gracefully (empty content)', + () { + final json = { + 'candidates': [ + { + // No 'content' field + 'finishReason': 'STOP', + }, + ], + }; + final response = AgentPlatformSerialization() + .parseGenerateContentResponse(json); + expect(response.candidates, hasLength(1)); + expect(response.candidates.first.content.parts, isEmpty); + expect(response.candidates.first.text, isNull); + }, + ); + test( + 'throws FormatException for invalid candidate structure (not a Map)', + () { + final jsonResponse = { + 'candidates': ['not_a_map_candidate'], + }; + expect( + () => AgentPlatformSerialization().parseGenerateContentResponse( + jsonResponse, + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('Candidate'), + ), + ), + ); + }, + ); test('throws FormatException for invalid safety rating structure', () { final jsonResponse = { 'candidates': [ { 'content': {'parts': []}, - 'safetyRatings': ['not_a_map_rating'] - } - ] - }; - expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(jsonResponse), - throwsA(isA().having( - (e) => e.message, 'message', contains('SafetyRating')))); - }); - test('throws FormatException for invalid citation metadata structure', - () { - final jsonResponse = { - 'candidates': [ - { - 'content': {'parts': []}, - 'citationMetadata': 'not_a_map_citation' - } - ] + 'safetyRatings': ['not_a_map_rating'], + }, + ], }; expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(jsonResponse), - throwsA(isA().having( - (e) => e.message, 'message', contains('CitationMetadata')))); + () => AgentPlatformSerialization().parseGenerateContentResponse( + jsonResponse, + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('SafetyRating'), + ), + ), + ); }); + test( + 'throws FormatException for invalid citation metadata structure', + () { + final jsonResponse = { + 'candidates': [ + { + 'content': {'parts': []}, + 'citationMetadata': 'not_a_map_citation', + }, + ], + }; + expect( + () => AgentPlatformSerialization().parseGenerateContentResponse( + jsonResponse, + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('CitationMetadata'), + ), + ), + ); + }, + ); test('throws FormatException for invalid prompt feedback structure', () { final jsonResponse = {'promptFeedback': 'not_a_map_feedback'}; expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(jsonResponse), - throwsA(isA().having( - (e) => e.message, 'message', contains('PromptFeedback')))); + () => AgentPlatformSerialization().parseGenerateContentResponse( + jsonResponse, + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('PromptFeedback'), + ), + ), + ); }); test('throws FormatException for invalid usage metadata structure', () { final jsonResponse = {'usageMetadata': 'not_a_map_usage'}; expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(jsonResponse), - throwsA(isA().having( - (e) => e.message, 'message', contains('UsageMetadata')))); - }); - test('throws FormatException for invalid modality token count structure', - () { - final jsonResponse = { - 'usageMetadata': { - 'promptTokensDetails': ['not_a_map_modality'] - } - }; - expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(jsonResponse), - throwsA(isA().having( - (e) => e.message, 'message', contains('ModalityTokenCount')))); + () => AgentPlatformSerialization().parseGenerateContentResponse( + jsonResponse, + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('UsageMetadata'), + ), + ), + ); }); + test( + 'throws FormatException for invalid modality token count structure', + () { + final jsonResponse = { + 'usageMetadata': { + 'promptTokensDetails': ['not_a_map_modality'], + }, + }; + expect( + () => AgentPlatformSerialization().parseGenerateContentResponse( + jsonResponse, + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('ModalityTokenCount'), + ), + ), + ); + }, + ); }); }); } diff --git a/packages/firebase_ai/firebase_ai/test/base_model_test.dart b/packages/firebase_ai/firebase_ai/test/base_model_test.dart index f4aba609e2dd..26c89b8f9e18 100644 --- a/packages/firebase_ai/firebase_ai/test/base_model_test.dart +++ b/packages/firebase_ai/firebase_ai/test/base_model_test.dart @@ -84,7 +84,9 @@ class MockUser extends Mock implements User { class MockApiClient extends Mock implements ApiClient { @override Future> makeRequest( - Uri uri, Map params) async { + Uri uri, + Map params, + ) async { // Simulate a successful API response return {'mockResponse': 'success'}; } @@ -106,10 +108,15 @@ void main() { test('firebaseTokens includes App Check token if available', () async { final mockAppCheck = MockFirebaseAppCheck(); - when(mockAppCheck.getToken()) - .thenAnswer((_) async => 'test-app-check-token'); - final tokenFunction = - BaseModel.firebaseTokens(mockAppCheck, null, null, false); + when( + mockAppCheck.getToken(), + ).thenAnswer((_) async => 'test-app-check-token'); + final tokenFunction = BaseModel.firebaseTokens( + mockAppCheck, + null, + null, + false, + ); final headers = await tokenFunction(); expect(headers['X-Firebase-AppCheck'], 'test-app-check-token'); expect(headers['x-goog-api-client'], contains('gl-dart')); @@ -122,8 +129,12 @@ void main() { final mockUser = MockUser(); when(mockUser.getIdToken()).thenAnswer((_) async => 'test-id-token'); when(mockAuth.currentUser).thenReturn(mockUser); - final tokenFunction = - BaseModel.firebaseTokens(null, mockAuth, null, false); + final tokenFunction = BaseModel.firebaseTokens( + null, + mockAuth, + null, + false, + ); final headers = await tokenFunction(); expect(headers['Authorization'], 'Firebase test-id-token'); expect(headers['x-goog-api-client'], contains('gl-dart')); @@ -132,109 +143,146 @@ void main() { }); test( - 'firebaseTokens includes App ID if automatic data collection is enabled', - () async { - final mockApp = MockFirebaseApp(); - - final tokenFunction = - BaseModel.firebaseTokens(null, null, mockApp, false); - final headers = await tokenFunction(); - expect(headers['X-Firebase-AppId'], 'test-app-id'); - expect(headers['x-goog-api-client'], contains('gl-dart')); - expect(headers['x-goog-api-client'], contains('fire')); - expect(headers.length, 2); - }); - - test('firebaseTokens discovers App Check token dynamically at request time', - () async { - final mockApp = MockFirebaseApp(); - final mockAppCheck = MockFirebaseAppCheck(); - when(mockAppCheck.getToken()) - .thenAnswer((_) async => 'dynamic-app-check-token'); - mockApp.mockAppCheck = mockAppCheck; - - final tokenFunction = - BaseModel.firebaseTokens(null, null, mockApp, false); - final headers = await tokenFunction(); - - expect(headers['X-Firebase-AppCheck'], 'dynamic-app-check-token'); - expect(headers['X-Firebase-AppId'], 'test-app-id'); - expect(headers.length, 3); - }); - - test('firebaseTokens discovers Auth ID token dynamically at request time', - () async { - final mockApp = MockFirebaseApp(); - final mockAuth = MockFirebaseAuth(); - final mockUser = MockUser(); - when(mockUser.getIdToken()).thenAnswer((_) async => 'dynamic-id-token'); - when(mockAuth.currentUser).thenReturn(mockUser); - mockApp.mockAuth = mockAuth; - - final tokenFunction = - BaseModel.firebaseTokens(null, null, mockApp, false); - final headers = await tokenFunction(); - - expect(headers['Authorization'], 'Firebase dynamic-id-token'); - expect(headers['X-Firebase-AppId'], 'test-app-id'); - expect(headers.length, 3); - }); - - test('firebaseTokens discovers both tokens dynamically at request time', - () async { - final mockApp = MockFirebaseApp(); - final mockAppCheck = MockFirebaseAppCheck(); - final mockAuth = MockFirebaseAuth(); - final mockUser = MockUser(); - - when(mockAppCheck.getToken()) - .thenAnswer((_) async => 'dynamic-app-check-token'); - when(mockUser.getIdToken()).thenAnswer((_) async => 'dynamic-id-token'); - when(mockAuth.currentUser).thenReturn(mockUser); - - mockApp.mockAppCheck = mockAppCheck; - mockApp.mockAuth = mockAuth; - - final tokenFunction = - BaseModel.firebaseTokens(null, null, mockApp, false); - final headers = await tokenFunction(); - - expect(headers['X-Firebase-AppCheck'], 'dynamic-app-check-token'); - expect(headers['Authorization'], 'Firebase dynamic-id-token'); - expect(headers['X-Firebase-AppId'], 'test-app-id'); - expect(headers.length, 4); - }); + 'firebaseTokens includes App ID if automatic data collection is enabled', + () async { + final mockApp = MockFirebaseApp(); + + final tokenFunction = BaseModel.firebaseTokens( + null, + null, + mockApp, + false, + ); + final headers = await tokenFunction(); + expect(headers['X-Firebase-AppId'], 'test-app-id'); + expect(headers['x-goog-api-client'], contains('gl-dart')); + expect(headers['x-goog-api-client'], contains('fire')); + expect(headers.length, 2); + }, + ); test( - 'firebaseTokens discovers App Check token dynamically with limited use', - () async { - final mockApp = MockFirebaseApp(); - final mockAppCheck = MockFirebaseAppCheck(); + 'firebaseTokens discovers App Check token dynamically at request time', + () async { + final mockApp = MockFirebaseApp(); + final mockAppCheck = MockFirebaseAppCheck(); + when( + mockAppCheck.getToken(), + ).thenAnswer((_) async => 'dynamic-app-check-token'); + mockApp.mockAppCheck = mockAppCheck; + + final tokenFunction = BaseModel.firebaseTokens( + null, + null, + mockApp, + false, + ); + final headers = await tokenFunction(); + + expect(headers['X-Firebase-AppCheck'], 'dynamic-app-check-token'); + expect(headers['X-Firebase-AppId'], 'test-app-id'); + expect(headers.length, 3); + }, + ); - when(mockAppCheck.getLimitedUseToken()) - .thenAnswer((_) async => 'dynamic-limited-use-token'); - mockApp.mockAppCheck = mockAppCheck; + test( + 'firebaseTokens discovers Auth ID token dynamically at request time', + () async { + final mockApp = MockFirebaseApp(); + final mockAuth = MockFirebaseAuth(); + final mockUser = MockUser(); + when(mockUser.getIdToken()).thenAnswer((_) async => 'dynamic-id-token'); + when(mockAuth.currentUser).thenReturn(mockUser); + mockApp.mockAuth = mockAuth; + + final tokenFunction = BaseModel.firebaseTokens( + null, + null, + mockApp, + false, + ); + final headers = await tokenFunction(); + + expect(headers['Authorization'], 'Firebase dynamic-id-token'); + expect(headers['X-Firebase-AppId'], 'test-app-id'); + expect(headers.length, 3); + }, + ); - final tokenFunction = BaseModel.firebaseTokens(null, null, mockApp, true); - final headers = await tokenFunction(); + test( + 'firebaseTokens discovers both tokens dynamically at request time', + () async { + final mockApp = MockFirebaseApp(); + final mockAppCheck = MockFirebaseAppCheck(); + final mockAuth = MockFirebaseAuth(); + final mockUser = MockUser(); + + when( + mockAppCheck.getToken(), + ).thenAnswer((_) async => 'dynamic-app-check-token'); + when(mockUser.getIdToken()).thenAnswer((_) async => 'dynamic-id-token'); + when(mockAuth.currentUser).thenReturn(mockUser); + + mockApp.mockAppCheck = mockAppCheck; + mockApp.mockAuth = mockAuth; + + final tokenFunction = BaseModel.firebaseTokens( + null, + null, + mockApp, + false, + ); + final headers = await tokenFunction(); + + expect(headers['X-Firebase-AppCheck'], 'dynamic-app-check-token'); + expect(headers['Authorization'], 'Firebase dynamic-id-token'); + expect(headers['X-Firebase-AppId'], 'test-app-id'); + expect(headers.length, 4); + }, + ); - expect(headers['X-Firebase-AppCheck'], 'dynamic-limited-use-token'); - expect(headers['X-Firebase-AppId'], 'test-app-id'); - expect(headers.length, 3); - }); + test( + 'firebaseTokens discovers App Check token dynamically with limited use', + () async { + final mockApp = MockFirebaseApp(); + final mockAppCheck = MockFirebaseAppCheck(); + + when( + mockAppCheck.getLimitedUseToken(), + ).thenAnswer((_) async => 'dynamic-limited-use-token'); + mockApp.mockAppCheck = mockAppCheck; + + final tokenFunction = BaseModel.firebaseTokens( + null, + null, + mockApp, + true, + ); + final headers = await tokenFunction(); + + expect(headers['X-Firebase-AppCheck'], 'dynamic-limited-use-token'); + expect(headers['X-Firebase-AppId'], 'test-app-id'); + expect(headers.length, 3); + }, + ); test('firebaseTokens includes all tokens if available', () async { final mockAppCheck = MockFirebaseAppCheck(); - when(mockAppCheck.getToken()) - .thenAnswer((_) async => 'test-app-check-token'); + when( + mockAppCheck.getToken(), + ).thenAnswer((_) async => 'test-app-check-token'); final mockAuth = MockFirebaseAuth(); final mockUser = MockUser(); when(mockUser.getIdToken()).thenAnswer((_) async => 'test-id-token'); when(mockAuth.currentUser).thenReturn(mockUser); final mockApp = MockFirebaseApp(); - final tokenFunction = - BaseModel.firebaseTokens(mockAppCheck, mockAuth, mockApp, false); + final tokenFunction = BaseModel.firebaseTokens( + mockAppCheck, + mockAuth, + mockApp, + false, + ); final headers = await tokenFunction(); expect(headers['X-Firebase-AppCheck'], 'test-app-check-token'); expect(headers['Authorization'], 'Firebase test-id-token'); @@ -244,72 +292,91 @@ void main() { expect(headers.length, 4); }); - test('firebaseTokens includes limited use App Check token if specified', - () async { - final mockAppCheck = MockFirebaseAppCheck(); - when(mockAppCheck.getLimitedUseToken()) - .thenAnswer((_) async => 'test-limited-use-app-check-token'); - final tokenFunction = - BaseModel.firebaseTokens(mockAppCheck, null, null, true); - final headers = await tokenFunction(); - expect( - headers['X-Firebase-AppCheck'], 'test-limited-use-app-check-token'); - expect(headers['x-goog-api-client'], contains('gl-dart')); - expect(headers['x-goog-api-client'], contains('fire')); - expect(headers.length, 2); - }); - - test('firebaseTokens includes Android platform headers when available', - () async { - debugDefaultTargetPlatformOverride = TargetPlatform.android; - addTearDown(() { - debugDefaultTargetPlatformOverride = null; - }); - - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(platformHeaderChannel, - (MethodCall methodCall) async { - return { - 'X-Android-Package': 'com.example.test', - 'X-Android-Cert': 'AABBCCDD', - }; - }); - addTearDown(() { - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(platformHeaderChannel, null); - }); + test( + 'firebaseTokens includes limited use App Check token if specified', + () async { + final mockAppCheck = MockFirebaseAppCheck(); + when( + mockAppCheck.getLimitedUseToken(), + ).thenAnswer((_) async => 'test-limited-use-app-check-token'); + final tokenFunction = BaseModel.firebaseTokens( + mockAppCheck, + null, + null, + true, + ); + final headers = await tokenFunction(); + expect( + headers['X-Firebase-AppCheck'], + 'test-limited-use-app-check-token', + ); + expect(headers['x-goog-api-client'], contains('gl-dart')); + expect(headers['x-goog-api-client'], contains('fire')); + expect(headers.length, 2); + }, + ); - final tokenFunction = BaseModel.firebaseTokens(null, null, null, false); - final headers = await tokenFunction(); - expect(headers['X-Android-Package'], 'com.example.test'); - expect(headers['X-Android-Cert'], 'AABBCCDD'); - expect(headers['x-goog-api-client'], contains('gl-dart')); - expect(headers.length, 3); - }); + test( + 'firebaseTokens includes Android platform headers when available', + () async { + debugDefaultTargetPlatformOverride = TargetPlatform.android; + addTearDown(() { + debugDefaultTargetPlatformOverride = null; + }); - test('firebaseTokens includes iOS bundle identifier when available', - () async { - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(platformHeaderChannel, - (MethodCall methodCall) async { - return { - 'x-ios-bundle-identifier': 'com.example.iosapp', - }; - }); - addTearDown(() { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(platformHeaderChannel, null); - }); + .setMockMethodCallHandler(platformHeaderChannel, ( + MethodCall methodCall, + ) async { + return { + 'X-Android-Package': 'com.example.test', + 'X-Android-Cert': 'AABBCCDD', + }; + }); + addTearDown(() { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(platformHeaderChannel, null); + }); + + final tokenFunction = BaseModel.firebaseTokens(null, null, null, false); + final headers = await tokenFunction(); + expect(headers['X-Android-Package'], 'com.example.test'); + expect(headers['X-Android-Cert'], 'AABBCCDD'); + expect(headers['x-goog-api-client'], contains('gl-dart')); + expect(headers.length, 3); + }, + ); - final mockApp = MockFirebaseApp(); - - final tokenFunction = - BaseModel.firebaseTokens(null, null, mockApp, false); - final headers = await tokenFunction(); - expect(headers['x-ios-bundle-identifier'], 'com.example.iosapp'); - expect(headers['X-Firebase-AppId'], 'test-app-id'); - expect(headers['x-goog-api-client'], contains('gl-dart')); - expect(headers.length, 3); - }); + test( + 'firebaseTokens includes iOS bundle identifier when available', + () async { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(platformHeaderChannel, ( + MethodCall methodCall, + ) async { + return { + 'x-ios-bundle-identifier': 'com.example.iosapp', + }; + }); + addTearDown(() { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(platformHeaderChannel, null); + }); + + final mockApp = MockFirebaseApp(); + + final tokenFunction = BaseModel.firebaseTokens( + null, + null, + mockApp, + false, + ); + final headers = await tokenFunction(); + expect(headers['x-ios-bundle-identifier'], 'com.example.iosapp'); + expect(headers['X-Firebase-AppId'], 'test-app-id'); + expect(headers['x-goog-api-client'], contains('gl-dart')); + expect(headers.length, 3); + }, + ); }); } diff --git a/packages/firebase_ai/firebase_ai/test/chat_test.dart b/packages/firebase_ai/firebase_ai/test/chat_test.dart index 757568e1989d..f1f5f2df35ea 100644 --- a/packages/firebase_ai/firebase_ai/test/chat_test.dart +++ b/packages/firebase_ai/firebase_ai/test/chat_test.dart @@ -38,20 +38,23 @@ void main() { ]) { final client = ClientController(); final model = createModelWithClient( - app: app, - useAgentPlatform: true, - model: modelName, - client: client.client, - location: 'us-central1'); + app: app, + useAgentPlatform: true, + model: modelName, + client: client.client, + location: 'us-central1', + ); return (client, model); } test('includes chat history in prompt', () async { final (client, model) = createModel('models/$defaultModelName'); - final chat = model.startChat(history: [ - Content.text('Hi!'), - Content.model([const TextPart('Hello, how can I help you today?')]), - ]); + final chat = model.startChat( + history: [ + Content.text('Hi!'), + Content.model([const TextPart('Hello, how can I help you today?')]), + ], + ); const prompt = 'Some prompt'; final response = await client.checkRequest( () => chat.sendMessage(Content.text(prompt)), @@ -69,10 +72,15 @@ void main() { test('forwards safety settings', () async { final (client, model) = createModel('models/$defaultModelName'); - final chat = model.startChat(safetySettings: [ - SafetySetting(HarmCategory.dangerousContent, HarmBlockThreshold.high, - HarmBlockMethod.severity), - ]); + final chat = model.startChat( + safetySettings: [ + SafetySetting( + HarmCategory.dangerousContent, + HarmBlockThreshold.high, + HarmBlockMethod.severity, + ), + ], + ); const prompt = 'Some prompt'; await client.checkRequest( () => chat.sendMessage(Content.text(prompt)), @@ -81,7 +89,7 @@ void main() { { 'category': 'HARM_CATEGORY_DANGEROUS_CONTENT', 'threshold': 'BLOCK_ONLY_HIGH', - 'method': 'SEVERITY' + 'method': 'SEVERITY', }, ]); }, @@ -91,10 +99,16 @@ void main() { test('forwards safety settings and config when streaming', () async { final (client, model) = createModel('models/$defaultModelName'); - final chat = model.startChat(safetySettings: [ - SafetySetting(HarmCategory.dangerousContent, HarmBlockThreshold.high, - HarmBlockMethod.probability), - ], generationConfig: GenerationConfig(stopSequences: ['a'])); + final chat = model.startChat( + safetySettings: [ + SafetySetting( + HarmCategory.dangerousContent, + HarmBlockThreshold.high, + HarmBlockMethod.probability, + ), + ], + generationConfig: GenerationConfig(stopSequences: ['a']), + ); const prompt = 'Some prompt'; final responses = await client.checkStreamRequest( () async => chat.sendMessageStream(Content.text(prompt)), diff --git a/packages/firebase_ai/firebase_ai/test/client_test.dart b/packages/firebase_ai/firebase_ai/test/client_test.dart index 30c80686510c..da9779fe2c99 100644 --- a/packages/firebase_ai/firebase_ai/test/client_test.dart +++ b/packages/firebase_ai/firebase_ai/test/client_test.dart @@ -25,51 +25,61 @@ void main() { const responseJson = {'ok': true}; MockClient jsonClient() => MockClient((request) async { - return http.Response( - jsonEncode(responseJson), - 200, - headers: {'content-type': 'application/json'}, - ); - }); + return http.Response( + jsonEncode(responseJson), + 200, + headers: {'content-type': 'application/json'}, + ); + }); MockClient sseClient() => MockClient((request) async { - return http.Response( - 'data: ${jsonEncode(responseJson)}\n', - 200, - headers: {'content-type': 'text/event-stream'}, - ); - }); + return http.Response( + 'data: ${jsonEncode(responseJson)}\n', + 200, + headers: {'content-type': 'text/event-stream'}, + ); + }); group('HttpApiClient', () { - test('reuses a single Client for unary requests when none is injected', - () async { - var created = 0; + test( + 'reuses a single Client for unary requests when none is injected', + () async { + var created = 0; - await http.runWithClient(() async { - final client = HttpApiClient(apiKey: 'test-key'); - await client.makeRequest(uri, requestBody); - await client.makeRequest(uri, requestBody); - expect(created, 1); - }, () { - created++; - return jsonClient(); - }); - }); + await http.runWithClient( + () async { + final client = HttpApiClient(apiKey: 'test-key'); + await client.makeRequest(uri, requestBody); + await client.makeRequest(uri, requestBody); + expect(created, 1); + }, + () { + created++; + return jsonClient(); + }, + ); + }, + ); - test('reuses a single Client for streaming requests when none is injected', - () async { - var created = 0; + test( + 'reuses a single Client for streaming requests when none is injected', + () async { + var created = 0; - await http.runWithClient(() async { - final client = HttpApiClient(apiKey: 'test-key'); - await client.streamRequest(uri, requestBody).drain(); - await client.streamRequest(uri, requestBody).drain(); - expect(created, 1); - }, () { - created++; - return sseClient(); - }); - }); + await http.runWithClient( + () async { + final client = HttpApiClient(apiKey: 'test-key'); + await client.streamRequest(uri, requestBody).drain(); + await client.streamRequest(uri, requestBody).drain(); + expect(created, 1); + }, + () { + created++; + return sseClient(); + }, + ); + }, + ); test('uses an injected Client for unary and streaming requests', () async { final requests = []; diff --git a/packages/firebase_ai/firebase_ai/test/content_test.dart b/packages/firebase_ai/firebase_ai/test/content_test.dart index 281c420d1acf..93e0bb9f7bc0 100644 --- a/packages/firebase_ai/firebase_ai/test/content_test.dart +++ b/packages/firebase_ai/firebase_ai/test/content_test.dart @@ -25,8 +25,10 @@ import 'package:flutter_test/flutter_test.dart'; void main() { group('Content tests', () { test('constructor', () { - final content = Content('user', - [const TextPart('Test'), InlineDataPart('image/png', Uint8List(0))]); + final content = Content('user', [ + const TextPart('Test'), + InlineDataPart('image/png', Uint8List(0)), + ]); expect(content.role, 'user'); expect(content.parts[0], isA()); expect((content.parts[0] as TextPart).text, 'Test'); @@ -42,8 +44,9 @@ void main() { }); test('data()', () { - final content = - Content('user', [InlineDataPart('image/png', Uint8List(0))]); + final content = Content('user', [ + InlineDataPart('image/png', Uint8List(0)), + ]); expect(content.parts[0], isA()); }); @@ -58,35 +61,36 @@ void main() { 'role': 'user', 'parts': [ { - 'inlineData': { - 'mimeType': 'image/png', - 'data': '', - }, - 'mediaResolution': { - 'level': 'MEDIA_RESOLUTION_HIGH', - }, - } + 'inlineData': {'mimeType': 'image/png', 'data': ''}, + 'mediaResolution': {'level': 'MEDIA_RESOLUTION_HIGH'}, + }, ], }); }); test('multi()', () { - final content = Content('user', - [const TextPart('Test'), InlineDataPart('image/png', Uint8List(0))]); + final content = Content('user', [ + const TextPart('Test'), + InlineDataPart('image/png', Uint8List(0)), + ]); expect(content.parts.length, 2); expect(content.parts[0], isA()); expect(content.parts[1], isA()); }); test('toJson', () { - final content = Content('user', - [const TextPart('Test'), InlineDataPart('image/png', Uint8List(0))]); + final content = Content('user', [ + const TextPart('Test'), + InlineDataPart('image/png', Uint8List(0)), + ]); final json = content.toJson(); expect(json['role'], 'user'); expect((json['parts']! as List).length, 2); expect((json['parts']! as List)[0]['text'], 'Test'); expect( - (json['parts']! as List)[1]['inlineData']['mimeType'], 'image/png'); + (json['parts']! as List)[1]['inlineData']['mimeType'], + 'image/png', + ); expect((json['parts']! as List)[1]['inlineData']['data'].length, 0); }); @@ -95,7 +99,7 @@ void main() { 'role': 'user', 'parts': [ {'text': 'Hello'}, - ] + ], }; final content = parseContent(json); expect(content.role, 'user'); @@ -107,8 +111,11 @@ void main() { group('Part tests', () { test('TextPart with isThought and thoughtSignature toJson', () { - const part = - TextPart.forTest('Test', isThought: true, thoughtSignature: 'sig'); + const part = TextPart.forTest( + 'Test', + isThought: true, + thoughtSignature: 'sig', + ); final json = part.toJson() as Map; expect(json['text'], 'Test'); expect(json['thought'], true); @@ -116,8 +123,12 @@ void main() { }); test('DataPart with isThought and thoughtSignature toJson', () { - final part = InlineDataPart.forTest('image/png', Uint8List(0), - isThought: true, thoughtSignature: 'sig'); + final part = InlineDataPart.forTest( + 'image/png', + Uint8List(0), + isThought: true, + thoughtSignature: 'sig', + ); final json = part.toJson() as Map; final inlineData = json['inlineData'] as Map; expect(inlineData['mimeType'], 'image/png'); @@ -128,8 +139,11 @@ void main() { }); test('DataPart with false willContinue toJson', () { - final part = - InlineDataPart('image/png', Uint8List(0), willContinue: false); + final part = InlineDataPart( + 'image/png', + Uint8List(0), + willContinue: false, + ); final json = part.toJson() as Map; final inlineData = json['inlineData'] as Map; expect(inlineData['mimeType'], 'image/png'); @@ -139,8 +153,11 @@ void main() { }); test('DataPart with true willContinue toJson', () { - final part = - InlineDataPart('image/png', Uint8List(0), willContinue: true); + final part = InlineDataPart( + 'image/png', + Uint8List(0), + willContinue: true, + ); final json = part.toJson() as Map; final inlineData = json['inlineData'] as Map; expect(inlineData['mimeType'], 'image/png'); @@ -157,27 +174,23 @@ void main() { ); expect(part.toJson(), { - 'inlineData': { - 'mimeType': 'image/png', - 'data': '', - }, - 'mediaResolution': { - 'level': 'MEDIA_RESOLUTION_ULTRA_HIGH', - }, + 'inlineData': {'mimeType': 'image/png', 'data': ''}, + 'mediaResolution': {'level': 'MEDIA_RESOLUTION_ULTRA_HIGH'}, }); }); test('FunctionCall with isThought and thoughtSignature toJson', () { const part = FunctionCall.forTest( - 'myFunction', - { - 'arguments': [ - {'text': 'Test'} - ], - }, - id: 'myFunctionId', - isThought: true, - thoughtSignature: 'sig'); + 'myFunction', + { + 'arguments': [ + {'text': 'Test'}, + ], + }, + id: 'myFunctionId', + isThought: true, + thoughtSignature: 'sig', + ); final json = part.toJson() as Map; final functionCall = json['functionCall'] as Map; expect(functionCall['name'], 'myFunction'); @@ -198,8 +211,8 @@ void main() { { 'inlineData': { 'mimeType': 'application/octet-stream', - 'data': Uint8List(0) - } + 'data': Uint8List(0), + }, }, id: 'myFunctionId', isThought: true, @@ -216,8 +229,11 @@ void main() { }); test('FileData with isThought and thoughtSignature toJson', () { - const part = FileData.forTest('image/png', 'gs://bucket-name/path', - isThought: true); + const part = FileData.forTest( + 'image/png', + 'gs://bucket-name/path', + isThought: true, + ); final json = part.toJson() as Map; final fileData = json['file_data'] as Map; expect(fileData['mime_type'], 'image/png'); @@ -237,9 +253,7 @@ void main() { 'mime_type': 'image/png', 'file_uri': 'gs://bucket-name/path', }, - 'mediaResolution': { - 'level': 'MEDIA_RESOLUTION_HIGH', - }, + 'mediaResolution': {'level': 'MEDIA_RESOLUTION_HIGH'}, }); }); }); @@ -258,7 +272,7 @@ void main() { 'name': 'myFunction', 'args': {'arg1': 1, 'arg2': 'value'}, 'id': '123', - } + }, }; final result = parsePart(json); expect(result, isA()); @@ -273,7 +287,7 @@ void main() { 'file_data': { 'file_uri': 'file:///path/to/file.txt', 'mime_type': 'text/plain', - } + }, }; final result = parsePart(json); expect(result, isA()); @@ -287,8 +301,8 @@ void main() { 'inlineData': { 'mimeType': 'image/png', 'data': base64Encode([1, 2, 3]), - 'willContinue': true - } + 'willContinue': true, + }, }; final result = parsePart(json); expect(result, isA()); @@ -303,8 +317,8 @@ void main() { 'inlineData': { 'mimeType': 'image/png', 'data': base64Encode([1, 2, 3]), - 'willContinue': false - } + 'willContinue': false, + }, }; final result = parsePart(json); expect(result, isA()); @@ -318,8 +332,8 @@ void main() { final json = { 'inlineData': { 'mimeType': 'image/png', - 'data': base64Encode([1, 2, 3]) - } + 'data': base64Encode([1, 2, 3]), + }, }; final result = parsePart(json); expect(result, isA()); @@ -331,7 +345,7 @@ void main() { test('returns UnknownPart for functionResponse', () { final json = { - 'functionResponse': {'name': 'test', 'response': {}} + 'functionResponse': {'name': 'test', 'response': {}}, }; final result = parsePart(json); expect(result, isA()); diff --git a/packages/firebase_ai/firebase_ai/test/developer_api_test.dart b/packages/firebase_ai/firebase_ai/test/developer_api_test.dart index 85116e454646..bbd203ee1b19 100644 --- a/packages/firebase_ai/firebase_ai/test/developer_api_test.dart +++ b/packages/firebase_ai/firebase_ai/test/developer_api_test.dart @@ -30,11 +30,11 @@ void main() { 'content': { 'role': 'model', 'parts': [ - {'text': 'Some generated text.'} - ] + {'text': 'Some generated text.'}, + ], }, 'finishReason': 'STOP', - } + }, ], 'usageMetadata': { 'promptTokenCount': 10, @@ -42,18 +42,19 @@ void main() { 'totalTokenCount': 15, 'thoughtsTokenCount': 3, 'promptTokensDetails': [ - {'modality': 'TEXT', 'tokenCount': 10} + {'modality': 'TEXT', 'tokenCount': 10}, ], 'candidatesTokensDetails': [ - {'modality': 'TEXT', 'tokenCount': 25} + {'modality': 'TEXT', 'tokenCount': 25}, ], 'toolUsePromptTokensDetails': [ - {'modality': 'TEXT', 'tokenCount': 12} + {'modality': 'TEXT', 'tokenCount': 12}, ], - } + }, }; - final response = - DeveloperSerialization().parseGenerateContentResponse(jsonResponse); + final response = DeveloperSerialization().parseGenerateContentResponse( + jsonResponse, + ); expect(response.usageMetadata, isNotNull); expect(response.usageMetadata!.promptTokenCount, 10); expect(response.usageMetadata!.candidatesTokenCount, 5); @@ -62,19 +63,24 @@ void main() { expect(response.usageMetadata!.promptTokensDetails, isNotNull); expect(response.usageMetadata!.promptTokensDetails, hasLength(1)); expect( - response.usageMetadata!.promptTokensDetails!.first.tokenCount, 10); + response.usageMetadata!.promptTokensDetails!.first.tokenCount, + 10, + ); expect(response.usageMetadata!.candidatesTokensDetails, isNotNull); expect(response.usageMetadata!.candidatesTokensDetails, hasLength(1)); expect( - response.usageMetadata!.candidatesTokensDetails!.first.tokenCount, - 25); + response.usageMetadata!.candidatesTokensDetails!.first.tokenCount, + 25, + ); expect(response.usageMetadata!.toolUsePromptTokensDetails, isNotNull); expect( - response.usageMetadata!.toolUsePromptTokensDetails, hasLength(1)); + response.usageMetadata!.toolUsePromptTokensDetails, + hasLength(1), + ); expect( - response - .usageMetadata!.toolUsePromptTokensDetails!.first.tokenCount, - 12); + response.usageMetadata!.toolUsePromptTokensDetails!.first.tokenCount, + 12, + ); }); test('parses usageMetadata when thoughtsTokenCount is missing', () { @@ -84,11 +90,11 @@ void main() { 'content': { 'role': 'model', 'parts': [ - {'text': 'Some generated text.'} - ] + {'text': 'Some generated text.'}, + ], }, 'finishReason': 'STOP', - } + }, ], 'usageMetadata': { 'promptTokenCount': 10, @@ -96,15 +102,16 @@ void main() { 'totalTokenCount': 15, // thoughtsTokenCount is missing 'promptTokensDetails': [ - {'modality': 'TEXT', 'tokenCount': 10} + {'modality': 'TEXT', 'tokenCount': 10}, ], 'candidatesTokensDetails': [ - {'modality': 'TEXT', 'tokenCount': 25} + {'modality': 'TEXT', 'tokenCount': 25}, ], - } + }, }; - final response = - DeveloperSerialization().parseGenerateContentResponse(jsonResponse); + final response = DeveloperSerialization().parseGenerateContentResponse( + jsonResponse, + ); expect(response.usageMetadata, isNotNull); expect(response.usageMetadata!.promptTokenCount, 10); expect(response.usageMetadata!.candidatesTokenCount, 5); @@ -112,32 +119,34 @@ void main() { expect(response.usageMetadata!.thoughtsTokenCount, isNull); }); - test('parses usageMetadata when thoughtsTokenCount is present but null', - () { - final jsonResponse = { - 'candidates': [ - { - 'content': { - 'role': 'model', - 'parts': [ - {'text': 'Some generated text.'} - ] + test( + 'parses usageMetadata when thoughtsTokenCount is present but null', + () { + final jsonResponse = { + 'candidates': [ + { + 'content': { + 'role': 'model', + 'parts': [ + {'text': 'Some generated text.'}, + ], + }, + 'finishReason': 'STOP', }, - 'finishReason': 'STOP', - } - ], - 'usageMetadata': { - 'promptTokenCount': 10, - 'candidatesTokenCount': 5, - 'totalTokenCount': 15, - 'thoughtsTokenCount': null, - } - }; - final response = - DeveloperSerialization().parseGenerateContentResponse(jsonResponse); - expect(response.usageMetadata, isNotNull); - expect(response.usageMetadata!.thoughtsTokenCount, isNull); - }); + ], + 'usageMetadata': { + 'promptTokenCount': 10, + 'candidatesTokenCount': 5, + 'totalTokenCount': 15, + 'thoughtsTokenCount': null, + }, + }; + final response = DeveloperSerialization() + .parseGenerateContentResponse(jsonResponse); + expect(response.usageMetadata, isNotNull); + expect(response.usageMetadata!.thoughtsTokenCount, isNull); + }, + ); test('parses response when usageMetadata is missing', () { final jsonResponse = { @@ -146,16 +155,17 @@ void main() { 'content': { 'role': 'model', 'parts': [ - {'text': 'Some generated text.'} - ] + {'text': 'Some generated text.'}, + ], }, 'finishReason': 'STOP', - } + }, ], // usageMetadata is missing }; - final response = - DeveloperSerialization().parseGenerateContentResponse(jsonResponse); + final response = DeveloperSerialization().parseGenerateContentResponse( + jsonResponse, + ); expect(response.usageMetadata, isNull); }); @@ -166,8 +176,8 @@ void main() { { 'content': { 'parts': [ - {'text': 'This is a grounded response.'} - ] + {'text': 'This is a grounded response.'}, + ], }, 'finishReason': 'STOP', 'groundingMetadata': { @@ -178,22 +188,22 @@ void main() { 'web': { 'uri': 'http://example.com/1', 'title': 'Example Page 1', - } - } + }, + }, ], 'groundingSupports': [ { 'segment': { 'startIndex': 5, 'endIndex': 13, - 'text': 'grounded' + 'text': 'grounded', }, 'groundingChunkIndices': [0], - } - ] - } - } - ] + }, + ], + }, + }, + ], }; final response = DeveloperSerialization() @@ -201,10 +211,14 @@ void main() { final groundingMetadata = response.candidates.first.groundingMetadata; expect(groundingMetadata, isNotNull); - expect(groundingMetadata!.webSearchQueries, - equals(['query1', 'query2'])); - expect(groundingMetadata.searchEntryPoint?.renderedContent, - '
'); + expect( + groundingMetadata!.webSearchQueries, + equals(['query1', 'query2']), + ); + expect( + groundingMetadata.searchEntryPoint?.renderedContent, + '
', + ); final groundingChunk = groundingMetadata.groundingChunks.first; expect(groundingChunk.web?.uri, 'http://example.com/1'); @@ -225,8 +239,8 @@ void main() { { 'content': { 'parts': [ - {'text': 'This is a maps response.'} - ] + {'text': 'This is a maps response.'}, + ], }, 'finishReason': 'STOP', 'groundingMetadata': { @@ -236,12 +250,12 @@ void main() { 'uri': 'https://maps.google.com/?cid=123', 'title': 'Google HQ', 'placeId': 'ChIJS5dFe_cZzosR26ZvwqWaMAM', - } - } + }, + }, ], - } - } - ] + }, + }, + ], }; final response = DeveloperSerialization() @@ -257,33 +271,35 @@ void main() { }); test( - 'parses groundingMetadata with all optional fields null/missing and empty lists', - () { - final jsonResponse = { - 'candidates': [ - { - 'content': { - 'parts': [ - {'text': 'Test'} - ] + 'parses groundingMetadata with all optional fields null/missing and empty lists', + () { + final jsonResponse = { + 'candidates': [ + { + 'content': { + 'parts': [ + {'text': 'Test'}, + ], + }, + 'finishReason': 'STOP', + 'groundingMetadata': { + // All fields are missing + }, }, - 'finishReason': 'STOP', - 'groundingMetadata': { - // All fields are missing - } - } - ] - }; - final response = DeveloperSerialization() - .parseGenerateContentResponse(jsonResponse); - final groundingMetadata = response.candidates.first.groundingMetadata; - - expect(groundingMetadata, isNotNull); - expect(groundingMetadata!.searchEntryPoint, isNull); - expect(groundingMetadata.groundingChunks, isEmpty); - expect(groundingMetadata.groundingSupports, isEmpty); - expect(groundingMetadata.webSearchQueries, isEmpty); - }); + ], + }; + final response = DeveloperSerialization() + .parseGenerateContentResponse(jsonResponse); + final groundingMetadata = + response.candidates.first.groundingMetadata; + + expect(groundingMetadata, isNotNull); + expect(groundingMetadata!.searchEntryPoint, isNull); + expect(groundingMetadata.groundingChunks, isEmpty); + expect(groundingMetadata.groundingSupports, isEmpty); + expect(groundingMetadata.webSearchQueries, isEmpty); + }, + ); test('handles absence of groundingMetadata field', () { final jsonResponse = { @@ -291,13 +307,13 @@ void main() { { 'content': { 'parts': [ - {'text': 'Test'} - ] + {'text': 'Test'}, + ], }, - 'finishReason': 'STOP' + 'finishReason': 'STOP', // No groundingMetadata key - } - ] + }, + ], }; final response = DeveloperSerialization() .parseGenerateContentResponse(jsonResponse); @@ -306,70 +322,80 @@ void main() { }); test( - 'throws FormatException if renderedContent is missing in searchEntryPoint', - () { - final jsonResponse = { - 'candidates': [ - { - 'groundingMetadata': {'searchEntryPoint': {}} - } - ] - }; - - expect( - () => DeveloperSerialization() - .parseGenerateContentResponse(jsonResponse), - throwsA(isA().having( - (e) => e.message, 'message', contains('SearchEntryPoint')))); - }); + 'throws FormatException if renderedContent is missing in searchEntryPoint', + () { + final jsonResponse = { + 'candidates': [ + { + 'groundingMetadata': {'searchEntryPoint': {}}, + }, + ], + }; + + expect( + () => DeveloperSerialization().parseGenerateContentResponse( + jsonResponse, + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('SearchEntryPoint'), + ), + ), + ); + }, + ); test( - 'parses groundingSupports and filters out entries without a segment', - () { - final jsonResponse = { - 'candidates': [ - { - 'content': { - 'parts': [ - {'text': 'Test'} - ] - }, - 'finishReason': 'STOP', - 'groundingMetadata': { - 'groundingSupports': [ - // Valid entry - { - 'segment': { - 'startIndex': 0, - 'endIndex': 4, - 'text': 'Test' + 'parses groundingSupports and filters out entries without a segment', + () { + final jsonResponse = { + 'candidates': [ + { + 'content': { + 'parts': [ + {'text': 'Test'}, + ], + }, + 'finishReason': 'STOP', + 'groundingMetadata': { + 'groundingSupports': [ + // Valid entry + { + 'segment': { + 'startIndex': 0, + 'endIndex': 4, + 'text': 'Test', + }, + 'groundingChunkIndices': [0], }, - 'groundingChunkIndices': [0] - }, - // Invalid entry - missing segment - { - 'groundingChunkIndices': [1] - }, - // Invalid entry - empty object - {} - ] - } - } - ] - }; - - final response = DeveloperSerialization() - .parseGenerateContentResponse(jsonResponse); - final groundingMetadata = response.candidates.first.groundingMetadata; - - expect(groundingMetadata, isNotNull); - // The invalid entries should be filtered out. - expect(groundingMetadata!.groundingSupports, hasLength(1)); - - final validSupport = groundingMetadata.groundingSupports.first; - expect(validSupport.segment.text, 'Test'); - expect(validSupport.groundingChunkIndices, [0]); - }); + // Invalid entry - missing segment + { + 'groundingChunkIndices': [1], + }, + // Invalid entry - empty object + {}, + ], + }, + }, + ], + }; + + final response = DeveloperSerialization() + .parseGenerateContentResponse(jsonResponse); + final groundingMetadata = + response.candidates.first.groundingMetadata; + + expect(groundingMetadata, isNotNull); + // The invalid entries should be filtered out. + expect(groundingMetadata!.groundingSupports, hasLength(1)); + + final validSupport = groundingMetadata.groundingSupports.first; + expect(validSupport.segment.text, 'Test'); + expect(validSupport.groundingChunkIndices, [0]); + }, + ); }); group('UrlContextMetadata parsing', () { @@ -379,20 +405,20 @@ void main() { { 'content': { 'parts': [ - {'text': 'Some text'} - ] + {'text': 'Some text'}, + ], }, 'finishReason': 'STOP', 'urlContextMetadata': { 'urlMetadata': [ { 'retrievedUrl': 'https://example.com', - 'urlRetrievalStatus': 'URL_RETRIEVAL_STATUS_SUCCESS' - } - ] - } - } - ] + 'urlRetrievalStatus': 'URL_RETRIEVAL_STATUS_SUCCESS', + }, + ], + }, + }, + ], }; final response = DeveloperSerialization() .parseGenerateContentResponse(jsonResponse); @@ -411,11 +437,11 @@ void main() { { 'urlContextMetadata': { 'urlMetadata': [ - {'urlRetrievalStatus': 'URL_RETRIEVAL_STATUS_ERROR'} - ] - } - } - ] + {'urlRetrievalStatus': 'URL_RETRIEVAL_STATUS_ERROR'}, + ], + }, + }, + ], }; final response = DeveloperSerialization() .parseGenerateContentResponse(jsonResponse); @@ -429,9 +455,9 @@ void main() { final jsonResponse = { 'candidates': [ { - 'urlContextMetadata': {'urlMetadata': []} - } - ] + 'urlContextMetadata': {'urlMetadata': []}, + }, + ], }; final response = DeveloperSerialization() .parseGenerateContentResponse(jsonResponse); @@ -444,8 +470,8 @@ void main() { test('handles missing urlContextMetadata field', () { final jsonResponse = { 'candidates': [ - {'finishReason': 'STOP'} - ] + {'finishReason': 'STOP'}, + ], }; final response = DeveloperSerialization() .parseGenerateContentResponse(jsonResponse); @@ -456,14 +482,21 @@ void main() { test('throws for invalid urlContextMetadata structure', () { final jsonResponse = { 'candidates': [ - {'urlContextMetadata': 'not_a_map'} - ] + {'urlContextMetadata': 'not_a_map'}, + ], }; expect( - () => DeveloperSerialization() - .parseGenerateContentResponse(jsonResponse), - throwsA(isA().having((e) => e.message, - 'message', contains('UrlContextMetadata')))); + () => DeveloperSerialization().parseGenerateContentResponse( + jsonResponse, + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('UrlContextMetadata'), + ), + ), + ); }); test('throws for invalid urlMetadata item in list', () { @@ -471,16 +504,23 @@ void main() { 'candidates': [ { 'urlContextMetadata': { - 'urlMetadata': ['not_a_map'] - } - } - ] + 'urlMetadata': ['not_a_map'], + }, + }, + ], }; expect( - () => DeveloperSerialization() - .parseGenerateContentResponse(jsonResponse), - throwsA(isA().having( - (e) => e.message, 'message', contains('UrlMetadata')))); + () => DeveloperSerialization().parseGenerateContentResponse( + jsonResponse, + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('UrlMetadata'), + ), + ), + ); }); }); @@ -490,11 +530,12 @@ void main() { 'promptTokenCount': 10, 'candidatesTokenCount': 25, 'totalTokenCount': 35, - } + }, }; - final response = - DeveloperSerialization().parseGenerateContentResponse(jsonResponse); + final response = DeveloperSerialization().parseGenerateContentResponse( + jsonResponse, + ); expect(response.usageMetadata, isNotNull); expect(response.usageMetadata!.promptTokenCount, 10); @@ -516,16 +557,17 @@ void main() { 'inlineData': { 'mimeType': 'application/octet-stream', 'data': base64Encode(inlineData), - } - } - ] + }, + }, + ], }, 'finishReason': 'STOP', - } + }, ], }; - final response = - DeveloperSerialization().parseGenerateContentResponse(jsonResponse); + final response = DeveloperSerialization().parseGenerateContentResponse( + jsonResponse, + ); final part = response.candidates.first.content.parts.first; expect(part, isA()); expect((part as InlineDataPart).mimeType, 'application/octet-stream'); @@ -538,8 +580,8 @@ void main() { { 'content': { 'parts': [ - {'text': 'Test'} - ] + {'text': 'Test'}, + ], }, 'safetyRatings': [ { @@ -548,14 +590,15 @@ void main() { 'blocked': true, // These fields should be ignored by the developer parser 'severity': 'HARM_SEVERITY_HIGH', - 'severityScore': 0.9 - } - ] - } - ] + 'severityScore': 0.9, + }, + ], + }, + ], }; - final response = - DeveloperSerialization().parseGenerateContentResponse(jsonResponse); + final response = DeveloperSerialization().parseGenerateContentResponse( + jsonResponse, + ); final rating = response.candidates.first.safetyRatings!.first; expect(rating.category, HarmCategory.dangerousContent); expect(rating.probability, HarmProbability.high); @@ -568,8 +611,9 @@ void main() { group('parseCountTokensResponse', () { test('parses valid JSON correctly', () { final json = {'totalTokens': 123}; - final response = - DeveloperSerialization().parseCountTokensResponse(json); + final response = DeveloperSerialization().parseCountTokensResponse( + json, + ); expect(response.totalTokens, 123); // Developer API does not return other fields // ignore: deprecated_member_use_from_same_package @@ -579,16 +623,20 @@ void main() { test('throws FirebaseAIException on error response', () { final json = { - 'error': {'code': 400, 'message': 'Invalid request'} + 'error': {'code': 400, 'message': 'Invalid request'}, }; - expect(() => DeveloperSerialization().parseCountTokensResponse(json), - throwsA(isA())); + expect( + () => DeveloperSerialization().parseCountTokensResponse(json), + throwsA(isA()), + ); }); test('throws unhandledFormat on invalid JSON', () { final json = {'wrongKey': 123}; - expect(() => DeveloperSerialization().parseCountTokensResponse(json), - throwsA(isA())); + expect( + () => DeveloperSerialization().parseCountTokensResponse(json), + throwsA(isA()), + ); }); }); @@ -599,7 +647,10 @@ void main() { (prefix: 'models', name: 'gemini-pro'), [ SafetySetting( - HarmCategory.dangerousContent, HarmBlockThreshold.high, null) + HarmCategory.dangerousContent, + HarmBlockThreshold.high, + null, + ), ], null, null, @@ -610,25 +661,29 @@ void main() { expect(safetySettings, hasLength(1)); expect(safetySettings.first, { 'category': 'HARM_CATEGORY_DANGEROUS_CONTENT', - 'threshold': 'BLOCK_ONLY_HIGH' + 'threshold': 'BLOCK_ONLY_HIGH', }); }); test('throws ArgumentError for safetySetting with method', () { expect( - () => DeveloperSerialization().generateContentRequest( - [], - (prefix: 'models', name: 'gemini-pro'), - [ - SafetySetting(HarmCategory.dangerousContent, - HarmBlockThreshold.high, HarmBlockMethod.severity) - ], - null, - null, - null, - null, - ), - throwsA(isA())); + () => DeveloperSerialization().generateContentRequest( + [], + (prefix: 'models', name: 'gemini-pro'), + [ + SafetySetting( + HarmCategory.dangerousContent, + HarmBlockThreshold.high, + HarmBlockMethod.severity, + ), + ], + null, + null, + null, + null, + ), + throwsA(isA()), + ); }); }); diff --git a/packages/firebase_ai/firebase_ai/test/error_test.dart b/packages/firebase_ai/firebase_ai/test/error_test.dart index fb4cf9b935bf..ca5a68b389f5 100644 --- a/packages/firebase_ai/firebase_ai/test/error_test.dart +++ b/packages/firebase_ai/firebase_ai/test/error_test.dart @@ -30,17 +30,20 @@ void main() { test('UnsupportedUserLocation message', () { final exception = UnsupportedUserLocation(); expect( - exception.message, 'User location is not supported for the API use.'); + exception.message, + 'User location is not supported for the API use.', + ); }); test('ServiceApiNotEnabled message', () { final exception = ServiceApiNotEnabled('projects/test-project'); expect( - exception.message, - 'Enable Firebase AI Logic in your Firebase project by visiting the Firebase Console at ' - 'https://console.firebase.google.com/project/test-project/ailogic ' - 'and clicking "Get started". If you enabled this API recently, wait a few minutes for the ' - 'action to propagate to our systems and then retry.'); + exception.message, + 'Enable Firebase AI Logic in your Firebase project by visiting the Firebase Console at ' + 'https://console.firebase.google.com/project/test-project/ailogic ' + 'and clicking "Get started". If you enabled this API recently, wait a few minutes for the ' + 'action to propagate to our systems and then retry.', + ); }); test('QuotaExceeded toString', () { @@ -56,40 +59,48 @@ void main() { test('FirebaseAISdkException toString', () { final exception = FirebaseAISdkException('SDK failed to parse response.'); expect( - exception.toString(), - 'SDK failed to parse response.\n' - 'This indicates a problem with the Firebase AI Logic SDK. ' - 'Try updating to the latest version ' - '(https://pub.dev/packages/firebase_ai/versions), ' - 'or file an issue at ' - 'https://github.com/firebase/flutterfire/issues.'); + exception.toString(), + 'SDK failed to parse response.\n' + 'This indicates a problem with the Firebase AI Logic SDK. ' + 'Try updating to the latest version ' + '(https://pub.dev/packages/firebase_ai/versions), ' + 'or file an issue at ' + 'https://github.com/firebase/flutterfire/issues.', + ); }); test('ImagenImagesBlockedException toString', () { - final exception = - ImagenImagesBlockedException('All images were blocked.'); + final exception = ImagenImagesBlockedException( + 'All images were blocked.', + ); expect(exception.toString(), 'All images were blocked.'); }); test('LiveWebSocketClosedException toString - DEADLINE_EXCEEDED', () { final exception = LiveWebSocketClosedException( - 'DEADLINE_EXCEEDED: Connection timed out.'); - expect(exception.toString(), - 'The current live session has expired. Please start a new session.'); + 'DEADLINE_EXCEEDED: Connection timed out.', + ); + expect( + exception.toString(), + 'The current live session has expired. Please start a new session.', + ); }); test('LiveWebSocketClosedException toString - RESOURCE_EXHAUSTED', () { final exception = LiveWebSocketClosedException( - 'RESOURCE_EXHAUSTED: Too many connections.'); + 'RESOURCE_EXHAUSTED: Too many connections.', + ); expect( - exception.toString(), - 'You have exceeded the maximum number of concurrent sessions. ' - 'Please close other sessions and try again later.'); + exception.toString(), + 'You have exceeded the maximum number of concurrent sessions. ' + 'Please close other sessions and try again later.', + ); }); test('LiveWebSocketClosedException toString - Other', () { - final exception = - LiveWebSocketClosedException('WebSocket connection closed.'); + final exception = LiveWebSocketClosedException( + 'WebSocket connection closed.', + ); expect(exception.toString(), 'WebSocket connection closed.'); }); @@ -98,8 +109,8 @@ void main() { final json = { 'message': 'Invalid API key', 'details': [ - {'reason': 'API_KEY_INVALID'} - ] + {'reason': 'API_KEY_INVALID'}, + ], }; final exception = parseError(json); expect(exception, isInstanceOf()); @@ -108,7 +119,7 @@ void main() { test('parses UNSUPPORTED_USER_LOCATION', () { final json = { - 'message': 'User location is not supported for the API use.' + 'message': 'User location is not supported for the API use.', }; final exception = parseError(json); expect(exception, isInstanceOf()); @@ -130,18 +141,19 @@ void main() { 'metadata': { 'service': 'firebasevertexai.googleapis.com', 'consumer': 'projects/my-project-id', - } - } - ] + }, + }, + ], }; final exception = parseError(json); expect(exception, isInstanceOf()); expect( - (exception as ServiceApiNotEnabled).message, - 'Enable Firebase AI Logic in your Firebase project by visiting the Firebase Console at ' - 'https://console.firebase.google.com/project/my-project-id/ailogic ' - 'and clicking "Get started". If you enabled this API recently, wait a few minutes for the ' - 'action to propagate to our systems and then retry.'); + (exception as ServiceApiNotEnabled).message, + 'Enable Firebase AI Logic in your Firebase project by visiting the Firebase Console at ' + 'https://console.firebase.google.com/project/my-project-id/ailogic ' + 'and clicking "Get started". If you enabled this API recently, wait a few minutes for the ' + 'action to propagate to our systems and then retry.', + ); }); test('parses SERVER_ERROR', () { @@ -153,8 +165,10 @@ void main() { test('parses UNHANDLED_FORMAT', () { final json = {'unexpected': 'format'}; - expect(() => parseError(json), - throwsA(isInstanceOf())); + expect( + () => parseError(json), + throwsA(isInstanceOf()), + ); }); }); }); diff --git a/packages/firebase_ai/firebase_ai/test/firebase_vertexai_test.dart b/packages/firebase_ai/firebase_ai/test/firebase_vertexai_test.dart index 166cd3ff6939..f3a586117125 100644 --- a/packages/firebase_ai/firebase_ai/test/firebase_vertexai_test.dart +++ b/packages/firebase_ai/firebase_ai/test/firebase_vertexai_test.dart @@ -56,14 +56,14 @@ void main() { customAuth = FirebaseAuth.instanceFor(app: customApp); TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMessageHandler( - 'dev.flutter.pigeon.firebase_app_check_platform_interface.' - 'FirebaseAppCheckHostApi.getToken', - (_) async { - return const StandardMessageCodec().encodeMessage( - ['app-check-token'], + 'dev.flutter.pigeon.firebase_app_check_platform_interface.' + 'FirebaseAppCheckHostApi.getToken', + (_) async { + return const StandardMessageCodec().encodeMessage([ + 'app-check-token', + ]); + }, ); - }, - ); }); group('agentPlatform tests', () { @@ -150,9 +150,10 @@ void main() { test('Instance creation with custom', () { // ignore: deprecated_member_use_from_same_package final vertexAI = FirebaseAI.vertexAI( - app: customApp, - appCheck: customAppCheck, - location: 'custom-location'); + app: customApp, + appCheck: customAppCheck, + location: 'custom-location', + ); expect(vertexAI.app, equals(customApp)); expect(vertexAI.appCheck, equals(customAppCheck)); expect(vertexAI.location, equals('custom-location')); @@ -242,10 +243,7 @@ void main() { }); final ai = FirebaseAI.googleAI(app: app); - final model = ai.generativeModel( - model: 'gemini-pro', - httpClient: client, - ); + final model = ai.generativeModel(model: 'gemini-pro', httpClient: client); await model.generateContent([Content.text('prompt')]); await model.generateContentStream([Content.text('prompt')]).drain(); diff --git a/packages/firebase_ai/firebase_ai/test/google_ai_generative_model_test.dart b/packages/firebase_ai/firebase_ai/test/google_ai_generative_model_test.dart index c8d2a8e551ed..c87bb08590f3 100644 --- a/packages/firebase_ai/firebase_ai/test/google_ai_generative_model_test.dart +++ b/packages/firebase_ai/firebase_ai/test/google_ai_generative_model_test.dart @@ -39,14 +39,15 @@ void main() { }) { final client = ClientController(); final model = createModelWithClient( - useAgentPlatform: false, - app: app, - model: modelName, - client: client.client, - tools: tools, - toolConfig: toolConfig, - systemInstruction: systemInstruction, - location: 'us-central1'); + useAgentPlatform: false, + app: app, + model: modelName, + client: client.client, + tools: tools, + toolConfig: toolConfig, + systemInstruction: systemInstruction, + location: 'us-central1', + ); return (client, model); } @@ -80,8 +81,8 @@ void main() { test('allows specifying an API version', () async { final (client, model) = createModel( - // requestOptions: RequestOptions(apiVersion: 'override_version'), - ); + // requestOptions: RequestOptions(apiVersion: 'override_version'), + ); const prompt = 'Some prompt'; await client.checkRequest( () => model.generateContent([Content.text(prompt)]), @@ -225,9 +226,7 @@ void main() { ]), ], toolConfig: ToolConfig( - functionCallingConfig: FunctionCallingConfig.any( - {'someFunction'}, - ), + functionCallingConfig: FunctionCallingConfig.any({'someFunction'}), ), ); const prompt = 'Some prompt'; @@ -245,11 +244,11 @@ void main() { 'properties': { 'schema1': { 'type': 'STRING', - 'description': 'Some parameter.' - } + 'description': 'Some parameter.', + }, }, - 'required': ['schema1'] - } + 'required': ['schema1'], + }, }, ], }, @@ -283,9 +282,9 @@ void main() { ]), ], toolConfig: ToolConfig( - functionCallingConfig: FunctionCallingConfig.any( - {'someFunction'}, - ), + functionCallingConfig: FunctionCallingConfig.any({ + 'someFunction', + }), ), ), verifyRequest: (_, request) { @@ -300,11 +299,11 @@ void main() { 'properties': { 'schema1': { 'type': 'STRING', - 'description': 'Some parameter.' - } + 'description': 'Some parameter.', + }, }, - 'required': ['schema1'] - } + 'required': ['schema1'], + }, }, ], }, @@ -321,9 +320,7 @@ void main() { }); test('can pass a google search tool', () async { - final (client, model) = createModel( - tools: [Tool.googleSearch()], - ); + final (client, model) = createModel(tools: [Tool.googleSearch()]); const prompt = 'Some prompt'; await client.checkRequest( () => model.generateContent([Content.text(prompt)]), @@ -337,9 +334,7 @@ void main() { }); test('can pass a url context tool', () async { - final (client, model) = createModel( - tools: [Tool.urlContext()], - ); + final (client, model) = createModel(tools: [Tool.urlContext()]); const prompt = 'Some prompt'; await client.checkRequest( () => model.generateContent([Content.text(prompt)]), @@ -353,15 +348,17 @@ void main() { }); test('can enable code execution', () async { - final (client, model) = createModel(tools: [ - // Tool(codeExecution: CodeExecution()), - ]); + final (client, model) = createModel( + tools: [ + // Tool(codeExecution: CodeExecution()), + ], + ); const prompt = 'Some prompt'; await client.checkRequest( () => model.generateContent([Content.text(prompt)]), verifyRequest: (_, request) { expect(request['tools'], [ - {'codeExecution': {}} + {'codeExecution': {}}, ]); }, response: arbitraryGenerateContentResponse, @@ -372,14 +369,15 @@ void main() { final (client, model) = createModel(); const prompt = 'Some prompt'; await client.checkRequest( - () => model.generateContent([ - Content.text(prompt) - ], tools: [ - // Tool(codeExecution: CodeExecution()), - ]), + () => model.generateContent( + [Content.text(prompt)], + tools: [ + // Tool(codeExecution: CodeExecution()), + ], + ), verifyRequest: (_, request) { expect(request['tools'], [ - {'codeExecution': {}} + {'codeExecution': {}}, ]); }, response: arbitraryGenerateContentResponse, @@ -495,9 +493,7 @@ void main() { }); test('can pass a google search tool', () async { - final (client, model) = createModel( - tools: [Tool.googleSearch()], - ); + final (client, model) = createModel(tools: [Tool.googleSearch()]); const prompt = 'Some prompt'; final responses = await client.checkStreamRequest( () async => model.generateContentStream([Content.text(prompt)]), @@ -538,7 +534,7 @@ void main() { ], }, ], - } + }, }); }, response: {'totalTokens': 2}, @@ -579,8 +575,9 @@ void main() { ), verifyRequest: (_, countTokensRequest) { expect(countTokensRequest, isNotNull); - final request = countTokensRequest['generateContentRequest']! - as Map; + final request = + countTokensRequest['generateContentRequest']! + as Map; expect(request['safetySettings'], [ { 'category': 'HARM_CATEGORY_DANGEROUS_CONTENT', @@ -615,9 +612,7 @@ void main() { }, skip: 'Only content argument supported for countTokens'); test('can pass a google search tool', () async { - final (client, model) = createModel( - tools: [Tool.googleSearch()], - ); + final (client, model) = createModel(tools: [Tool.googleSearch()]); const prompt = 'Some prompt'; await client.checkRequest( () => model.countTokens([Content.text(prompt)]), @@ -680,18 +675,24 @@ void main() { const outputDimensionality = 1; final embeddingValues = [0.1]; - await client.checkRequest(() async { - Content.text(content); - // await model.embedContent( - // Content.text(content), - // outputDimensionality: outputDimensionality, - // ); - }, verifyRequest: (_, request) { - expect(request, - containsPair('outputDimensionality', outputDimensionality)); - }, response: { - 'embedding': {'values': embeddingValues}, - }); + await client.checkRequest( + () async { + Content.text(content); + // await model.embedContent( + // Content.text(content), + // outputDimensionality: outputDimensionality, + // ); + }, + verifyRequest: (_, request) { + expect( + request, + containsPair('outputDimensionality', outputDimensionality), + ); + }, + response: { + 'embedding': {'values': embeddingValues}, + }, + ); }); }, skip: 'No support for embedding content'); @@ -768,30 +769,34 @@ void main() { final embeddingValues1 = [0.1]; final embeddingValues2 = [0.4]; - await client.checkRequest(() async { - Content.text(content1); - Content.text(content2); - // await model.batchEmbedContents([ - // EmbedContentRequest( - // Content.text(content1), - // outputDimensionality: outputDimensionality, - // ), - // EmbedContentRequest( - // Content.text(content2), - // outputDimensionality: outputDimensionality, - // ), - // ]); - }, verifyRequest: (_, request) { - expect(request['requests'], [ - containsPair('outputDimensionality', outputDimensionality), - containsPair('outputDimensionality', outputDimensionality), - ]); - }, response: { - 'embeddings': [ - {'values': embeddingValues1}, - {'values': embeddingValues2}, - ], - }); + await client.checkRequest( + () async { + Content.text(content1); + Content.text(content2); + // await model.batchEmbedContents([ + // EmbedContentRequest( + // Content.text(content1), + // outputDimensionality: outputDimensionality, + // ), + // EmbedContentRequest( + // Content.text(content2), + // outputDimensionality: outputDimensionality, + // ), + // ]); + }, + verifyRequest: (_, request) { + expect(request['requests'], [ + containsPair('outputDimensionality', outputDimensionality), + containsPair('outputDimensionality', outputDimensionality), + ]); + }, + response: { + 'embeddings': [ + {'values': embeddingValues1}, + {'values': embeddingValues2}, + ], + }, + ); }); }, skip: 'No support for embed content'); }); diff --git a/packages/firebase_ai/firebase_ai/test/google_ai_response_parsing_test.dart b/packages/firebase_ai/firebase_ai/test/google_ai_response_parsing_test.dart index af602bcf353d..3a08817cf1ee 100644 --- a/packages/firebase_ai/firebase_ai/test/google_ai_response_parsing_test.dart +++ b/packages/firebase_ai/firebase_ai/test/google_ai_response_parsing_test.dart @@ -94,8 +94,8 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - DeveloperSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = DeveloperSerialization() + .parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( @@ -188,8 +188,8 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - DeveloperSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = DeveloperSerialization() + .parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( @@ -270,33 +270,30 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - DeveloperSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = DeveloperSerialization() + .parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( - GenerateContentResponse( - [ - Candidate( - Content.model([ - const TextPart('some response'), - ]), - [ - SafetyRating( - HarmCategory.sexuallyExplicit, - HarmProbability.negligible, - isBlocked: true, - ), - SafetyRating( - HarmCategory.hateSpeech, HarmProbability.negligible), - ], - null, - FinishReason.stop, - null, - ), - ], - null, - ), + GenerateContentResponse([ + Candidate( + Content.model([const TextPart('some response')]), + [ + SafetyRating( + HarmCategory.sexuallyExplicit, + HarmProbability.negligible, + isBlocked: true, + ), + SafetyRating( + HarmCategory.hateSpeech, + HarmProbability.negligible, + ), + ], + null, + FinishReason.stop, + null, + ), + ], null), ), ); }); @@ -384,8 +381,8 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - DeveloperSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = DeveloperSerialization() + .parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( @@ -519,8 +516,8 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - DeveloperSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = DeveloperSerialization() + .parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( @@ -603,27 +600,24 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - DeveloperSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = DeveloperSerialization() + .parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( - GenerateContentResponse( - [ - Candidate( - Content.model([ - // ExecutableCode(Language.python, 'print(\'hello world\')'), - // CodeExecutionResult(Outcome.ok, 'hello world'), - const TextPart('hello world') - ]), - [], - null, - FinishReason.stop, - null, - ), - ], - null, - ), + GenerateContentResponse([ + Candidate( + Content.model([ + // ExecutableCode(Language.python, 'print(\'hello world\')'), + // CodeExecutionResult(Outcome.ok, 'hello world'), + const TextPart('hello world'), + ]), + [], + null, + FinishReason.stop, + null, + ), + ], null), ), ); }, skip: 'Code Execution Unsupported'); @@ -706,16 +700,20 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - DeveloperSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = DeveloperSerialization() + .parseGenerateContentResponse(decoded); final candidate = generateContentResponse.candidates.first; final urlContextMetadata = candidate.urlContextMetadata; expect(urlContextMetadata, isNotNull); expect(urlContextMetadata!.urlMetadata, hasLength(1)); - expect(urlContextMetadata.urlMetadata.first.retrievedUrl, - Uri.parse('https://berkshirehathaway.com')); - expect(urlContextMetadata.urlMetadata.first.urlRetrievalStatus, - UrlRetrievalStatus.success); + expect( + urlContextMetadata.urlMetadata.first.retrievedUrl, + Uri.parse('https://berkshirehathaway.com'), + ); + expect( + urlContextMetadata.urlMetadata.first.urlRetrievalStatus, + UrlRetrievalStatus.success, + ); final usageMetadata = generateContentResponse.usageMetadata; expect(usageMetadata, isNotNull); expect(usageMetadata!.toolUsePromptTokenCount, 34); @@ -847,26 +845,38 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - DeveloperSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = DeveloperSerialization() + .parseGenerateContentResponse(decoded); final urlContextMetadata = generateContentResponse.candidates.first.urlContextMetadata; expect(urlContextMetadata, isNotNull); expect(urlContextMetadata!.urlMetadata, hasLength(3)); expect( - urlContextMetadata.urlMetadata[0].retrievedUrl, - Uri.parse( - 'https://www.nytimes.com/2023/06/25/realestate/barbiecore-home-decor-interior-design.html?action=click&contentCollection=undefined®ion=Footer&module=WhatsNext&version=WhatsNext&contentID=WhatsNext&moduleDetail=most-emailed-0&pgtype=undefinedl')); - expect(urlContextMetadata.urlMetadata[0].urlRetrievalStatus, - UrlRetrievalStatus.error); - expect(urlContextMetadata.urlMetadata[1].retrievedUrl, - Uri.parse('https://ai.google.dev')); - expect(urlContextMetadata.urlMetadata[1].urlRetrievalStatus, - UrlRetrievalStatus.success); - expect(urlContextMetadata.urlMetadata[2].retrievedUrl, - Uri.parse('https://a-completely-non-existent-url-for-testing.org')); - expect(urlContextMetadata.urlMetadata[2].urlRetrievalStatus, - UrlRetrievalStatus.error); + urlContextMetadata.urlMetadata[0].retrievedUrl, + Uri.parse( + 'https://www.nytimes.com/2023/06/25/realestate/barbiecore-home-decor-interior-design.html?action=click&contentCollection=undefined®ion=Footer&module=WhatsNext&version=WhatsNext&contentID=WhatsNext&moduleDetail=most-emailed-0&pgtype=undefinedl', + ), + ); + expect( + urlContextMetadata.urlMetadata[0].urlRetrievalStatus, + UrlRetrievalStatus.error, + ); + expect( + urlContextMetadata.urlMetadata[1].retrievedUrl, + Uri.parse('https://ai.google.dev'), + ); + expect( + urlContextMetadata.urlMetadata[1].urlRetrievalStatus, + UrlRetrievalStatus.success, + ); + expect( + urlContextMetadata.urlMetadata[2].retrievedUrl, + Uri.parse('https://a-completely-non-existent-url-for-testing.org'), + ); + expect( + urlContextMetadata.urlMetadata[2].urlRetrievalStatus, + UrlRetrievalStatus.error, + ); }); test('allows missing content', () async { @@ -899,31 +909,36 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - DeveloperSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = DeveloperSerialization() + .parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( GenerateContentResponse([ Candidate( - Content(null, []), - [ - SafetyRating( - HarmCategory.sexuallyExplicit, - HarmProbability.negligible, - ), - SafetyRating( - HarmCategory.hateSpeech, HarmProbability.negligible), - SafetyRating( - HarmCategory.harassment, HarmProbability.negligible), - SafetyRating( - HarmCategory.dangerousContent, - HarmProbability.negligible, - ), - ], - CitationMetadata([]), - FinishReason.safety, - null), + Content(null, []), + [ + SafetyRating( + HarmCategory.sexuallyExplicit, + HarmProbability.negligible, + ), + SafetyRating( + HarmCategory.hateSpeech, + HarmProbability.negligible, + ), + SafetyRating( + HarmCategory.harassment, + HarmProbability.negligible, + ), + SafetyRating( + HarmCategory.dangerousContent, + HarmProbability.negligible, + ), + ], + CitationMetadata([]), + FinishReason.safety, + null, + ), ], null), ), ); @@ -955,11 +970,13 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - DeveloperSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = DeveloperSerialization() + .parseGenerateContentResponse(decoded); expect(generateContentResponse.text, 'Initial text And more text'); - expect(generateContentResponse.candidates.single.text, - 'Initial text And more text'); + expect( + generateContentResponse.candidates.single.text, + 'Initial text And more text', + ); }); }); @@ -997,10 +1014,13 @@ void main() { ), ); expect( - () => DeveloperSerialization().parseGenerateContentResponse(decoded), - expectedThrow); - expect(() => DeveloperSerialization().parseCountTokensResponse(decoded), - expectedThrow); + () => DeveloperSerialization().parseGenerateContentResponse(decoded), + expectedThrow, + ); + expect( + () => DeveloperSerialization().parseCountTokensResponse(decoded), + expectedThrow, + ); // expect(() => parseEmbedContentResponse(decoded), expectedThrow); }); @@ -1029,10 +1049,13 @@ void main() { ), ); expect( - () => DeveloperSerialization().parseGenerateContentResponse(decoded), - expectedThrow); - expect(() => DeveloperSerialization().parseCountTokensResponse(decoded), - expectedThrow); + () => DeveloperSerialization().parseGenerateContentResponse(decoded), + expectedThrow, + ); + expect( + () => DeveloperSerialization().parseCountTokensResponse(decoded), + expectedThrow, + ); // expect(() => parseEmbedContentResponse(decoded), expectedThrow); }); @@ -1064,10 +1087,13 @@ void main() { ), ); expect( - () => DeveloperSerialization().parseGenerateContentResponse(decoded), - expectedThrow); - expect(() => DeveloperSerialization().parseCountTokensResponse(decoded), - expectedThrow); + () => DeveloperSerialization().parseGenerateContentResponse(decoded), + expectedThrow, + ); + expect( + () => DeveloperSerialization().parseCountTokensResponse(decoded), + expectedThrow, + ); // expect(() => parseEmbedContentResponse(decoded), expectedThrow); }); }); diff --git a/packages/firebase_ai/firebase_ai/test/live_session_test.dart b/packages/firebase_ai/firebase_ai/test/live_session_test.dart index f2e68b587a2c..de5db2b5382e 100644 --- a/packages/firebase_ai/firebase_ai/test/live_session_test.dart +++ b/packages/firebase_ai/firebase_ai/test/live_session_test.dart @@ -122,36 +122,36 @@ void main() { fakeWs.close(); }); - test('sendStartActivityRealtime sends correct activity_start message', - () async { - final fakeWs = FakeWebSocketChannel(); - final session = LiveSession.forTesting(fakeWs); - - await session.sendStartActivityRealtime(); - - expect(fakeWs.sentMessages.length, 1); - final jsonPayload = json.decode(fakeWs.sentMessages.first as String); - expect(jsonPayload, { - 'realtime_input': { - 'activity_start': {}, - }, - }); - }); - - test('sendStopActivityRealtime sends correct activity_end message', - () async { - final fakeWs = FakeWebSocketChannel(); - final session = LiveSession.forTesting(fakeWs); - - await session.sendStopActivityRealtime(); - - expect(fakeWs.sentMessages.length, 1); - final jsonPayload = json.decode(fakeWs.sentMessages.first as String); - expect(jsonPayload, { - 'realtime_input': { - 'activity_end': {}, - }, - }); - }); + test( + 'sendStartActivityRealtime sends correct activity_start message', + () async { + final fakeWs = FakeWebSocketChannel(); + final session = LiveSession.forTesting(fakeWs); + + await session.sendStartActivityRealtime(); + + expect(fakeWs.sentMessages.length, 1); + final jsonPayload = json.decode(fakeWs.sentMessages.first as String); + expect(jsonPayload, { + 'realtime_input': {'activity_start': {}}, + }); + }, + ); + + test( + 'sendStopActivityRealtime sends correct activity_end message', + () async { + final fakeWs = FakeWebSocketChannel(); + final session = LiveSession.forTesting(fakeWs); + + await session.sendStopActivityRealtime(); + + expect(fakeWs.sentMessages.length, 1); + final jsonPayload = json.decode(fakeWs.sentMessages.first as String); + expect(jsonPayload, { + 'realtime_input': {'activity_end': {}}, + }); + }, + ); }); } diff --git a/packages/firebase_ai/firebase_ai/test/live_test.dart b/packages/firebase_ai/firebase_ai/test/live_test.dart index a0754bb2fd3b..b5da745bcfac 100644 --- a/packages/firebase_ai/firebase_ai/test/live_test.dart +++ b/packages/firebase_ai/firebase_ai/test/live_test.dart @@ -27,8 +27,8 @@ void main() { final speechConfigWithVoice = SpeechConfig(voiceName: 'Aoede'); expect(speechConfigWithVoice.toJson(), { 'voice_config': { - 'prebuilt_voice_config': {'voice_name': 'Aoede'} - } + 'prebuilt_voice_config': {'voice_name': 'Aoede'}, + }, }); final speechConfigWithoutVoice = SpeechConfig(); @@ -36,19 +36,19 @@ void main() { }); test('SpeechConfig with languageCode toJson() returns correct JSON', () { - final speechConfigWithLanguage = - SpeechConfig(voiceName: 'Aoede', languageCode: 'en-US'); + final speechConfigWithLanguage = SpeechConfig( + voiceName: 'Aoede', + languageCode: 'en-US', + ); expect(speechConfigWithLanguage.toJson(), { 'voice_config': { - 'prebuilt_voice_config': {'voice_name': 'Aoede'} + 'prebuilt_voice_config': {'voice_name': 'Aoede'}, }, 'language_code': 'en-US', }); final speechConfigLanguageOnly = SpeechConfig(languageCode: 'fr-FR'); - expect(speechConfigLanguageOnly.toJson(), { - 'language_code': 'fr-FR', - }); + expect(speechConfigLanguageOnly.toJson(), {'language_code': 'fr-FR'}); }); test('SpeechConfig.multiSpeaker toJson() returns correct JSON', () { @@ -68,16 +68,16 @@ void main() { { 'speaker': 'Joe', 'voice_config': { - 'prebuilt_voice_config': {'voice_name': 'Kore'} - } + 'prebuilt_voice_config': {'voice_name': 'Kore'}, + }, }, { 'speaker': 'Jane', 'voice_config': { - 'prebuilt_voice_config': {'voice_name': 'Puck'} - } - } - ] + 'prebuilt_voice_config': {'voice_name': 'Puck'}, + }, + }, + ], }, 'language_code': 'en-US', }); @@ -107,8 +107,8 @@ void main() { 'topK': 40, 'speechConfig': { 'voice_config': { - 'prebuilt_voice_config': {'voice_name': 'Charon'} - } + 'prebuilt_voice_config': {'voice_name': 'Charon'}, + }, }, 'responseModalities': ['TEXT', 'AUDIO'], 'mediaResolution': 'MEDIA_RESOLUTION_LOW', @@ -118,46 +118,48 @@ void main() { expect(liveGenerationConfigWithoutOptionals.toJson(), {}); }); - test('GenerationConfig with SpeechConfig toJson() returns correct JSON', - () { - final config = GenerationConfig( - speechConfig: SpeechConfig(voiceName: 'Aoede', languageCode: 'en-US'), - ); - - expect(config.toJson(), { - 'speechConfig': { - 'voice_config': { - 'prebuilt_voice_config': {'voice_name': 'Aoede'} + test( + 'GenerationConfig with SpeechConfig toJson() returns correct JSON', + () { + final config = GenerationConfig( + speechConfig: SpeechConfig(voiceName: 'Aoede', languageCode: 'en-US'), + ); + + expect(config.toJson(), { + 'speechConfig': { + 'voice_config': { + 'prebuilt_voice_config': {'voice_name': 'Aoede'}, + }, + 'language_code': 'en-US', }, - 'language_code': 'en-US', - } - }); - - final multiConfig = GenerationConfig( - speechConfig: SpeechConfig.multiSpeaker( - multiSpeakerVoiceConfig: MultiSpeakerVoiceConfig( - speakerVoiceConfigs: [ - SpeakerVoiceConfig(speaker: 'Joe', voiceName: 'Kore'), - ], + }); + + final multiConfig = GenerationConfig( + speechConfig: SpeechConfig.multiSpeaker( + multiSpeakerVoiceConfig: MultiSpeakerVoiceConfig( + speakerVoiceConfigs: [ + SpeakerVoiceConfig(speaker: 'Joe', voiceName: 'Kore'), + ], + ), ), - ), - ); - - expect(multiConfig.toJson(), { - 'speechConfig': { - 'multi_speaker_voice_config': { - 'speaker_voice_configs': [ - { - 'speaker': 'Joe', - 'voice_config': { - 'prebuilt_voice_config': {'voice_name': 'Kore'} - } - } - ] - } - } - }); - }); + ); + + expect(multiConfig.toJson(), { + 'speechConfig': { + 'multi_speaker_voice_config': { + 'speaker_voice_configs': [ + { + 'speaker': 'Joe', + 'voice_config': { + 'prebuilt_voice_config': {'voice_name': 'Kore'}, + }, + }, + ], + }, + }, + }); + }, + ); test('SessionResumptionConfig toJson() returns correct JSON', () { final resumableConfig = SessionResumptionConfig(); @@ -208,18 +210,13 @@ void main() { expect(message.toJson(), { 'realtime_input': { 'media_chunks': [ - { - 'mimeType': 'audio/pcm', - 'data': 'AQID', - } + {'mimeType': 'audio/pcm', 'data': 'AQID'}, ], }, }); final message2 = LiveClientRealtimeInput(); - expect(message2.toJson(), { - 'realtime_input': {}, - }); + expect(message2.toJson(), {'realtime_input': {}}); }); test('LiveClientContent toJson() returns correct JSON', () { @@ -231,20 +228,17 @@ void main() { { 'role': 'user', 'parts': [ - {'text': 'some test input'} - ] - } + {'text': 'some test input'}, + ], + }, ], 'turn_complete': true, - } + }, }); final message2 = LiveClientContent(); expect(message2.toJson(), { - 'client_content': { - 'turns': null, - 'turn_complete': null, - } + 'client_content': {'turns': null, 'turn_complete': null}, }); }); @@ -254,14 +248,14 @@ void main() { expect(message.toJson(), { 'toolResponse': { 'functionResponses': [ - {'name': 'test', 'response': {}} - ] - } + {'name': 'test', 'response': {}}, + ], + }, }); final message2 = LiveClientToolResponse(); expect(message2.toJson(), { - 'toolResponse': {'functionResponses': null} + 'toolResponse': {'functionResponses': null}, }); }); @@ -270,11 +264,11 @@ void main() { 'serverContent': { 'modelTurn': { 'parts': [ - {'text': 'Hello, world!'} - ] + {'text': 'Hello, world!'}, + ], }, 'turnComplete': true, - } + }, }; final response = parseServerResponse(jsonObject); expect(response.message, isA()); @@ -289,14 +283,14 @@ void main() { 'functionCalls': [ { 'name': 'test1', - 'args': {'foo1': 'bar1'} + 'args': {'foo1': 'bar1'}, }, { 'name': 'test2', - 'args': {'foo2': 'bar2'} - } - ] - } + 'args': {'foo2': 'bar2'}, + }, + ], + }, }; final response = parseServerResponse(jsonObject); expect(response.message, isA()); @@ -304,21 +298,25 @@ void main() { expect(toolCallMessage.functionCalls, isA>()); }); - test('parseServerMessage parses toolCallCancellation message correctly', - () { - final jsonObject = jsonDecode(''' + test( + 'parseServerMessage parses toolCallCancellation message correctly', + () { + final jsonObject = + jsonDecode(''' { "toolCallCancellation": { "ids": ["1", "2"] } } - ''') as Map; - final response = parseServerResponse(jsonObject); - expect(response.message, isA()); - final cancellationMessage = - response.message as LiveServerToolCallCancellation; - expect(cancellationMessage.functionIds, ['1', '2']); - }); + ''') + as Map; + final response = parseServerResponse(jsonObject); + expect(response.message, isA()); + final cancellationMessage = + response.message as LiveServerToolCallCancellation; + expect(cancellationMessage.functionIds, ['1', '2']); + }, + ); test('parseServerMessage parses setupComplete message correctly', () { final jsonObject = {'setupComplete': {}}; @@ -328,7 +326,7 @@ void main() { test('parseServerMessage parses goAway message correctly', () { final jsonObject = { - 'goAway': {'timeLeft': '50s'} + 'goAway': {'timeLeft': '50s'}, }; final response = parseServerResponse(jsonObject); expect(response.message, isA()); @@ -338,40 +336,47 @@ void main() { test('parseServerMessage throws VertexAIException for error message', () { final jsonObject = {'error': {}}; - expect(() => parseServerResponse(jsonObject), - throwsA(isA())); + expect( + () => parseServerResponse(jsonObject), + throwsA(isA()), + ); }); - test('parseServerMessage throws VertexAISdkException for unhandled format', - () { - final jsonObject = {'unknown': {}}; - expect(() => parseServerResponse(jsonObject), - throwsA(isA())); - }); + test( + 'parseServerMessage throws VertexAISdkException for unhandled format', + () { + final jsonObject = {'unknown': {}}; + expect( + () => parseServerResponse(jsonObject), + throwsA(isA()), + ); + }, + ); test( - 'LiveGenerationConfig with transcriptions toJson() returns correct JSON', - () { - final liveGenerationConfig = LiveGenerationConfig( - inputAudioTranscription: AudioTranscriptionConfig(), - outputAudioTranscription: AudioTranscriptionConfig(), - ); - // Explicitly, these two config should not exist in the toJson() - expect(liveGenerationConfig.toJson(), {}); - }); + 'LiveGenerationConfig with transcriptions toJson() returns correct JSON', + () { + final liveGenerationConfig = LiveGenerationConfig( + inputAudioTranscription: AudioTranscriptionConfig(), + outputAudioTranscription: AudioTranscriptionConfig(), + ); + // Explicitly, these two config should not exist in the toJson() + expect(liveGenerationConfig.toJson(), {}); + }, + ); test('parseServerMessage parses serverContent with transcriptions', () { final jsonObject = { 'serverContent': { 'modelTurn': { 'parts': [ - {'text': 'Hello, world!'} - ] + {'text': 'Hello, world!'}, + ], }, 'turnComplete': true, 'inputTranscription': {'text': 'input', 'finished': true}, - 'outputTranscription': {'text': 'output', 'finished': false} - } + 'outputTranscription': {'text': 'output', 'finished': false}, + }, }; final response = parseServerResponse(jsonObject); expect(response.message, isA()); @@ -401,9 +406,7 @@ void main() { }); final disabledConfig = ActivityDetectionConfig.disabled(); - expect(disabledConfig.toJson(), { - 'disabled': true, - }); + expect(disabledConfig.toJson(), {'disabled': true}); final emptyConfig = ActivityDetectionConfig(); expect(emptyConfig.toJson(), {}); @@ -426,30 +429,27 @@ void main() { }); test( - 'LiveGenerationConfig with realtimeInputConfig toJson() returns correct JSON', - () { - final liveGenerationConfig = LiveGenerationConfig( - realtimeInputConfig: RealtimeInputConfig( - automaticActivityDetection: ActivityDetectionConfig.disabled(), - ), - ); - // Explicitly, realtimeInputConfig should not exist in generation_config toJson() directly - expect(liveGenerationConfig.toJson(), {}); - }); + 'LiveGenerationConfig with realtimeInputConfig toJson() returns correct JSON', + () { + final liveGenerationConfig = LiveGenerationConfig( + realtimeInputConfig: RealtimeInputConfig( + automaticActivityDetection: ActivityDetectionConfig.disabled(), + ), + ); + // Explicitly, realtimeInputConfig should not exist in generation_config toJson() directly + expect(liveGenerationConfig.toJson(), {}); + }, + ); test('LiveClientRealtimeInput activityStart and activityEnd toJson()', () { final startMessage = LiveClientRealtimeInput.activityStart(); expect(startMessage.toJson(), { - 'realtime_input': { - 'activity_start': {}, - }, + 'realtime_input': {'activity_start': {}}, }); final stopMessage = LiveClientRealtimeInput.activityEnd(); expect(stopMessage.toJson(), { - 'realtime_input': { - 'activity_end': {}, - }, + 'realtime_input': {'activity_end': {}}, }); }); }); diff --git a/packages/firebase_ai/firebase_ai/test/mime_types_test.dart b/packages/firebase_ai/firebase_ai/test/mime_types_test.dart index e43119c89858..a83f56502523 100644 --- a/packages/firebase_ai/firebase_ai/test/mime_types_test.dart +++ b/packages/firebase_ai/firebase_ai/test/mime_types_test.dart @@ -17,14 +17,15 @@ import 'package:flutter_test/flutter_test.dart'; void main() { test('exposes supported MIME types by media category', () { - expect( - FirebaseAIMimeTypes.image, - const ['image/png', 'image/jpeg', 'image/webp'], - ); - expect( - FirebaseAIMimeTypes.document, - const ['application/pdf', 'text/plain'], - ); + expect(FirebaseAIMimeTypes.image, const [ + 'image/png', + 'image/jpeg', + 'image/webp', + ]); + expect(FirebaseAIMimeTypes.document, const [ + 'application/pdf', + 'text/plain', + ]); expect( FirebaseAIMimeTypes.all, containsAll([ diff --git a/packages/firebase_ai/firebase_ai/test/mock.dart b/packages/firebase_ai/firebase_ai/test/mock.dart index 99be2169b9c9..f30cfd99b050 100644 --- a/packages/firebase_ai/firebase_ai/test/mock.dart +++ b/packages/firebase_ai/firebase_ai/test/mock.dart @@ -43,7 +43,7 @@ class MockFirebaseAppAI implements TestFirebaseCoreHostApi { messagingSenderId: '123', ), pluginConstants: {}, - ) + ), ]; } diff --git a/packages/firebase_ai/firebase_ai/test/model_test.dart b/packages/firebase_ai/firebase_ai/test/model_test.dart index 668712db6ff4..19a6f0c2053e 100644 --- a/packages/firebase_ai/firebase_ai/test/model_test.dart +++ b/packages/firebase_ai/firebase_ai/test/model_test.dart @@ -40,14 +40,15 @@ void main() { }) { final client = ClientController(); final model = createModelWithClient( - useAgentPlatform: true, - app: app, - model: modelName, - client: client.client, - tools: tools, - toolConfig: toolConfig, - systemInstruction: systemInstruction, - location: 'us-central1'); + useAgentPlatform: true, + app: app, + model: modelName, + client: client.client, + tools: tools, + toolConfig: toolConfig, + systemInstruction: systemInstruction, + location: 'us-central1', + ); return (client, model); } @@ -181,9 +182,13 @@ void main() { final (client, model) = createModel(); const prompt = 'Some prompt'; await client.checkRequest( - () => model.generateContent([Content.text(prompt)], - generationConfig: GenerationConfig( - presencePenalty: 0.5, frequencyPenalty: 0.2)), + () => model.generateContent( + [Content.text(prompt)], + generationConfig: GenerationConfig( + presencePenalty: 0.5, + frequencyPenalty: 0.2, + ), + ), verifyRequest: (_, request) { expect(request['generationConfig'], { 'presencePenalty': 0.5, @@ -222,15 +227,13 @@ void main() { 'someFunction', 'Some cool function.', parameters: { - 'schema1': Schema.string(description: 'Some parameter.') + 'schema1': Schema.string(description: 'Some parameter.'), }, ), ]), ], toolConfig: ToolConfig( - functionCallingConfig: FunctionCallingConfig.any( - {'someFunction'}, - ), + functionCallingConfig: FunctionCallingConfig.any({'someFunction'}), ), ); const prompt = 'Some prompt'; @@ -248,11 +251,11 @@ void main() { 'properties': { 'schema1': { 'type': 'STRING', - 'description': 'Some parameter.' - } + 'description': 'Some parameter.', + }, }, - 'required': ['schema1'] - } + 'required': ['schema1'], + }, }, ], }, @@ -269,9 +272,7 @@ void main() { }); test('can pass a google search tool', () async { - final (client, model) = createModel( - tools: [Tool.googleSearch()], - ); + final (client, model) = createModel(tools: [Tool.googleSearch()]); const prompt = 'Some prompt'; await client.checkRequest( () => model.generateContent([Content.text(prompt)]), @@ -285,9 +286,7 @@ void main() { }); test('can pass a url context tool', () async { - final (client, model) = createModel( - tools: [Tool.urlContext()], - ); + final (client, model) = createModel(tools: [Tool.urlContext()]); const prompt = 'Some prompt'; await client.checkRequest( () => model.generateContent([Content.text(prompt)]), @@ -312,15 +311,15 @@ void main() { 'someFunction', 'Some cool function.', parameters: { - 'schema1': Schema.string(description: 'Some parameter.') + 'schema1': Schema.string(description: 'Some parameter.'), }, ), ]), ], toolConfig: ToolConfig( - functionCallingConfig: FunctionCallingConfig.any( - {'someFunction'}, - ), + functionCallingConfig: FunctionCallingConfig.any({ + 'someFunction', + }), ), ), verifyRequest: (_, request) { @@ -335,11 +334,11 @@ void main() { 'properties': { 'schema1': { 'type': 'STRING', - 'description': 'Some parameter.' - } + 'description': 'Some parameter.', + }, }, - 'required': ['schema1'] - } + 'required': ['schema1'], + }, }, ], }, diff --git a/packages/firebase_ai/firebase_ai/test/platform_header_helper_test.dart b/packages/firebase_ai/firebase_ai/test/platform_header_helper_test.dart index 442b56c95577..bf6b0d6ea911 100644 --- a/packages/firebase_ai/firebase_ai/test/platform_header_helper_test.dart +++ b/packages/firebase_ai/firebase_ai/test/platform_header_helper_test.dart @@ -29,16 +29,17 @@ void main() { group('getPlatformSecurityHeaders', () { test('returns headers from native plugin', () async { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(platformHeaderChannel, - (MethodCall methodCall) async { - if (methodCall.method == 'getPlatformHeaders') { - return { - 'X-Android-Package': 'com.example.test', - 'X-Android-Cert': 'AABBCCDD', - }; - } - return null; - }); + .setMockMethodCallHandler(platformHeaderChannel, ( + MethodCall methodCall, + ) async { + if (methodCall.method == 'getPlatformHeaders') { + return { + 'X-Android-Package': 'com.example.test', + 'X-Android-Cert': 'AABBCCDD', + }; + } + return null; + }); final headers = await getPlatformSecurityHeaders(); @@ -49,15 +50,16 @@ void main() { test('returns iOS bundle identifier from native plugin', () async { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(platformHeaderChannel, - (MethodCall methodCall) async { - if (methodCall.method == 'getPlatformHeaders') { - return { - 'x-ios-bundle-identifier': 'com.example.iosapp', - }; - } - return null; - }); + .setMockMethodCallHandler(platformHeaderChannel, ( + MethodCall methodCall, + ) async { + if (methodCall.method == 'getPlatformHeaders') { + return { + 'x-ios-bundle-identifier': 'com.example.iosapp', + }; + } + return null; + }); final headers = await getPlatformSecurityHeaders(); @@ -68,14 +70,15 @@ void main() { test('caches result across calls', () async { var callCount = 0; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(platformHeaderChannel, - (MethodCall methodCall) async { - callCount++; - return { - 'X-Android-Package': 'com.example.test', - 'X-Android-Cert': 'AABBCCDD', - }; - }); + .setMockMethodCallHandler(platformHeaderChannel, ( + MethodCall methodCall, + ) async { + callCount++; + return { + 'X-Android-Package': 'com.example.test', + 'X-Android-Cert': 'AABBCCDD', + }; + }); await getPlatformSecurityHeaders(); await getPlatformSecurityHeaders(); @@ -86,10 +89,11 @@ void main() { test('returns empty map when native plugin is not available', () async { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(platformHeaderChannel, - (MethodCall methodCall) async { - throw MissingPluginException(); - }); + .setMockMethodCallHandler(platformHeaderChannel, ( + MethodCall methodCall, + ) async { + throw MissingPluginException(); + }); final headers = await getPlatformSecurityHeaders(); @@ -98,10 +102,11 @@ void main() { test('returns empty map when native plugin returns null', () async { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(platformHeaderChannel, - (MethodCall methodCall) async { - return null; - }); + .setMockMethodCallHandler(platformHeaderChannel, ( + MethodCall methodCall, + ) async { + return null; + }); final headers = await getPlatformSecurityHeaders(); diff --git a/packages/firebase_ai/firebase_ai/test/response_parsing_test.dart b/packages/firebase_ai/firebase_ai/test/response_parsing_test.dart index 28868a31a496..c1edc0f1e11a 100644 --- a/packages/firebase_ai/firebase_ai/test/response_parsing_test.dart +++ b/packages/firebase_ai/firebase_ai/test/response_parsing_test.dart @@ -120,8 +120,8 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - AgentPlatformSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = AgentPlatformSerialization() + .parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( @@ -192,7 +192,8 @@ void main() { (e) => e.message, 'message', startsWith( - 'Enable Firebase AI Logic in your Firebase project by visiting the Firebase Console'), + 'Enable Firebase AI Logic in your Firebase project by visiting the Firebase Console', + ), ), ), ); @@ -306,8 +307,8 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - AgentPlatformSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = AgentPlatformSerialization() + .parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( @@ -440,8 +441,8 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - AgentPlatformSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = AgentPlatformSerialization() + .parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( @@ -575,8 +576,8 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - AgentPlatformSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = AgentPlatformSerialization() + .parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( @@ -657,31 +658,36 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - AgentPlatformSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = AgentPlatformSerialization() + .parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( GenerateContentResponse([ Candidate( - Content(null, []), - [ - SafetyRating( - HarmCategory.sexuallyExplicit, - HarmProbability.negligible, - ), - SafetyRating( - HarmCategory.hateSpeech, HarmProbability.negligible), - SafetyRating( - HarmCategory.harassment, HarmProbability.negligible), - SafetyRating( - HarmCategory.dangerousContent, - HarmProbability.negligible, - ), - ], - CitationMetadata([]), - FinishReason.safety, - null), + Content(null, []), + [ + SafetyRating( + HarmCategory.sexuallyExplicit, + HarmProbability.negligible, + ), + SafetyRating( + HarmCategory.hateSpeech, + HarmProbability.negligible, + ), + SafetyRating( + HarmCategory.harassment, + HarmProbability.negligible, + ), + SafetyRating( + HarmCategory.dangerousContent, + HarmProbability.negligible, + ), + ], + CitationMetadata([]), + FinishReason.safety, + null, + ), ], null), ), ); @@ -724,38 +730,61 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - AgentPlatformSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = AgentPlatformSerialization() + .parseGenerateContentResponse(decoded); expect( - generateContentResponse.text, 'Here is a description of the image:'); + generateContentResponse.text, + 'Here is a description of the image:', + ); expect(generateContentResponse.usageMetadata?.totalTokenCount, 1913); expect(generateContentResponse.usageMetadata?.toolUsePromptTokenCount, 5); expect( - generateContentResponse.usageMetadata?.cachedContentTokenCount, 10); + generateContentResponse.usageMetadata?.cachedContentTokenCount, + 10, + ); expect( - generateContentResponse - .usageMetadata?.cacheTokensDetails?.first.modality, - ContentModality.text); + generateContentResponse + .usageMetadata + ?.cacheTokensDetails + ?.first + .modality, + ContentModality.text, + ); expect( - generateContentResponse - .usageMetadata?.cacheTokensDetails?.first.tokenCount, - 10); + generateContentResponse + .usageMetadata + ?.cacheTokensDetails + ?.first + .tokenCount, + 10, + ); expect( - generateContentResponse - .usageMetadata?.promptTokensDetails?[1].modality, - ContentModality.image); + generateContentResponse.usageMetadata?.promptTokensDetails?[1].modality, + ContentModality.image, + ); expect( - generateContentResponse - .usageMetadata?.promptTokensDetails?[1].tokenCount, - 1806); + generateContentResponse + .usageMetadata + ?.promptTokensDetails?[1] + .tokenCount, + 1806, + ); expect( - generateContentResponse - .usageMetadata?.candidatesTokensDetails?.first.modality, - ContentModality.text); + generateContentResponse + .usageMetadata + ?.candidatesTokensDetails + ?.first + .modality, + ContentModality.text, + ); expect( - generateContentResponse - .usageMetadata?.candidatesTokensDetails?.first.tokenCount, - 76); + generateContentResponse + .usageMetadata + ?.candidatesTokensDetails + ?.first + .tokenCount, + 76, + ); }); test('countTokens with modality fields returned', () async { @@ -773,11 +802,13 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final countTokensResponse = - AgentPlatformSerialization().parseCountTokensResponse(decoded); + final countTokensResponse = AgentPlatformSerialization() + .parseCountTokensResponse(decoded); expect(countTokensResponse.totalTokens, 1837); - expect(countTokensResponse.promptTokensDetails?.first.modality, - ContentModality.image); + expect( + countTokensResponse.promptTokensDetails?.first.modality, + ContentModality.image, + ); expect(countTokensResponse.promptTokensDetails?.first.tokenCount, 1806); }); @@ -807,11 +838,13 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - AgentPlatformSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = AgentPlatformSerialization() + .parseGenerateContentResponse(decoded); expect(generateContentResponse.text, 'Initial text And more text'); - expect(generateContentResponse.candidates.single.text, - 'Initial text And more text'); + expect( + generateContentResponse.candidates.single.text, + 'Initial text And more text', + ); }); test('url context', () { @@ -892,16 +925,20 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - AgentPlatformSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = AgentPlatformSerialization() + .parseGenerateContentResponse(decoded); final candidate = generateContentResponse.candidates.first; final urlContextMetadata = candidate.urlContextMetadata; expect(urlContextMetadata, isNotNull); expect(urlContextMetadata!.urlMetadata, hasLength(1)); - expect(urlContextMetadata.urlMetadata.first.retrievedUrl, - Uri.parse('https://berkshirehathaway.com')); - expect(urlContextMetadata.urlMetadata.first.urlRetrievalStatus, - UrlRetrievalStatus.success); + expect( + urlContextMetadata.urlMetadata.first.retrievedUrl, + Uri.parse('https://berkshirehathaway.com'), + ); + expect( + urlContextMetadata.urlMetadata.first.urlRetrievalStatus, + UrlRetrievalStatus.success, + ); final usageMetadata = generateContentResponse.usageMetadata; expect(usageMetadata, isNotNull); expect(usageMetadata!.toolUsePromptTokenCount, 34); @@ -1033,20 +1070,28 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - AgentPlatformSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = AgentPlatformSerialization() + .parseGenerateContentResponse(decoded); final urlContextMetadata = generateContentResponse.candidates.first.urlContextMetadata; expect(urlContextMetadata, isNotNull); expect(urlContextMetadata!.urlMetadata, hasLength(3)); - expect(urlContextMetadata.urlMetadata[2].retrievedUrl, - Uri.parse('https://a-completely-non-existent-url-for-testing.org')); - expect(urlContextMetadata.urlMetadata[2].urlRetrievalStatus, - UrlRetrievalStatus.error); - expect(urlContextMetadata.urlMetadata[1].retrievedUrl, - Uri.parse('https://ai.google.dev')); - expect(urlContextMetadata.urlMetadata[1].urlRetrievalStatus, - UrlRetrievalStatus.success); + expect( + urlContextMetadata.urlMetadata[2].retrievedUrl, + Uri.parse('https://a-completely-non-existent-url-for-testing.org'), + ); + expect( + urlContextMetadata.urlMetadata[2].urlRetrievalStatus, + UrlRetrievalStatus.error, + ); + expect( + urlContextMetadata.urlMetadata[1].retrievedUrl, + Uri.parse('https://ai.google.dev'), + ); + expect( + urlContextMetadata.urlMetadata[1].urlRetrievalStatus, + UrlRetrievalStatus.success, + ); }); test('url context missing retrievedUrl', () { @@ -1108,15 +1153,17 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - AgentPlatformSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = AgentPlatformSerialization() + .parseGenerateContentResponse(decoded); final urlContextMetadata = generateContentResponse.candidates.first.urlContextMetadata; expect(urlContextMetadata, isNotNull); expect(urlContextMetadata!.urlMetadata, hasLength(1)); expect(urlContextMetadata.urlMetadata[0].retrievedUrl, isNull); - expect(urlContextMetadata.urlMetadata[0].urlRetrievalStatus, - UrlRetrievalStatus.error); + expect( + urlContextMetadata.urlMetadata[0].urlRetrievalStatus, + UrlRetrievalStatus.error, + ); }); test('parses json with google maps grounding chunk', () { @@ -1125,8 +1172,8 @@ void main() { { 'content': { 'parts': [ - {'text': 'This is a maps response.'} - ] + {'text': 'This is a maps response.'}, + ], }, 'finishReason': 'STOP', 'groundingMetadata': { @@ -1136,12 +1183,12 @@ void main() { 'uri': 'https://maps.google.com/?cid=123', 'title': 'Google HQ', 'placeId': 'ChIJS5dFe_cZzosR26ZvwqWaMAM', - } - } + }, + }, ], - } - } - ] + }, + }, + ], }; final response = AgentPlatformSerialization() @@ -1206,30 +1253,22 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - AgentPlatformSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = AgentPlatformSerialization() + .parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( GenerateContentResponse( [ Candidate( - Content.model([ - const TextPart('Some text'), - ]), + Content.model([const TextPart('Some text')]), [ - SafetyRating( - HarmCategory.harassment, - HarmProbability.medium, - ), + SafetyRating(HarmCategory.harassment, HarmProbability.medium), SafetyRating( HarmCategory.dangerousContent, HarmProbability.unknown, ), - SafetyRating( - HarmCategory.unknown, - HarmProbability.high, - ), + SafetyRating(HarmCategory.unknown, HarmProbability.high), ], null, FinishReason.stop, @@ -1237,18 +1276,12 @@ void main() { ), ], PromptFeedback(null, null, [ - SafetyRating( - HarmCategory.harassment, - HarmProbability.medium, - ), + SafetyRating(HarmCategory.harassment, HarmProbability.medium), SafetyRating( HarmCategory.dangerousContent, HarmProbability.unknown, ), - SafetyRating( - HarmCategory.unknown, - HarmProbability.high, - ), + SafetyRating(HarmCategory.unknown, HarmProbability.high), ]), ), ), @@ -1277,25 +1310,20 @@ void main() { } '''; final decoded = jsonDecode(response) as Object; - final generateContentResponse = - AgentPlatformSerialization().parseGenerateContentResponse(decoded); + final generateContentResponse = AgentPlatformSerialization() + .parseGenerateContentResponse(decoded); expect( generateContentResponse, matchesGenerateContentResponse( - GenerateContentResponse( - [ - Candidate( - Content.model([ - const FunctionCall('current_time', {}), - ]), - null, - null, - FinishReason.stop, - null, - ), - ], - null, - ), + GenerateContentResponse([ + Candidate( + Content.model([const FunctionCall('current_time', {})]), + null, + null, + FinishReason.stop, + null, + ), + ], null), ), ); }); @@ -1335,12 +1363,14 @@ void main() { ), ); expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(decoded), - expectedThrow); + () => + AgentPlatformSerialization().parseGenerateContentResponse(decoded), + expectedThrow, + ); expect( - () => AgentPlatformSerialization().parseCountTokensResponse(decoded), - expectedThrow); + () => AgentPlatformSerialization().parseCountTokensResponse(decoded), + expectedThrow, + ); }); test('for unsupported user location', () async { @@ -1368,12 +1398,14 @@ void main() { ), ); expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(decoded), - expectedThrow); + () => + AgentPlatformSerialization().parseGenerateContentResponse(decoded), + expectedThrow, + ); expect( - () => AgentPlatformSerialization().parseCountTokensResponse(decoded), - expectedThrow); + () => AgentPlatformSerialization().parseCountTokensResponse(decoded), + expectedThrow, + ); }); test('for general server errors', () async { @@ -1404,12 +1436,14 @@ void main() { ), ); expect( - () => AgentPlatformSerialization() - .parseGenerateContentResponse(decoded), - expectedThrow); + () => + AgentPlatformSerialization().parseGenerateContentResponse(decoded), + expectedThrow, + ); expect( - () => AgentPlatformSerialization().parseCountTokensResponse(decoded), - expectedThrow); + () => AgentPlatformSerialization().parseCountTokensResponse(decoded), + expectedThrow, + ); }); }); } diff --git a/packages/firebase_ai/firebase_ai/test/schema_test.dart b/packages/firebase_ai/firebase_ai/test/schema_test.dart index 724c803d3080..0f6f52b26fe9 100644 --- a/packages/firebase_ai/firebase_ai/test/schema_test.dart +++ b/packages/firebase_ai/firebase_ai/test/schema_test.dart @@ -20,7 +20,10 @@ void main() { // Test basic constructors and toJson() for primitive types test('Schema.boolean', () { final schema = Schema.boolean( - description: 'A boolean value', nullable: true, title: 'Is Active'); + description: 'A boolean value', + nullable: true, + title: 'Is Active', + ); expect(schema.type, SchemaType.boolean); expect(schema.description, 'A boolean value'); expect(schema.nullable, true); @@ -35,7 +38,11 @@ void main() { test('Schema.integer', () { final schema = Schema.integer( - format: 'int32', minimum: 0, maximum: 100, title: 'Count'); + format: 'int32', + minimum: 0, + maximum: 100, + title: 'Count', + ); expect(schema.type, SchemaType.integer); expect(schema.format, 'int32'); expect(schema.minimum, 0); @@ -52,11 +59,12 @@ void main() { test('Schema.number', () { final schema = Schema.number( - format: 'double', - nullable: false, - minimum: 0.5, - maximum: 99.5, - title: 'Percentage'); + format: 'double', + nullable: false, + minimum: 0.5, + maximum: 99.5, + title: 'Percentage', + ); expect(schema.type, SchemaType.number); expect(schema.format, 'double'); expect(schema.nullable, false); @@ -81,8 +89,10 @@ void main() { }); test('Schema.enumString', () { - final schema = - Schema.enumString(enumValues: ['value1', 'value2'], title: 'Status'); + final schema = Schema.enumString( + enumValues: ['value1', 'value2'], + title: 'Status', + ); expect(schema.type, SchemaType.string); expect(schema.format, 'enum'); expect(schema.enumValues, ['value1', 'value2']); @@ -99,7 +109,11 @@ void main() { test('Schema.array', () { final itemSchema = Schema.string(); final schema = Schema.array( - items: itemSchema, minItems: 1, maxItems: 5, title: 'Tags'); + items: itemSchema, + minItems: 1, + maxItems: 5, + title: 'Tags', + ); expect(schema.type, SchemaType.array); expect(schema.items, itemSchema); expect(schema.minItems, 1); @@ -148,18 +162,13 @@ void main() { }); test('JSONSchema.object with defs', () { - final properties = { - 'metadata': JSONSchema.ref('#/metadata_schema'), - }; + final properties = {'metadata': JSONSchema.ref('#/metadata_schema')}; final defs = { - 'metadata_schema': JSONSchema.object(properties: { - 'id': JSONSchema.string(), - }) + 'metadata_schema': JSONSchema.object( + properties: {'id': JSONSchema.string()}, + ), }; - final schema = JSONSchema.object( - properties: properties, - defs: defs, - ); + final schema = JSONSchema.object(properties: properties, defs: defs); expect(schema.type, SchemaType.object); expect(schema.properties, properties); expect(schema.defs, defs); @@ -176,16 +185,13 @@ void main() { 'id': {'type': 'string'}, }, 'required': ['id'], - } - } + }, + }, }); }); test('Schema.object with empty optionalProperties', () { - final properties = { - 'name': Schema.string(), - 'age': Schema.integer(), - }; + final properties = {'name': Schema.string(), 'age': Schema.integer()}; final schema = Schema.object( properties: properties, // No optionalProperties, so all are required @@ -203,10 +209,7 @@ void main() { }); test('Schema.object with all properties optional', () { - final properties = { - 'name': Schema.string(), - 'age': Schema.integer(), - }; + final properties = {'name': Schema.string(), 'age': Schema.integer()}; final schema = Schema.object( properties: properties, optionalProperties: ['name', 'age'], @@ -243,16 +246,16 @@ void main() { }); test('Schema.anyOf with complex types', () { - final userSchema = Schema.object(properties: { - 'id': Schema.integer(), - 'username': Schema.string(), - }, optionalProperties: [ - 'username' - ]); - final errorSchema = Schema.object(properties: { - 'errorCode': Schema.integer(), - 'errorMessage': Schema.string(), - }); + final userSchema = Schema.object( + properties: {'id': Schema.integer(), 'username': Schema.string()}, + optionalProperties: ['username'], + ); + final errorSchema = Schema.object( + properties: { + 'errorCode': Schema.integer(), + 'errorMessage': Schema.string(), + }, + ); final schema = Schema.anyOf(schemas: [userSchema, errorSchema]); expect(schema.type, SchemaType.anyOf); @@ -288,8 +291,10 @@ void main() { expect(SchemaType.array.toJson(), 'ARRAY'); expect(SchemaType.object.toJson(), 'OBJECT'); expect(SchemaType.ref.toJson(), 'null'); - expect(SchemaType.anyOf.toJson(), - 'null'); // As per implementation, 'null' string for anyOf + expect( + SchemaType.anyOf.toJson(), + 'null', + ); // As per implementation, 'null' string for anyOf }); // Test JSONSchema.ref @@ -297,9 +302,7 @@ void main() { final schema = JSONSchema.ref('#/components/schemas/User'); expect(schema.type, SchemaType.ref); expect(schema.ref, '#/components/schemas/User'); - expect(schema.toJson(), { - r'$ref': '#/components/schemas/User', - }); + expect(schema.toJson(), {r'$ref': '#/components/schemas/User'}); }); test('JSONSchema.toJson handles nullable correctly', () { @@ -309,9 +312,7 @@ void main() { }); final stringSchema = JSONSchema.string(nullable: false); - expect(stringSchema.toJson(), { - 'type': 'string', - }); + expect(stringSchema.toJson(), {'type': 'string'}); }); // Test edge cases diff --git a/packages/firebase_ai/firebase_ai/test/server_template_test.dart b/packages/firebase_ai/firebase_ai/test/server_template_test.dart index 19f1649bc3f8..0ef9cb805d16 100644 --- a/packages/firebase_ai/firebase_ai/test/server_template_test.dart +++ b/packages/firebase_ai/firebase_ai/test/server_template_test.dart @@ -49,8 +49,10 @@ void main() { const templateId = 'my-template'; const location = 'us-central1'; - TemplateGenerativeModel createModel(http.Client client, - {bool useAgentPlatform = true}) { + TemplateGenerativeModel createModel( + http.Client client, { + bool useAgentPlatform = true, + }) { // ignore: invalid_use_of_internal_member return createTestTemplateGenerativeModel( app: app, @@ -63,16 +65,23 @@ void main() { test('generateContent can make successful request', () async { final mockHttp = MockClient((request) async { final body = jsonDecode(request.body) as Map; - expect(request.url.path, - endsWith('/templates/$templateId:templateGenerateContent')); + expect( + request.url.path, + endsWith('/templates/$templateId:templateGenerateContent'), + ); expect(body['inputs'], {'prompt': 'Some prompt'}); - return http.Response(jsonEncode(_arbitraryGenerateContentResponse), 200, - headers: {'content-type': 'application/json'}); + return http.Response( + jsonEncode(_arbitraryGenerateContentResponse), + 200, + headers: {'content-type': 'application/json'}, + ); }); final model = createModel(mockHttp); - final response = await model - .generateContent(templateId, inputs: {'prompt': 'Some prompt'}); + final response = await model.generateContent( + templateId, + inputs: {'prompt': 'Some prompt'}, + ); expect(response.text, 'Some response'); }); @@ -86,8 +95,11 @@ void main() { 'contents': base64Encode([1, 2, 3]), }, }); - return http.Response(jsonEncode(_arbitraryGenerateContentResponse), 200, - headers: {'content-type': 'application/json'}); + return http.Response( + jsonEncode(_arbitraryGenerateContentResponse), + 200, + headers: {'content-type': 'application/json'}, + ); }); final model = createModel(mockHttp); @@ -103,74 +115,59 @@ void main() { expect(response.text, 'Some response'); }); - test('generateContent with TemplateToolConfig passes retrievalConfig', - () async { - final mockHttp = MockClient((request) async { - final body = jsonDecode(request.body) as Map; - expect(request.url.path, - endsWith('/templates/$templateId:templateGenerateContent')); - expect(body['inputs'], {'prompt': 'Some prompt'}); - expect(body['toolConfig'], { - 'retrievalConfig': { - 'latLng': {'latitude': 1.0, 'longitude': 2.0}, - 'languageCode': 'en' - } + test( + 'generateContent with TemplateToolConfig passes retrievalConfig', + () async { + final mockHttp = MockClient((request) async { + final body = jsonDecode(request.body) as Map; + expect( + request.url.path, + endsWith('/templates/$templateId:templateGenerateContent'), + ); + expect(body['inputs'], {'prompt': 'Some prompt'}); + expect(body['toolConfig'], { + 'retrievalConfig': { + 'latLng': {'latitude': 1.0, 'longitude': 2.0}, + 'languageCode': 'en', + }, + }); + return http.Response( + jsonEncode(_arbitraryGenerateContentResponse), + 200, + headers: {'content-type': 'application/json'}, + ); }); - return http.Response(jsonEncode(_arbitraryGenerateContentResponse), 200, - headers: {'content-type': 'application/json'}); - }); - final model = createModel(mockHttp); - final response = await model.generateContent( - templateId, - inputs: {'prompt': 'Some prompt'}, - toolConfig: TemplateToolConfig( - retrievalConfig: RetrievalConfig( - latLng: LatLng(latitude: 1, longitude: 2), - languageCode: 'en', + final model = createModel(mockHttp); + final response = await model.generateContent( + templateId, + inputs: {'prompt': 'Some prompt'}, + toolConfig: TemplateToolConfig( + retrievalConfig: RetrievalConfig( + latLng: LatLng(latitude: 1, longitude: 2), + languageCode: 'en', + ), ), - ), - ); - expect(response.text, 'Some response'); - }); + ); + expect(response.text, 'Some response'); + }, + ); test('generateContentStream can make successful request', () async { final mockHttp = MockClient((request) async { final body = jsonDecode(request.body) as Map; - expect(request.url.path, - endsWith('/templates/$templateId:templateStreamGenerateContent')); - expect(body['inputs'], {'prompt': 'Some prompt'}); - final responsePayload = jsonEncode(_arbitraryGenerateContentResponse); - final stream = Stream.value(utf8.encode('data: $responsePayload')); - final streamedResponse = http.StreamedResponse(stream, 200, - headers: {'content-type': 'application/json'}); - return http.Response.fromStream(streamedResponse); - }); - - final model = createModel(mockHttp); - final responseStream = model - .generateContentStream(templateId, inputs: {'prompt': 'Some prompt'}); - final response = await responseStream.first; - expect(response.text, 'Some response'); - }); - - test('generateContentStream with TemplateToolConfig passes retrievalConfig', - () async { - final mockHttp = MockClient((request) async { - final body = jsonDecode(request.body) as Map; - expect(request.url.path, - endsWith('/templates/$templateId:templateStreamGenerateContent')); + expect( + request.url.path, + endsWith('/templates/$templateId:templateStreamGenerateContent'), + ); expect(body['inputs'], {'prompt': 'Some prompt'}); - expect(body['toolConfig'], { - 'retrievalConfig': { - 'latLng': {'latitude': 1.0, 'longitude': 2.0}, - 'languageCode': 'en' - } - }); final responsePayload = jsonEncode(_arbitraryGenerateContentResponse); final stream = Stream.value(utf8.encode('data: $responsePayload')); - final streamedResponse = http.StreamedResponse(stream, 200, - headers: {'content-type': 'application/json'}); + final streamedResponse = http.StreamedResponse( + stream, + 200, + headers: {'content-type': 'application/json'}, + ); return http.Response.fromStream(streamedResponse); }); @@ -178,15 +175,51 @@ void main() { final responseStream = model.generateContentStream( templateId, inputs: {'prompt': 'Some prompt'}, - toolConfig: TemplateToolConfig( - retrievalConfig: RetrievalConfig( - latLng: LatLng(latitude: 1, longitude: 2), - languageCode: 'en', - ), - ), ); final response = await responseStream.first; expect(response.text, 'Some response'); }); + + test( + 'generateContentStream with TemplateToolConfig passes retrievalConfig', + () async { + final mockHttp = MockClient((request) async { + final body = jsonDecode(request.body) as Map; + expect( + request.url.path, + endsWith('/templates/$templateId:templateStreamGenerateContent'), + ); + expect(body['inputs'], {'prompt': 'Some prompt'}); + expect(body['toolConfig'], { + 'retrievalConfig': { + 'latLng': {'latitude': 1.0, 'longitude': 2.0}, + 'languageCode': 'en', + }, + }); + final responsePayload = jsonEncode(_arbitraryGenerateContentResponse); + final stream = Stream.value(utf8.encode('data: $responsePayload')); + final streamedResponse = http.StreamedResponse( + stream, + 200, + headers: {'content-type': 'application/json'}, + ); + return http.Response.fromStream(streamedResponse); + }); + + final model = createModel(mockHttp); + final responseStream = model.generateContentStream( + templateId, + inputs: {'prompt': 'Some prompt'}, + toolConfig: TemplateToolConfig( + retrievalConfig: RetrievalConfig( + latLng: LatLng(latitude: 1, longitude: 2), + languageCode: 'en', + ), + ), + ); + final response = await responseStream.first; + expect(response.text, 'Some response'); + }, + ); }); } diff --git a/packages/firebase_ai/firebase_ai/test/tool_test.dart b/packages/firebase_ai/firebase_ai/test/tool_test.dart index ff5b06152612..909bf7d4c4e6 100644 --- a/packages/firebase_ai/firebase_ai/test/tool_test.dart +++ b/packages/firebase_ai/firebase_ai/test/tool_test.dart @@ -44,8 +44,10 @@ void main() { // Verify properties expect(autoDeclaration.name, 'greetUser'); - expect(autoDeclaration.description, - 'Greets a user with their name and calculates age plus ten.'); + expect( + autoDeclaration.description, + 'Greets a user with their name and calculates age plus ten.', + ); expect(autoDeclaration.callable, myFunction); // Verify toJson output (should match FunctionDeclaration's toJson) @@ -64,16 +66,20 @@ void main() { }); // Optionally, test invoking the callable directly (simulating client execution) - final result = - await autoDeclaration.callable({'name': 'Alice', 'age': 30}); + final result = await autoDeclaration.callable({ + 'name': 'Alice', + 'age': 30, + }); expect(result, {'result': 'Hello, Alice!', 'age_plus_ten': 40}); }); test('AutoFunctionDeclaration with optional parameters', () async { Future> optionalParamFunction( - Map args) async { - final greeting = - args['name'] != null ? 'Hello, ${args['name']}!' : 'Hello!'; + Map args, + ) async { + final greeting = args['name'] != null + ? 'Hello, ${args['name']}!' + : 'Hello!'; return {'message': greeting}; } @@ -114,9 +120,7 @@ void main() { }); test('AutoFunctionDeclaration with JSONSchema', () async { - final parametersSchema = { - 'count': JSONSchema.integer(), - }; + final parametersSchema = {'count': JSONSchema.integer()}; final autoDeclaration = AutoFunctionDeclaration( name: 'testSchema', @@ -139,9 +143,7 @@ void main() { }); test('FunctionDeclaration with JSONSchema', () { - final parametersSchema = { - 'count': JSONSchema.integer(), - }; + final parametersSchema = {'count': JSONSchema.integer()}; final declaration = FunctionDeclaration( 'testSchema', @@ -163,32 +165,31 @@ void main() { }); test( - 'FunctionDeclaration mixing Schema and JSONSchema throws TypeError on toJson', - () { - final mixedParametersSchema = { - 'count': Schema.integer(), - 'mixed': JSONSchema.string(), - }; + 'FunctionDeclaration mixing Schema and JSONSchema throws TypeError on toJson', + () { + final mixedParametersSchema = { + 'count': Schema.integer(), + 'mixed': JSONSchema.string(), + }; - final declaration = FunctionDeclaration( - 'testMixedSchema', - 'Tests mixed schemas.', - parameters: mixedParametersSchema, - ); + final declaration = FunctionDeclaration( + 'testMixedSchema', + 'Tests mixed schemas.', + parameters: mixedParametersSchema, + ); - expect(declaration.toJson, throwsA(isA())); - }); + expect(declaration.toJson, throwsA(isA())); + }, + ); test('FunctionDeclaration with JSONSchema defs and ref', () { final parametersSchema = { 'metadataContainer': JSONSchema.object( - properties: { - 'metadata': JSONSchema.ref('#/metadata_schema'), - }, + properties: {'metadata': JSONSchema.ref('#/metadata_schema')}, defs: { - 'metadata_schema': JSONSchema.object(properties: { - 'id': JSONSchema.string(), - }), + 'metadata_schema': JSONSchema.object( + properties: {'id': JSONSchema.string()}, + ), }, ), }; @@ -218,9 +219,9 @@ void main() { 'id': {'type': 'string'}, }, 'required': ['id'], - } - } - } + }, + }, + }, }, 'required': ['metadataContainer'], }, @@ -283,8 +284,8 @@ void main() { }, 'required': ['param1'], }, - } - ] + }, + ], }); }); @@ -292,34 +293,26 @@ void main() { test('Tool.googleSearch()', () { final tool = Tool.googleSearch(); - expect(tool.toJson(), { - 'googleSearch': {}, - }); + expect(tool.toJson(), {'googleSearch': {}}); }); // Test Tool.codeExecution() test('Tool.codeExecution()', () { final tool = Tool.codeExecution(); - expect(tool.toJson(), { - 'codeExecution': {}, - }); + expect(tool.toJson(), {'codeExecution': {}}); }); // Test Tool.urlContext() test('Tool.urlContext()', () { final tool = Tool.urlContext(); - expect(tool.toJson(), { - 'urlContext': {}, - }); + expect(tool.toJson(), {'urlContext': {}}); }); // Test Tool.googleMaps() test('Tool.googleMaps()', () { final tool = Tool.googleMaps(); - expect(tool.toJson(), { - 'googleMaps': {}, - }); + expect(tool.toJson(), {'googleMaps': {}}); }); // Test ToolConfig @@ -370,10 +363,11 @@ void main() { }); test('RetrievalConfig.toJson() with partial fields', () { - final config1 = - RetrievalConfig(latLng: LatLng(latitude: 1.2, longitude: 2.1)); + final config1 = RetrievalConfig( + latLng: LatLng(latitude: 1.2, longitude: 2.1), + ); expect(config1.toJson(), { - 'latLng': {'latitude': 1.2, 'longitude': 2.1} + 'latLng': {'latitude': 1.2, 'longitude': 2.1}, }); final config2 = RetrievalConfig(languageCode: 'fr'); diff --git a/packages/firebase_ai/firebase_ai/test/utils/matchers.dart b/packages/firebase_ai/firebase_ai/test/utils/matchers.dart index ab44da91d5d0..6615271f6795 100644 --- a/packages/firebase_ai/firebase_ai/test/utils/matchers.dart +++ b/packages/firebase_ai/firebase_ai/test/utils/matchers.dart @@ -16,44 +16,51 @@ import 'package:http/http.dart' as http; import 'package:matcher/matcher.dart'; Matcher matchesPart(Part part) => switch (part) { - TextPart(text: final text) => - isA().having((p) => p.text, 'text', text), - InlineDataPart(mimeType: final mimeType, bytes: final bytes) => - isA() - .having((p) => p.mimeType, 'mimeType', mimeType) - .having((p) => p.bytes, 'bytes', bytes), - FileData(mimeType: final mimeType, fileUri: final fileUri) => - isA() - .having((p) => p.mimeType, 'mimeType', mimeType) - .having((p) => p.fileUri, 'fileUri', fileUri), - FunctionCall(name: final name, args: final args) => isA() - .having((p) => p.name, 'name', name) - .having((p) => p.args, 'args', args), - FunctionResponse(name: final name, response: final response) => - isA() - .having((p) => p.name, 'name', name) - .having((p) => p.response, 'args', response), - CodeExecutionResultPart(outcome: final outcome, output: final output) => - isA() - .having((p) => p.outcome, 'outcome', outcome) - .having((p) => p.output, 'output', output), - ExecutableCodePart(language: final language, code: final code) => - isA() - .having((p) => p.language, 'language', language) - .having((p) => p.code, 'code', code), - UnknownPart(data: final data) => - isA().having((p) => p.data, 'data', data), - }; + TextPart(text: final text) => isA().having( + (p) => p.text, + 'text', + text, + ), + InlineDataPart(mimeType: final mimeType, bytes: final bytes) => + isA() + .having((p) => p.mimeType, 'mimeType', mimeType) + .having((p) => p.bytes, 'bytes', bytes), + FileData(mimeType: final mimeType, fileUri: final fileUri) => + isA() + .having((p) => p.mimeType, 'mimeType', mimeType) + .having((p) => p.fileUri, 'fileUri', fileUri), + FunctionCall(name: final name, args: final args) => + isA() + .having((p) => p.name, 'name', name) + .having((p) => p.args, 'args', args), + FunctionResponse(name: final name, response: final response) => + isA() + .having((p) => p.name, 'name', name) + .having((p) => p.response, 'args', response), + CodeExecutionResultPart(outcome: final outcome, output: final output) => + isA() + .having((p) => p.outcome, 'outcome', outcome) + .having((p) => p.output, 'output', output), + ExecutableCodePart(language: final language, code: final code) => + isA() + .having((p) => p.language, 'language', language) + .having((p) => p.code, 'code', code), + UnknownPart(data: final data) => isA().having( + (p) => p.data, + 'data', + data, + ), +}; Matcher matchesContent(Content content) => isA() .having((c) => c.role, 'role', content.role) .having((c) => c.parts, 'parts', content.parts.map(matchesPart).toList()); Matcher matchesCandidate(Candidate candidate) => isA().having( - (c) => c.content, - 'content', - matchesContent(candidate.content), - ); + (c) => c.content, + 'content', + matchesContent(candidate.content), +); Matcher matchesGenerateContentResponse(GenerateContentResponse response) => isA() @@ -70,9 +77,7 @@ Matcher matchesGenerateContentResponse(GenerateContentResponse response) => : matchesPromptFeedback(response.promptFeedback!), ); -Matcher matchesPromptFeedback( - PromptFeedback promptFeedback, -) => +Matcher matchesPromptFeedback(PromptFeedback promptFeedback) => isA() .having((p) => p.blockReason, 'blockReason', promptFeedback.blockReason) .having( @@ -84,7 +89,8 @@ Matcher matchesPromptFeedback( (p) => p.safetyRatings, 'safetyRatings', unorderedMatches( - promptFeedback.safetyRatings.map(matchesSafetyRating)), + promptFeedback.safetyRatings.map(matchesSafetyRating), + ), ); Matcher matchesSafetyRating(SafetyRating safetyRating) => isA() diff --git a/packages/firebase_analytics/firebase_analytics/example/integration_test/e2e_test.dart b/packages/firebase_analytics/firebase_analytics/example/integration_test/e2e_test.dart index c8eb946c6e8c..53bcd59a983a 100644 --- a/packages/firebase_analytics/firebase_analytics/example/integration_test/e2e_test.dart +++ b/packages/firebase_analytics/firebase_analytics/example/integration_test/e2e_test.dart @@ -38,28 +38,24 @@ void main() { }); // getSessionId has to be first, else Android returns null - test( - 'getSessionId', - () async { - if (kIsWeb) { - await expectLater( - FirebaseAnalytics.instance.getSessionId(), - throwsA(isA()), - ); - } else { - await expectLater( - FirebaseAnalytics.instance.setConsent( - analyticsStorageConsentGranted: true, - ), - completes, - ); + test('getSessionId', () async { + if (kIsWeb) { + await expectLater( + FirebaseAnalytics.instance.getSessionId(), + throwsA(isA()), + ); + } else { + await expectLater( + FirebaseAnalytics.instance.setConsent( + analyticsStorageConsentGranted: true, + ), + completes, + ); - final result = await FirebaseAnalytics.instance.getSessionId(); - expect(result, isA()); - } - }, - skip: skipTestsOnCI && defaultTargetPlatform == TargetPlatform.iOS, - ); + final result = await FirebaseAnalytics.instance.getSessionId(); + expect(result, isA()); + } + }, skip: skipTestsOnCI && defaultTargetPlatform == TargetPlatform.iOS); test('isSupported', () async { final result = await FirebaseAnalytics.instance.isSupported(); @@ -101,10 +97,7 @@ void main() { await expectLater( FirebaseAnalytics.instance.logEvent( name: 'testing-parameters', - parameters: { - 'foo': 'bar', - 'baz': 500, - }, + parameters: {'foo': 'bar', 'baz': 500}, ), completes, ); @@ -137,10 +130,7 @@ void main() { FirebaseAnalytics.instance.logEvent( name: 'testing-items-and-parameters', items: [analyticsEventItem], - parameters: { - 'foo': 'bar', - 'baz': 500, - }, + parameters: {'foo': 'bar', 'baz': 500}, ), completes, ); @@ -181,24 +171,23 @@ void main() { ); }); - test( - 'setSessionTimeoutDuration', - () async { - if (kIsWeb) { - await expectLater( - FirebaseAnalytics.instance - .setSessionTimeoutDuration(const Duration(milliseconds: 5000)), - throwsA(isA()), - ); - } else { - await expectLater( - FirebaseAnalytics.instance - .setSessionTimeoutDuration(const Duration(milliseconds: 5000)), - completes, - ); - } - }, - ); + test('setSessionTimeoutDuration', () async { + if (kIsWeb) { + await expectLater( + FirebaseAnalytics.instance.setSessionTimeoutDuration( + const Duration(milliseconds: 5000), + ), + throwsA(isA()), + ); + } else { + await expectLater( + FirebaseAnalytics.instance.setSessionTimeoutDuration( + const Duration(milliseconds: 5000), + ), + completes, + ); + } + }); test('setAnalyticsCollectionEnabled', () async { await expectLater( @@ -207,26 +196,22 @@ void main() { ); }); - test( - 'logInAppPurchase', - () async { - await expectLater( - FirebaseAnalytics.instance.logInAppPurchase( - currency: 'USD', - freeTrial: false, - price: 4.99, - priceIsDiscounted: false, - productID: 'com.example.product', - productName: 'Example Product', - quantity: 1, - subscription: true, - value: 4.99, - ), - completes, - ); - }, - skip: defaultTargetPlatform != TargetPlatform.iOS, - ); + test('logInAppPurchase', () async { + await expectLater( + FirebaseAnalytics.instance.logInAppPurchase( + currency: 'USD', + freeTrial: false, + price: 4.99, + priceIsDiscounted: false, + productID: 'com.example.product', + productName: 'Example Product', + quantity: 1, + subscription: true, + value: 4.99, + ), + completes, + ); + }, skip: defaultTargetPlatform != TargetPlatform.iOS); test('setUserId', () async { await expectLater( @@ -252,94 +237,87 @@ void main() { ); }); - test( - 'resetAnalyticsData', - () async { - if (kIsWeb) { - await expectLater( - FirebaseAnalytics.instance.resetAnalyticsData(), - throwsA(isA()), - ); - } else { - await expectLater( - FirebaseAnalytics.instance.resetAnalyticsData(), - completes, - ); - } - }, - ); - - test( - 'setConsent', - () async { + test('resetAnalyticsData', () async { + if (kIsWeb) { await expectLater( - FirebaseAnalytics.instance.setConsent( - analyticsStorageConsentGranted: true, - adStorageConsentGranted: true, - adPersonalizationSignalsConsentGranted: true, - adUserDataConsentGranted: true, - functionalityStorageConsentGranted: true, - personalizationStorageConsentGranted: true, - securityStorageConsentGranted: true, - ), + FirebaseAnalytics.instance.resetAnalyticsData(), + throwsA(isA()), + ); + } else { + await expectLater( + FirebaseAnalytics.instance.resetAnalyticsData(), completes, ); - }, - ); + } + }); - test( - 'setDefaultEventParameters', - () async { - if (kIsWeb) { - await expectLater( - FirebaseAnalytics.instance - .setDefaultEventParameters({'default': 'parameters'}), - throwsA(isA()), - ); - // reset a single default parameter - await expectLater( - FirebaseAnalytics.instance - .setDefaultEventParameters({'default': null}), - throwsA(isA()), - ); - // reset all default parameters - await expectLater( - FirebaseAnalytics.instance.setDefaultEventParameters(null), - throwsA(isA()), - ); - } else { - await expectLater( - FirebaseAnalytics.instance - .setDefaultEventParameters({'default': 'parameters'}), - completes, - ); - // reset a single default parameter - await expectLater( - FirebaseAnalytics.instance - .setDefaultEventParameters({'default': null}), - completes, - ); - // reset all default parameters - await expectLater( - FirebaseAnalytics.instance.setDefaultEventParameters(null), - completes, - ); + test('setConsent', () async { + await expectLater( + FirebaseAnalytics.instance.setConsent( + analyticsStorageConsentGranted: true, + adStorageConsentGranted: true, + adPersonalizationSignalsConsentGranted: true, + adUserDataConsentGranted: true, + functionalityStorageConsentGranted: true, + personalizationStorageConsentGranted: true, + securityStorageConsentGranted: true, + ), + completes, + ); + }); - // test custom event assert exception - await expectLater( - FirebaseAnalytics.instance.setDefaultEventParameters( - { - 'foo': 'bar', - 'baz': 500, - // Lists are not supported - 'items': ['some', 'items'], - }, - ), - throwsA(isA()), - ); - } - }, - ); + test('setDefaultEventParameters', () async { + if (kIsWeb) { + await expectLater( + FirebaseAnalytics.instance.setDefaultEventParameters({ + 'default': 'parameters', + }), + throwsA(isA()), + ); + // reset a single default parameter + await expectLater( + FirebaseAnalytics.instance.setDefaultEventParameters({ + 'default': null, + }), + throwsA(isA()), + ); + // reset all default parameters + await expectLater( + FirebaseAnalytics.instance.setDefaultEventParameters(null), + throwsA(isA()), + ); + } else { + await expectLater( + FirebaseAnalytics.instance.setDefaultEventParameters({ + 'default': 'parameters', + }), + completes, + ); + // reset a single default parameter + await expectLater( + FirebaseAnalytics.instance.setDefaultEventParameters({ + 'default': null, + }), + completes, + ); + // reset all default parameters + await expectLater( + FirebaseAnalytics.instance.setDefaultEventParameters(null), + completes, + ); + + // test custom event assert exception + await expectLater( + FirebaseAnalytics.instance.setDefaultEventParameters({ + 'foo': 'bar', + 'baz': 500, + // Lists are not supported + 'items': ['some', 'items'], + }), + throwsA(isA()), + ); + } + }); test('appInstanceId', () async { if (kIsWeb) { @@ -372,27 +350,23 @@ void main() { } }); - test( - 'initiateOnDeviceConversionMeasurement', - () async { - await expectLater( - FirebaseAnalytics.instance - .initiateOnDeviceConversionMeasurementWithEmailAddress( - 'test@mail.com', - ), - completes, - ); + test('initiateOnDeviceConversionMeasurement', () async { + await expectLater( + FirebaseAnalytics.instance + .initiateOnDeviceConversionMeasurementWithEmailAddress( + 'test@mail.com', + ), + completes, + ); - await expectLater( - FirebaseAnalytics.instance - .initiateOnDeviceConversionMeasurementWithPhoneNumber( - '+15555555555', - ), - completes, - ); - }, - skip: kIsWeb || defaultTargetPlatform != TargetPlatform.iOS, - ); + await expectLater( + FirebaseAnalytics.instance + .initiateOnDeviceConversionMeasurementWithPhoneNumber( + '+15555555555', + ), + completes, + ); + }, skip: kIsWeb || defaultTargetPlatform != TargetPlatform.iOS); group('logTransaction', () { test( @@ -409,7 +383,8 @@ void main() { ), ); }, - skip: kIsWeb || + skip: + kIsWeb || (defaultTargetPlatform != TargetPlatform.iOS && defaultTargetPlatform != TargetPlatform.macOS), ); @@ -428,7 +403,8 @@ void main() { ), ); }, - skip: kIsWeb || + skip: + kIsWeb || (defaultTargetPlatform != TargetPlatform.iOS && defaultTargetPlatform != TargetPlatform.macOS), ); diff --git a/packages/firebase_analytics/firebase_analytics/example/integration_test/report_test_results.dart b/packages/firebase_analytics/firebase_analytics/example/integration_test/report_test_results.dart index 038d20c39931..416b8cd76dd0 100644 --- a/packages/firebase_analytics/firebase_analytics/example/integration_test/report_test_results.dart +++ b/packages/firebase_analytics/firebase_analytics/example/integration_test/report_test_results.dart @@ -26,8 +26,9 @@ void reportTestResultsToDriver(IntegrationTestWidgetsFlutterBinding binding) { for (final entry in binding.results.entries) if (entry.value is Failure) entry.key, ]; - bool didFail(String name) => failures - .any((failure) => name == failure || name.endsWith(' $failure')); + bool didFail(String name) => failures.any( + (failure) => name == failure || name.endsWith(' $failure'), + ); binding.reportData ??= {}; binding.reportData!['testResults'] = { diff --git a/packages/firebase_analytics/firebase_analytics/example/lib/firebase_options.dart b/packages/firebase_analytics/firebase_analytics/example/lib/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/firebase_analytics/firebase_analytics/example/lib/firebase_options.dart +++ b/packages/firebase_analytics/firebase_analytics/example/lib/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/firebase_analytics/firebase_analytics/example/lib/main.dart b/packages/firebase_analytics/firebase_analytics/example/lib/main.dart index 37c7dd8eec76..09cc38c1378d 100755 --- a/packages/firebase_analytics/firebase_analytics/example/lib/main.dart +++ b/packages/firebase_analytics/firebase_analytics/example/lib/main.dart @@ -15,9 +15,7 @@ import 'tabs_page.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); + await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); runApp(const MyApp()); } @@ -25,16 +23,15 @@ class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); static FirebaseAnalytics analytics = FirebaseAnalytics.instance; - static FirebaseAnalyticsObserver observer = - FirebaseAnalyticsObserver(analytics: analytics); + static FirebaseAnalyticsObserver observer = FirebaseAnalyticsObserver( + analytics: analytics, + ); @override Widget build(BuildContext context) { return MaterialApp( title: 'Firebase Analytics Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), + theme: ThemeData(primarySwatch: Colors.blue), navigatorObservers: [observer], home: MyHomePage( title: 'Firebase Analytics Demo', @@ -70,8 +67,9 @@ class _MyHomePageState extends State { @override void initState() { super.initState(); - _purchaseSubscription = - InAppPurchase.instance.purchaseStream.listen(_onPurchaseUpdate); + _purchaseSubscription = InAppPurchase.instance.purchaseStream.listen( + _onPurchaseUpdate, + ); } @override @@ -90,11 +88,14 @@ class _MyHomePageState extends State { final transactionId = purchase.purchaseID; print('transactionId: $transactionId'); if (transactionId != null) { - widget.analytics.logTransaction(transactionId).then((_) { - setMessage('logTransaction succeeded with ID: $transactionId'); - }).catchError((e) { - setMessage('logTransaction failed: $e'); - }); + widget.analytics + .logTransaction(transactionId) + .then((_) { + setMessage('logTransaction succeeded with ID: $transactionId'); + }) + .catchError((e) { + setMessage('logTransaction failed: $e'); + }); } } else if (purchase.status == PurchaseStatus.error) { setMessage('Purchase error: ${purchase.error?.message}'); @@ -158,8 +159,9 @@ class _MyHomePageState extends State { } Future _testSetSessionTimeoutDuration() async { - await widget.analytics - .setSessionTimeoutDuration(const Duration(milliseconds: 20000)); + await widget.analytics.setSessionTimeoutDuration( + const Duration(milliseconds: 20000), + ); setMessage('setSessionTimeoutDuration succeeded'); } @@ -207,8 +209,9 @@ class _MyHomePageState extends State { setMessage('Loading product $_testProductId...'); - final response = - await InAppPurchase.instance.queryProductDetails({_testProductId}); + final response = await InAppPurchase.instance.queryProductDetails({ + _testProductId, + }); if (response.error != null) { setMessage('Failed to load product: ${response.error!.message}'); @@ -287,25 +290,19 @@ class _MyHomePageState extends State { value: 345.66, ); - await widget.analytics.logGenerateLead( - currency: 'USD', - value: 123.45, - ); - await widget.analytics.logJoinGroup( - groupId: 'test group id', - ); - await widget.analytics.logLevelUp( - level: 5, - character: 'witch doctor', - ); + await widget.analytics.logGenerateLead(currency: 'USD', value: 123.45); + await widget.analytics.logJoinGroup(groupId: 'test group id'); + await widget.analytics.logLevelUp(level: 5, character: 'witch doctor'); await widget.analytics.logLogin(loginMethod: 'login'); await widget.analytics.logPostScore( score: 1000000, level: 70, character: 'tiefling cleric', ); - await widget.analytics - .logPurchase(currency: 'USD', transactionId: 'transaction-id'); + await widget.analytics.logPurchase( + currency: 'USD', + transactionId: 'transaction-id', + ); await widget.analytics.logSearch( searchTerm: 'hotel', numberOfNights: 2, @@ -332,9 +329,7 @@ class _MyHomePageState extends State { itemListName: 't-shirt', itemListId: '1234', ); - await widget.analytics.logScreenView( - screenName: 'tabs-page', - ); + await widget.analytics.logScreenView(screenName: 'tabs-page'); await widget.analytics.logViewCart( currency: 'USD', value: 123, @@ -345,9 +340,7 @@ class _MyHomePageState extends State { itemId: 'test item id', method: 'facebook', ); - await widget.analytics.logSignUp( - signUpMethod: 'test sign up method', - ); + await widget.analytics.logSignUp(signUpMethod: 'test sign up method'); await widget.analytics.logSpendVirtualCurrency( itemName: 'test item name', virtualCurrencyName: 'bitcoin', @@ -379,18 +372,14 @@ class _MyHomePageState extends State { itemListName: 'green t-shirt', items: [itemCreator()], ); - await widget.analytics.logViewSearchResults( - searchTerm: 'test search term', - ); + await widget.analytics.logViewSearchResults(searchTerm: 'test search term'); setMessage('All standard events logged successfully'); } @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), + appBar: AppBar(title: Text(widget.title)), body: Center( child: Column( children: [ diff --git a/packages/firebase_analytics/firebase_analytics/example/lib/tabs_page.dart b/packages/firebase_analytics/firebase_analytics/example/lib/tabs_page.dart index bd9a36865363..df6b5592e672 100644 --- a/packages/firebase_analytics/firebase_analytics/example/lib/tabs_page.dart +++ b/packages/firebase_analytics/firebase_analytics/example/lib/tabs_page.dart @@ -64,10 +64,7 @@ class _TabsPageState extends State Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - bottom: TabBar( - controller: _controller, - tabs: tabs, - ), + bottom: TabBar(controller: _controller, tabs: tabs), ), body: TabBarView( controller: _controller, diff --git a/packages/firebase_analytics/firebase_analytics/example/pubspec.yaml b/packages/firebase_analytics/firebase_analytics/example/pubspec.yaml index 687d991defb9..0f14afdb57a0 100755 --- a/packages/firebase_analytics/firebase_analytics/example/pubspec.yaml +++ b/packages/firebase_analytics/firebase_analytics/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the firebase_analytics plugin. resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_analytics: ^12.5.0 diff --git a/packages/firebase_analytics/firebase_analytics/example/test_driver/integration_test.dart b/packages/firebase_analytics/firebase_analytics/example/test_driver/integration_test.dart index 691723cbbfe1..9ccbcc26ab97 100644 --- a/packages/firebase_analytics/firebase_analytics/example/test_driver/integration_test.dart +++ b/packages/firebase_analytics/firebase_analytics/example/test_driver/integration_test.dart @@ -7,28 +7,32 @@ import 'dart:io'; import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver( - writeResponseOnFailure: true, - responseDataCallback: (Map? data) async { - final results = - (data?['testResults'] as Map?)?.cast() ?? - const {}; - var passed = 0; - var failed = 0; - for (final entry in results.entries) { - final ok = entry.value == 'success'; - ok ? passed++ : failed++; - // ignore: avoid_print - print('${ok ? '✅' : '❌'} ${entry.key}'); - } - // ignore: avoid_print - print('Web e2e summary: $passed passed, $failed failed, ' - '${results.length} total'); - if (results.isEmpty) { - // ignore: avoid_print - print('[E] No tests reported by the app - treating as ' - 'infrastructure failure.'); - exit(1); - } - await writeResponseData(data); - }, + writeResponseOnFailure: true, + responseDataCallback: (Map? data) async { + final results = + (data?['testResults'] as Map?)?.cast() ?? + const {}; + var passed = 0; + var failed = 0; + for (final entry in results.entries) { + final ok = entry.value == 'success'; + ok ? passed++ : failed++; + // ignore: avoid_print + print('${ok ? '✅' : '❌'} ${entry.key}'); + } + // ignore: avoid_print + print( + 'Web e2e summary: $passed passed, $failed failed, ' + '${results.length} total', ); + if (results.isEmpty) { + // ignore: avoid_print + print( + '[E] No tests reported by the app - treating as ' + 'infrastructure failure.', + ); + exit(1); + } + await writeResponseData(data); + }, +); diff --git a/packages/firebase_analytics/firebase_analytics/lib/observer.dart b/packages/firebase_analytics/firebase_analytics/lib/observer.dart index 1501a41bb235..ebffd8aeff5c 100644 --- a/packages/firebase_analytics/firebase_analytics/lib/observer.dart +++ b/packages/firebase_analytics/firebase_analytics/lib/observer.dart @@ -83,17 +83,16 @@ class FirebaseAnalyticsObserver extends RouteObserver> { void _sendScreenView(Route route) { final String? screenName = nameExtractor(route.settings); if (screenName != null) { - analytics.logScreenView(screenName: screenName).catchError( - (Object error) { - final _onError = this._onError; - if (_onError == null) { - debugPrint('$FirebaseAnalyticsObserver: $error'); - } else { - _onError(error as PlatformException); - } - }, - test: (Object error) => error is PlatformException, - ); + analytics.logScreenView(screenName: screenName).catchError(( + Object error, + ) { + final _onError = this._onError; + if (_onError == null) { + debugPrint('$FirebaseAnalyticsObserver: $error'); + } else { + _onError(error as PlatformException); + } + }, test: (Object error) => error is PlatformException); } } diff --git a/packages/firebase_analytics/firebase_analytics/lib/src/firebase_analytics.dart b/packages/firebase_analytics/firebase_analytics/lib/src/firebase_analytics.dart index c67f9eb71533..f882d7771a04 100755 --- a/packages/firebase_analytics/firebase_analytics/lib/src/firebase_analytics.dart +++ b/packages/firebase_analytics/firebase_analytics/lib/src/firebase_analytics.dart @@ -6,10 +6,8 @@ part of '../firebase_analytics.dart'; /// Firebase Analytics API. class FirebaseAnalytics extends FirebasePlugin { - FirebaseAnalytics._({ - required this.app, - this.webOptions, - }) : super(app.name, 'plugins.flutter.io/firebase_analytics'); + FirebaseAnalytics._({required this.app, this.webOptions}) + : super(app.name, 'plugins.flutter.io/firebase_analytics'); static Map _firebaseAnalyticsInstances = {}; @@ -21,8 +19,10 @@ class FirebaseAnalytics extends FirebasePlugin { FirebaseAnalyticsPlatform? _delegatePackingProperty; FirebaseAnalyticsPlatform get _delegate { - return _delegatePackingProperty ??= - FirebaseAnalyticsPlatform.instanceFor(app: app, webOptions: webOptions); + return _delegatePackingProperty ??= FirebaseAnalyticsPlatform.instanceFor( + app: app, + webOptions: webOptions, + ); } /// Returns an instance using a specified [FirebaseApp]. @@ -896,20 +896,18 @@ class FirebaseAnalytics extends FirebasePlugin { return _delegate.logEvent( name: 'search', - parameters: filterOutNulls( - { - _SEARCH_TERM: searchTerm, - _NUMBER_OF_NIGHTS: numberOfNights, - _NUMBER_OF_ROOMS: numberOfRooms, - _NUMBER_OF_PASSENGERS: numberOfPassengers, - _ORIGIN: origin, - _DESTINATION: destination, - _START_DATE: startDate, - _END_DATE: endDate, - _TRAVEL_CLASS: travelClass, - if (parameters != null) ...parameters, - }, - ), + parameters: filterOutNulls({ + _SEARCH_TERM: searchTerm, + _NUMBER_OF_NIGHTS: numberOfNights, + _NUMBER_OF_ROOMS: numberOfRooms, + _NUMBER_OF_PASSENGERS: numberOfPassengers, + _ORIGIN: origin, + _DESTINATION: destination, + _START_DATE: startDate, + _END_DATE: endDate, + _TRAVEL_CLASS: travelClass, + if (parameters != null) ...parameters, + }), callOptions: callOptions, ); } @@ -1019,15 +1017,10 @@ class FirebaseAnalytics extends FirebasePlugin { /// users complete this process and move on to the full app experience. /// /// See: https://firebase.google.com/docs/reference/android/com/google/firebase/analytics/FirebaseAnalytics.Event.html#TUTORIAL_BEGIN - Future logTutorialBegin({ - Map? parameters, - }) { + Future logTutorialBegin({Map? parameters}) { _assertParameterTypesAreCorrect(parameters); - return _delegate.logEvent( - name: 'tutorial_begin', - parameters: parameters, - ); + return _delegate.logEvent(name: 'tutorial_begin', parameters: parameters); } /// Logs the standard `tutorial_complete` event. @@ -1037,9 +1030,7 @@ class FirebaseAnalytics extends FirebasePlugin { /// completion rate of your on-boarding process. /// /// See: https://firebase.google.com/docs/reference/android/com/google/firebase/analytics/FirebaseAnalytics.Event.html#TUTORIAL_COMPLETE - Future logTutorialComplete({ - Map? parameters, - }) { + Future logTutorialComplete({Map? parameters}) { _assertParameterTypesAreCorrect(parameters); return _delegate.logEvent( @@ -1363,7 +1354,8 @@ Map filterOutNulls(Map parameters) { } @visibleForTesting -const String valueAndCurrencyMustBeTogetherError = 'If you supply the "value" ' +const String valueAndCurrencyMustBeTogetherError = + 'If you supply the "value" ' 'parameter, you must also supply the "currency" parameter.'; void _requireValueAndCurrencyTogether(double? value, String? currency) { @@ -1400,13 +1392,12 @@ List>? _marshalItems(List? items) { void _assertParameterTypesAreCorrect( Map? parameters, -) => - parameters?.forEach((key, value) { - assert( - value is String || value is num, - "'string' OR 'number' must be set as the value of the parameter: $key. $value found instead", - ); - }); +) => parameters?.forEach((key, value) { + assert( + value is String || value is num, + "'string' OR 'number' must be set as the value of the parameter: $key. $value found instead", + ); +}); void _assertItemsParameterTypesAreCorrect(List? items) => items?.forEach((item) { diff --git a/packages/firebase_analytics/firebase_analytics/pubspec.yaml b/packages/firebase_analytics/firebase_analytics/pubspec.yaml index 6948419678ce..5aefdce7851c 100755 --- a/packages/firebase_analytics/firebase_analytics/pubspec.yaml +++ b/packages/firebase_analytics/firebase_analytics/pubspec.yaml @@ -16,8 +16,8 @@ false_secrets: - example/** environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_analytics_platform_interface: ^6.0.7 diff --git a/packages/firebase_analytics/firebase_analytics/test/firebase_analytics_test.dart b/packages/firebase_analytics/firebase_analytics/test/firebase_analytics_test.dart index f4d47aba6d68..fe68fe841208 100755 --- a/packages/firebase_analytics/firebase_analytics/test/firebase_analytics_test.dart +++ b/packages/firebase_analytics/firebase_analytics/test/firebase_analytics_test.dart @@ -155,39 +155,27 @@ void main() { } testRequiresValueAndCurrencyTogether('logAddToCart', () { - return analytics!.logAddToCart( - value: 123.90, - ); + return analytics!.logAddToCart(value: 123.90); }); testRequiresValueAndCurrencyTogether('logRemoveFromCart', () { - return analytics!.logRemoveFromCart( - value: 123.90, - ); + return analytics!.logRemoveFromCart(value: 123.90); }); testRequiresValueAndCurrencyTogether('logAddToWishlist', () { - return analytics!.logAddToWishlist( - value: 123.90, - ); + return analytics!.logAddToWishlist(value: 123.90); }); testRequiresValueAndCurrencyTogether('logBeginCheckout', () { - return analytics!.logBeginCheckout( - value: 123.90, - ); + return analytics!.logBeginCheckout(value: 123.90); }); testRequiresValueAndCurrencyTogether('logGenerateLead', () { - return analytics!.logGenerateLead( - value: 123.90, - ); + return analytics!.logGenerateLead(value: 123.90); }); testRequiresValueAndCurrencyTogether('logViewItem', () { - return analytics!.logViewItem( - value: 123.90, - ); + return analytics!.logViewItem(value: 123.90); }); test('logEvent with items rejects invalid item parameter types', () { @@ -195,10 +183,7 @@ void main() { () => analytics!.logEvent( name: 'custom_event', items: [ - AnalyticsEventItem( - itemId: 'id', - parameters: {'invalid': true}, - ), + AnalyticsEventItem(itemId: 'id', parameters: {'invalid': true}), ], ), throwsA(isA()), @@ -240,8 +225,10 @@ void main() { ); // reserved prefix expect( - analytics! - .setUserProperty(name: 'firebase_test', value: 'test-value'), + analytics!.setUserProperty( + name: 'firebase_test', + value: 'test-value', + ), throwsArgumentError, ); }); diff --git a/packages/firebase_analytics/firebase_analytics/test/mock.dart b/packages/firebase_analytics/firebase_analytics/test/mock.dart index 117f0cd5662f..427655b9844f 100644 --- a/packages/firebase_analytics/firebase_analytics/test/mock.dart +++ b/packages/firebase_analytics/firebase_analytics/test/mock.dart @@ -17,15 +17,16 @@ void setupFirebaseAnalyticsMocks([Callback? customHandlers]) { setupFirebaseCoreMocks(); TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(MethodChannelFirebaseAnalytics.channel, - (MethodCall methodCall) async { - methodCallLog.add(methodCall); - switch (methodCall.method) { - case 'Analytics#getAppInstanceId': - return 'ABCD1234'; + .setMockMethodCallHandler(MethodChannelFirebaseAnalytics.channel, ( + MethodCall methodCall, + ) async { + methodCallLog.add(methodCall); + switch (methodCall.method) { + case 'Analytics#getAppInstanceId': + return 'ABCD1234'; - default: - return false; - } - }); + default: + return false; + } + }); } diff --git a/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/analytics_call_options.dart b/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/analytics_call_options.dart index 13bd33f4e6ea..0c7890572b1b 100644 --- a/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/analytics_call_options.dart +++ b/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/analytics_call_options.dart @@ -5,18 +5,14 @@ /// Additional options that can be passed to Analytics method calls. /// Note; these options are only used on the web. class AnalyticsCallOptions { - AnalyticsCallOptions({ - required this.global, - }); + AnalyticsCallOptions({required this.global}); /// If true, this config or event call applies globally to all Google Analytics properties on the page. final bool global; /// Returns the current instance as a [Map]. Map asMap() { - return { - 'global': global, - }; + return {'global': global}; } @override diff --git a/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/method_channel/method_channel_firebase_analytics.dart b/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/method_channel/method_channel_firebase_analytics.dart index 151734da565e..208d9aa9ec0d 100644 --- a/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/method_channel/method_channel_firebase_analytics.dart +++ b/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/method_channel/method_channel_firebase_analytics.dart @@ -17,7 +17,7 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform { /// Creates a new [MethodChannelFirebaseAnalytics] instance with an [app] and/or /// [region]. MethodChannelFirebaseAnalytics({required FirebaseApp app}) - : super(appInstance: app); + : super(appInstance: app); /// Internal stub class initializer. /// @@ -32,8 +32,9 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform { return MethodChannelFirebaseAnalytics._(); } - static const MethodChannel channel = - MethodChannel('plugins.flutter.io/firebase_analytics'); + static const MethodChannel channel = MethodChannel( + 'plugins.flutter.io/firebase_analytics', + ); @override FirebaseAnalyticsPlatform delegateFor({ @@ -122,10 +123,7 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform { } @override - Future setUserId({ - String? id, - AnalyticsCallOptions? callOptions, - }) { + Future setUserId({String? id, AnalyticsCallOptions? callOptions}) { try { return _api.setUserId(id); } catch (e, s) { @@ -183,23 +181,19 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform { String? hashedPhoneNumber, }) { try { - return _api.initiateOnDeviceConversionMeasurement( - { - 'emailAddress': emailAddress, - 'phoneNumber': phoneNumber, - 'hashedEmailAddress': hashedEmailAddress, - 'hashedPhoneNumber': hashedPhoneNumber, - }, - ); + return _api.initiateOnDeviceConversionMeasurement({ + 'emailAddress': emailAddress, + 'phoneNumber': phoneNumber, + 'hashedEmailAddress': hashedEmailAddress, + 'hashedPhoneNumber': hashedPhoneNumber, + }); } catch (e, s) { convertPlatformException(e, s); } } @override - Future logTransaction({ - required String transactionId, - }) { + Future logTransaction({required String transactionId}) { try { return _api.logTransaction(transactionId); } catch (e, s) { diff --git a/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/pigeon/messages.pigeon.dart b/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/pigeon/messages.pigeon.dart index b61f5de91985..7f9fc112bc99 100644 --- a/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/pigeon/messages.pigeon.dart +++ b/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/pigeon/messages.pigeon.dart @@ -37,8 +37,11 @@ Object? _extractReplyValueOrThrow( return replyList.firstOrNull; } -List wrapResponse( - {Object? result, PlatformException? error, bool empty = false}) { +List wrapResponse({ + Object? result, + PlatformException? error, + bool empty = false, +}) { if (empty) { return []; } @@ -60,8 +63,9 @@ bool _deepEquals(Object? a, Object? b) { } if (a is List && b is List) { return a.length == b.length && - a.indexed - .every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1])); + a.indexed.every( + ((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]), + ); } if (a is Map && b is Map) { if (a.length != b.length) { @@ -111,20 +115,14 @@ int _deepHash(Object? value) { } class AnalyticsEvent { - AnalyticsEvent({ - required this.name, - this.parameters, - }); + AnalyticsEvent({required this.name, this.parameters}); String name; Map? parameters; List _toList() { - return [ - name, - parameters, - ]; + return [name, parameters]; } Object encode() { @@ -135,8 +133,8 @@ class AnalyticsEvent { result as List; return AnalyticsEvent( name: result[0]! as String, - parameters: - (result[1] as Map?)?.cast(), + parameters: (result[1] as Map?) + ?.cast(), ); } @@ -188,11 +186,13 @@ class FirebaseAnalyticsHostApi { /// Constructor for [FirebaseAnalyticsHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - FirebaseAnalyticsHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + FirebaseAnalyticsHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -207,8 +207,9 @@ class FirebaseAnalyticsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([event]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [event], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -226,8 +227,9 @@ class FirebaseAnalyticsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([userId]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [userId], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -245,8 +247,9 @@ class FirebaseAnalyticsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([name, value]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [name, value], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -264,8 +267,9 @@ class FirebaseAnalyticsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([enabled]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [enabled], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -301,8 +305,9 @@ class FirebaseAnalyticsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([timeout]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [timeout], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -320,8 +325,9 @@ class FirebaseAnalyticsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([consent]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [consent], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -332,7 +338,8 @@ class FirebaseAnalyticsHostApi { } Future setDefaultEventParameters( - Map? parameters) async { + Map? parameters, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.setDefaultEventParameters$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -340,8 +347,9 @@ class FirebaseAnalyticsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([parameters]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [parameters], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -390,7 +398,8 @@ class FirebaseAnalyticsHostApi { } Future initiateOnDeviceConversionMeasurement( - Map arguments) async { + Map arguments, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.initiateOnDeviceConversionMeasurement$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -398,8 +407,9 @@ class FirebaseAnalyticsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([arguments]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [arguments], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -417,8 +427,9 @@ class FirebaseAnalyticsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([transactionId]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [transactionId], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( diff --git a/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/platform_interface/platform_interface_firebase_analytics.dart b/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/platform_interface/platform_interface_firebase_analytics.dart index f69c816e707d..d3e0f30dbca4 100644 --- a/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/platform_interface/platform_interface_firebase_analytics.dart +++ b/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/platform_interface/platform_interface_firebase_analytics.dart @@ -44,8 +44,10 @@ abstract class FirebaseAnalyticsPlatform extends PlatformInterface { required FirebaseApp app, Map? webOptions, }) { - return FirebaseAnalyticsPlatform.instance - .delegateFor(app: app, webOptions: webOptions); + return FirebaseAnalyticsPlatform.instance.delegateFor( + app: app, + webOptions: webOptions, + ); } /// The current default [FirebaseAnalyticsPlatform] instance. @@ -131,10 +133,7 @@ abstract class FirebaseAnalyticsPlatform extends PlatformInterface { /// Sets the user id. /// Setting a null [id] removes the user id. /// [callOptions] are for web platform only. - Future setUserId({ - String? id, - AnalyticsCallOptions? callOptions, - }) { + Future setUserId({String? id, AnalyticsCallOptions? callOptions}) { throw UnimplementedError('setUserId() is not implemented'); } @@ -210,9 +209,7 @@ abstract class FirebaseAnalyticsPlatform extends PlatformInterface { ); } - Future logTransaction({ - required String transactionId, - }) { + Future logTransaction({required String transactionId}) { throw UnimplementedError('logTransaction() is not implemented'); } } diff --git a/packages/firebase_analytics/firebase_analytics_platform_interface/pigeons/messages.dart b/packages/firebase_analytics/firebase_analytics_platform_interface/pigeons/messages.dart index b7008b4d3871..62dfb97af028 100644 --- a/packages/firebase_analytics/firebase_analytics_platform_interface/pigeons/messages.dart +++ b/packages/firebase_analytics/firebase_analytics_platform_interface/pigeons/messages.dart @@ -23,10 +23,7 @@ import 'package:pigeon/pigeon.dart'; ), ) class AnalyticsEvent { - const AnalyticsEvent({ - required this.name, - required this.parameters, - }); + const AnalyticsEvent({required this.name, required this.parameters}); final String name; final Map? parameters; diff --git a/packages/firebase_analytics/firebase_analytics_platform_interface/pubspec.yaml b/packages/firebase_analytics/firebase_analytics_platform_interface/pubspec.yaml index 525b13cb3dae..26ee085fa8b5 100644 --- a/packages/firebase_analytics/firebase_analytics_platform_interface/pubspec.yaml +++ b/packages/firebase_analytics/firebase_analytics_platform_interface/pubspec.yaml @@ -6,8 +6,8 @@ version: 6.0.7 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_analytics/firebase_analytics_platform_interface/test/mock.dart b/packages/firebase_analytics/firebase_analytics_platform_interface/test/mock.dart index f63b0507d302..15c341fc837d 100644 --- a/packages/firebase_analytics/firebase_analytics_platform_interface/test/mock.dart +++ b/packages/firebase_analytics/firebase_analytics_platform_interface/test/mock.dart @@ -18,22 +18,24 @@ void setupFirebaseAnalyticsMocks([Callback? customHandlers]) { setupFirebaseCoreMocks(); TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(MethodChannelFirebaseAnalytics.channel, - (MethodCall methodCall) async { - methodCallLog.add(methodCall); - switch (methodCall.method) { - case 'Analytics#getAppInstanceId': - return 'ABCD1234'; - - default: - return false; - } - }); + .setMockMethodCallHandler(MethodChannelFirebaseAnalytics.channel, ( + MethodCall methodCall, + ) async { + methodCallLog.add(methodCall); + switch (methodCall.method) { + case 'Analytics#getAppInstanceId': + return 'ABCD1234'; + + default: + return false; + } + }); } void handleMethodCall(MethodCallCallback methodCallCallback) => TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(MethodChannelFirebaseAnalytics.channel, - (call) async { - return await methodCallCallback(call); - }); + .setMockMethodCallHandler(MethodChannelFirebaseAnalytics.channel, ( + call, + ) async { + return await methodCallCallback(call); + }); diff --git a/packages/firebase_analytics/firebase_analytics_platform_interface/test/pigeon/test_api.dart b/packages/firebase_analytics/firebase_analytics_platform_interface/test/pigeon/test_api.dart index 830f97b9696d..e805758a785e 100644 --- a/packages/firebase_analytics/firebase_analytics_platform_interface/test/pigeon/test_api.dart +++ b/packages/firebase_analytics/firebase_analytics_platform_interface/test/pigeon/test_api.dart @@ -65,7 +65,8 @@ abstract class TestFirebaseAnalyticsHostApi { Future getSessionId(); Future initiateOnDeviceConversionMeasurement( - Map arguments); + Map arguments, + ); Future logTransaction(String transactionId); @@ -74,317 +75,390 @@ abstract class TestFirebaseAnalyticsHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.logEvent$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.logEvent$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final Map arg_event = - (args[0]! as Map).cast(); - try { - await api.logEvent(arg_event); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final Map arg_event = + (args[0]! as Map).cast(); + try { + await api.logEvent(arg_event); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.setUserId$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.setUserId$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String? arg_userId = args[0] as String?; - try { - await api.setUserId(arg_userId); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String? arg_userId = args[0] as String?; + try { + await api.setUserId(arg_userId); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.setUserProperty$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.setUserProperty$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_name = args[0]! as String; - final String? arg_value = args[1] as String?; - try { - await api.setUserProperty(arg_name, arg_value); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_name = args[0]! as String; + final String? arg_value = args[1] as String?; + try { + await api.setUserProperty(arg_name, arg_value); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.setAnalyticsCollectionEnabled$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.setAnalyticsCollectionEnabled$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final bool arg_enabled = args[0]! as bool; - try { - await api.setAnalyticsCollectionEnabled(arg_enabled); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final bool arg_enabled = args[0]! as bool; + try { + await api.setAnalyticsCollectionEnabled(arg_enabled); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.resetAnalyticsData$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.resetAnalyticsData$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - try { - await api.resetAnalyticsData(); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + try { + await api.resetAnalyticsData(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.setSessionTimeoutDuration$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.setSessionTimeoutDuration$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final int arg_timeout = args[0]! as int; - try { - await api.setSessionTimeoutDuration(arg_timeout); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final int arg_timeout = args[0]! as int; + try { + await api.setSessionTimeoutDuration(arg_timeout); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.setConsent$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.setConsent$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final Map arg_consent = - (args[0]! as Map).cast(); - try { - await api.setConsent(arg_consent); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final Map arg_consent = + (args[0]! as Map).cast(); + try { + await api.setConsent(arg_consent); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.setDefaultEventParameters$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.setDefaultEventParameters$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final Map? arg_parameters = - (args[0] as Map?)?.cast(); - try { - await api.setDefaultEventParameters(arg_parameters); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final Map? arg_parameters = + (args[0] as Map?)?.cast(); + try { + await api.setDefaultEventParameters(arg_parameters); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.getAppInstanceId$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.getAppInstanceId$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - try { - final String? output = await api.getAppInstanceId(); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + try { + final String? output = await api.getAppInstanceId(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.getSessionId$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.getSessionId$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - try { - final int? output = await api.getSessionId(); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + try { + final int? output = await api.getSessionId(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.initiateOnDeviceConversionMeasurement$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.initiateOnDeviceConversionMeasurement$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final Map arg_arguments = - (args[0]! as Map).cast(); - try { - await api.initiateOnDeviceConversionMeasurement(arg_arguments); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final Map arg_arguments = + (args[0]! as Map).cast(); + try { + await api.initiateOnDeviceConversionMeasurement(arg_arguments); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.logTransaction$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_analytics_platform_interface.FirebaseAnalyticsHostApi.logTransaction$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_transactionId = args[0]! as String; - try { - await api.logTransaction(arg_transactionId); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_transactionId = args[0]! as String; + try { + await api.logTransaction(arg_transactionId); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } diff --git a/packages/firebase_analytics/firebase_analytics_platform_interface/test/platform_interface_tests/platform_interface_analytics_test.dart b/packages/firebase_analytics/firebase_analytics_platform_interface/test/platform_interface_tests/platform_interface_analytics_test.dart index 7444f2c5ea12..63212ac48215 100644 --- a/packages/firebase_analytics/firebase_analytics_platform_interface/test/platform_interface_tests/platform_interface_analytics_test.dart +++ b/packages/firebase_analytics/firebase_analytics_platform_interface/test/platform_interface_tests/platform_interface_analytics_test.dart @@ -30,9 +30,7 @@ void main() { ), ); - firebaseAnalyticsPlatform = TestFirebaseAnalyticsPlatform( - app, - ); + firebaseAnalyticsPlatform = TestFirebaseAnalyticsPlatform(app); }); test('Constructor', () { @@ -52,8 +50,9 @@ void main() { }); test('set.instance', () { - FirebaseAnalyticsPlatform.instance = - TestFirebaseAnalyticsPlatform(secondaryApp); + FirebaseAnalyticsPlatform.instance = TestFirebaseAnalyticsPlatform( + secondaryApp, + ); expect( FirebaseAnalyticsPlatform.instance, @@ -88,19 +87,21 @@ void main() { ); }); - test('throws if .setAnalyticsCollectionEnabled() not implemented', - () async { - await expectLater( - () => firebaseAnalyticsPlatform.setAnalyticsCollectionEnabled(true), - throwsA( - isA().having( - (e) => e.message, - 'message', - 'setAnalyticsCollectionEnabled() is not implemented', + test( + 'throws if .setAnalyticsCollectionEnabled() not implemented', + () async { + await expectLater( + () => firebaseAnalyticsPlatform.setAnalyticsCollectionEnabled(true), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'setAnalyticsCollectionEnabled() is not implemented', + ), ), - ), - ); - }); + ); + }, + ); test('throws if .setUserId() not implemented', () async { await expectLater( @@ -146,8 +147,9 @@ void main() { test('throws if .setSessionTimeoutDuration() not implemented', () async { await expectLater( - () => firebaseAnalyticsPlatform - .setSessionTimeoutDuration(const Duration(milliseconds: 1000)), + () => firebaseAnalyticsPlatform.setSessionTimeoutDuration( + const Duration(milliseconds: 1000), + ), throwsA( isA().having( (e) => e.message, diff --git a/packages/firebase_analytics/firebase_analytics_web/lib/firebase_analytics_web.dart b/packages/firebase_analytics/firebase_analytics_web/lib/firebase_analytics_web.dart index b16554ec508e..ef4db293fff5 100644 --- a/packages/firebase_analytics/firebase_analytics_web/lib/firebase_analytics_web.dart +++ b/packages/firebase_analytics/firebase_analytics_web/lib/firebase_analytics_web.dart @@ -33,10 +33,8 @@ class FirebaseAnalyticsWeb extends FirebaseAnalyticsPlatform { /// Builds an instance of [FirebaseAnalyticsWeb] with an optional [FirebaseApp] instance /// If [app] is null then the created instance will use the default [FirebaseApp] - FirebaseAnalyticsWeb({ - FirebaseApp? app, - this.webOptions, - }) : super(appInstance: app); + FirebaseAnalyticsWeb({FirebaseApp? app, this.webOptions}) + : super(appInstance: app); /// Called by PluginRegistry to register this plugin for Flutter Web static void registerWith(Registrar registrar) { @@ -117,10 +115,7 @@ class FirebaseAnalyticsWeb extends FirebaseAnalyticsPlatform { AnalyticsCallOptions? callOptions, }) async { return convertWebExceptions(() { - return _delegate.setUserId( - id: id, - callOptions: callOptions, - ); + return _delegate.setUserId(id: id, callOptions: callOptions); }); } @@ -162,8 +157,6 @@ class FirebaseAnalyticsWeb extends FirebaseAnalyticsPlatform { @override Future getAppInstanceId() async { - throw UnimplementedError( - 'getAppInstanceId() is not supported on web', - ); + throw UnimplementedError('getAppInstanceId() is not supported on web'); } } diff --git a/packages/firebase_analytics/firebase_analytics_web/lib/interop/analytics.dart b/packages/firebase_analytics/firebase_analytics_web/lib/interop/analytics.dart index 0d6b8a63590b..18c267c7d7f7 100644 --- a/packages/firebase_analytics/firebase_analytics_web/lib/interop/analytics.dart +++ b/packages/firebase_analytics/firebase_analytics_web/lib/interop/analytics.dart @@ -30,7 +30,7 @@ Analytics getAnalyticsInstance([ class Analytics extends JsObjectWrapper { Analytics._fromJsObject(analytics_interop.AnalyticsJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); static final _expando = Expando(); /// Creates a new Analytics instance from a [jsObject]. @@ -70,29 +70,32 @@ class Analytics extends JsObjectWrapper { }) { final consentSettings = { if (adPersonalizationSignalsConsentGranted != null) - 'ad_personalization': - adPersonalizationSignalsConsentGranted ? 'granted' : 'denied', + 'ad_personalization': adPersonalizationSignalsConsentGranted + ? 'granted' + : 'denied', if (adStorageConsentGranted != null) 'ad_storage': adStorageConsentGranted ? 'granted' : 'denied', if (adUserDataConsentGranted != null) 'ad_user_data': adUserDataConsentGranted ? 'granted' : 'denied', if (analyticsStorageConsentGranted != null) - 'analytics_storage': - analyticsStorageConsentGranted ? 'granted' : 'denied', + 'analytics_storage': analyticsStorageConsentGranted + ? 'granted' + : 'denied', if (functionalityStorageConsentGranted != null) - 'functionality_storage': - functionalityStorageConsentGranted ? 'granted' : 'denied', + 'functionality_storage': functionalityStorageConsentGranted + ? 'granted' + : 'denied', if (personalizationStorageConsentGranted != null) - 'personalization_storage': - personalizationStorageConsentGranted ? 'granted' : 'denied', + 'personalization_storage': personalizationStorageConsentGranted + ? 'granted' + : 'denied', if (securityStorageConsentGranted != null) - 'security_storage': - securityStorageConsentGranted ? 'granted' : 'denied', + 'security_storage': securityStorageConsentGranted + ? 'granted' + : 'denied', }.jsify(); - return analytics_interop.setConsent( - consentSettings, - ); + return analytics_interop.setConsent(consentSettings); } void setAnalyticsCollectionEnabled({required bool enabled}) { @@ -102,10 +105,7 @@ class Analytics extends JsObjectWrapper { ); } - void setUserId({ - String? id, - AnalyticsCallOptions? callOptions, - }) { + void setUserId({String? id, AnalyticsCallOptions? callOptions}) { return analytics_interop.setUserId( jsObject, id?.toJS, diff --git a/packages/firebase_analytics/firebase_analytics_web/lib/interop/analytics_interop.dart b/packages/firebase_analytics/firebase_analytics_web/lib/interop/analytics_interop.dart index 67c96423dd65..9b87eb7d663d 100644 --- a/packages/firebase_analytics/firebase_analytics_web/lib/interop/analytics_interop.dart +++ b/packages/firebase_analytics/firebase_analytics_web/lib/interop/analytics_interop.dart @@ -17,10 +17,7 @@ external AnalyticsJsImpl getAnalytics([AppJsImpl? app]); @JS() @staticInterop -external AnalyticsJsImpl initializeAnalytics( - AppJsImpl app, [ - JSAny? options, -]); +external AnalyticsJsImpl initializeAnalytics(AppJsImpl app, [JSAny? options]); @JS() @staticInterop diff --git a/packages/firebase_analytics/firebase_analytics_web/pubspec.yaml b/packages/firebase_analytics/firebase_analytics_web/pubspec.yaml index 9aa7eb056634..b4073b5acb73 100644 --- a/packages/firebase_analytics/firebase_analytics_web/pubspec.yaml +++ b/packages/firebase_analytics/firebase_analytics_web/pubspec.yaml @@ -6,8 +6,8 @@ version: 0.6.1+13 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.22.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_analytics/firebase_analytics_web/test/firebase_analytics_web_test.dart b/packages/firebase_analytics/firebase_analytics_web/test/firebase_analytics_web_test.dart index e01a3c0c1bde..499794195b00 100644 --- a/packages/firebase_analytics/firebase_analytics_web/test/firebase_analytics_web_test.dart +++ b/packages/firebase_analytics/firebase_analytics_web/test/firebase_analytics_web_test.dart @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @TestOn('chrome') - import 'package:firebase_analytics_web/firebase_analytics_web.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; diff --git a/packages/firebase_analytics/firebase_analytics_web/test/firebase_analytics_web_test.mocks.dart b/packages/firebase_analytics/firebase_analytics_web/test/firebase_analytics_web_test.mocks.dart index 9a504a46aefc..c7ad0911dccc 100644 --- a/packages/firebase_analytics/firebase_analytics_web/test/firebase_analytics_web_test.mocks.dart +++ b/packages/firebase_analytics/firebase_analytics_web/test/firebase_analytics_web_test.mocks.dart @@ -29,24 +29,14 @@ import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: subtype_of_sealed_class class _FakeFirebaseApp_0 extends _i1.SmartFake implements _i2.FirebaseApp { - _FakeFirebaseApp_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeFirebaseApp_0(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeFirebaseAnalyticsPlatform_1 extends _i1.SmartFake implements _i3.FirebaseAnalyticsPlatform { - _FakeFirebaseAnalyticsPlatform_1( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeFirebaseAnalyticsPlatform_1(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } /// A class which mocks [FirebaseAnalyticsWeb]. @@ -56,25 +46,21 @@ class MockFirebaseAnalyticsWeb extends _i1.Mock implements _i4.FirebaseAnalyticsWeb { @override set appInstance(_i2.FirebaseApp? _appInstance) => super.noSuchMethod( - Invocation.setter( - #appInstance, - _appInstance, - ), - returnValueForMissingStub: null, - ); + Invocation.setter(#appInstance, _appInstance), + returnValueForMissingStub: null, + ); @override - _i2.FirebaseApp get app => (super.noSuchMethod( - Invocation.getter(#app), - returnValue: _FakeFirebaseApp_0( - this, - Invocation.getter(#app), - ), - returnValueForMissingStub: _FakeFirebaseApp_0( - this, - Invocation.getter(#app), - ), - ) as _i2.FirebaseApp); + _i2.FirebaseApp get app => + (super.noSuchMethod( + Invocation.getter(#app), + returnValue: _FakeFirebaseApp_0(this, Invocation.getter(#app)), + returnValueForMissingStub: _FakeFirebaseApp_0( + this, + Invocation.getter(#app), + ), + ) + as _i2.FirebaseApp); @override _i3.FirebaseAnalyticsPlatform delegateFor({ @@ -82,57 +68,44 @@ class MockFirebaseAnalyticsWeb extends _i1.Mock Map? webOptions, }) => (super.noSuchMethod( - Invocation.method( - #delegateFor, - [], - { - #app: app, - #webOptions: webOptions, - }, - ), - returnValue: _FakeFirebaseAnalyticsPlatform_1( - this, - Invocation.method( - #delegateFor, - [], - { - #app: app, - #webOptions: webOptions, - }, - ), - ), - returnValueForMissingStub: _FakeFirebaseAnalyticsPlatform_1( - this, - Invocation.method( - #delegateFor, - [], - { + Invocation.method(#delegateFor, [], { #app: app, #webOptions: webOptions, - }, - ), - ), - ) as _i3.FirebaseAnalyticsPlatform); + }), + returnValue: _FakeFirebaseAnalyticsPlatform_1( + this, + Invocation.method(#delegateFor, [], { + #app: app, + #webOptions: webOptions, + }), + ), + returnValueForMissingStub: _FakeFirebaseAnalyticsPlatform_1( + this, + Invocation.method(#delegateFor, [], { + #app: app, + #webOptions: webOptions, + }), + ), + ) + as _i3.FirebaseAnalyticsPlatform); @override - _i5.Future isSupported() => (super.noSuchMethod( - Invocation.method( - #isSupported, - [], - ), - returnValue: _i5.Future.value(false), - returnValueForMissingStub: _i5.Future.value(false), - ) as _i5.Future); + _i5.Future isSupported() => + (super.noSuchMethod( + Invocation.method(#isSupported, []), + returnValue: _i5.Future.value(false), + returnValueForMissingStub: _i5.Future.value(false), + ) + as _i5.Future); @override - _i5.Future getSessionId() => (super.noSuchMethod( - Invocation.method( - #getSessionId, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + _i5.Future getSessionId() => + (super.noSuchMethod( + Invocation.method(#getSessionId, []), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future logEvent({ @@ -141,18 +114,15 @@ class MockFirebaseAnalyticsWeb extends _i1.Mock _i3.AnalyticsCallOptions? callOptions, }) => (super.noSuchMethod( - Invocation.method( - #logEvent, - [], - { - #name: name, - #parameters: parameters, - #callOptions: callOptions, - }, - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#logEvent, [], { + #name: name, + #parameters: parameters, + #callOptions: callOptions, + }), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future setConsent({ @@ -165,36 +135,31 @@ class MockFirebaseAnalyticsWeb extends _i1.Mock bool? securityStorageConsentGranted, }) => (super.noSuchMethod( - Invocation.method( - #setConsent, - [], - { - #adStorageConsentGranted: adStorageConsentGranted, - #analyticsStorageConsentGranted: analyticsStorageConsentGranted, - #adPersonalizationSignalsConsentGranted: - adPersonalizationSignalsConsentGranted, - #adUserDataConsentGranted: adUserDataConsentGranted, - #functionalityStorageConsentGranted: - functionalityStorageConsentGranted, - #personalizationStorageConsentGranted: - personalizationStorageConsentGranted, - #securityStorageConsentGranted: securityStorageConsentGranted, - }, - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#setConsent, [], { + #adStorageConsentGranted: adStorageConsentGranted, + #analyticsStorageConsentGranted: analyticsStorageConsentGranted, + #adPersonalizationSignalsConsentGranted: + adPersonalizationSignalsConsentGranted, + #adUserDataConsentGranted: adUserDataConsentGranted, + #functionalityStorageConsentGranted: + functionalityStorageConsentGranted, + #personalizationStorageConsentGranted: + personalizationStorageConsentGranted, + #securityStorageConsentGranted: securityStorageConsentGranted, + }), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future setAnalyticsCollectionEnabled(bool? enabled) => (super.noSuchMethod( - Invocation.method( - #setAnalyticsCollectionEnabled, - [enabled], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#setAnalyticsCollectionEnabled, [enabled]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future setUserId({ @@ -202,27 +167,23 @@ class MockFirebaseAnalyticsWeb extends _i1.Mock _i3.AnalyticsCallOptions? callOptions, }) => (super.noSuchMethod( - Invocation.method( - #setUserId, - [], - { - #id: id, - #callOptions: callOptions, - }, - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#setUserId, [], { + #id: id, + #callOptions: callOptions, + }), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override - _i5.Future resetAnalyticsData() => (super.noSuchMethod( - Invocation.method( - #resetAnalyticsData, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + _i5.Future resetAnalyticsData() => + (super.noSuchMethod( + Invocation.method(#resetAnalyticsData, []), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future setUserProperty({ @@ -231,51 +192,44 @@ class MockFirebaseAnalyticsWeb extends _i1.Mock _i3.AnalyticsCallOptions? callOptions, }) => (super.noSuchMethod( - Invocation.method( - #setUserProperty, - [], - { - #name: name, - #value: value, - #callOptions: callOptions, - }, - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#setUserProperty, [], { + #name: name, + #value: value, + #callOptions: callOptions, + }), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future setSessionTimeoutDuration(Duration? timeout) => (super.noSuchMethod( - Invocation.method( - #setSessionTimeoutDuration, - [timeout], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#setSessionTimeoutDuration, [timeout]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future setDefaultEventParameters( - Map? defaultParameters) => + Map? defaultParameters, + ) => (super.noSuchMethod( - Invocation.method( - #setDefaultEventParameters, - [defaultParameters], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#setDefaultEventParameters, [defaultParameters]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override - _i5.Future getAppInstanceId() => (super.noSuchMethod( - Invocation.method( - #getAppInstanceId, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + _i5.Future getAppInstanceId() => + (super.noSuchMethod( + Invocation.method(#getAppInstanceId, []), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future initiateOnDeviceConversionMeasurement({ @@ -285,17 +239,14 @@ class MockFirebaseAnalyticsWeb extends _i1.Mock String? hashedPhoneNumber, }) => (super.noSuchMethod( - Invocation.method( - #initiateOnDeviceConversionMeasurement, - [], - { - #emailAddress: emailAddress, - #phoneNumber: phoneNumber, - #hashedEmailAddress: hashedEmailAddress, - #hashedPhoneNumber: hashedPhoneNumber, - }, - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#initiateOnDeviceConversionMeasurement, [], { + #emailAddress: emailAddress, + #phoneNumber: phoneNumber, + #hashedEmailAddress: hashedEmailAddress, + #hashedPhoneNumber: hashedPhoneNumber, + }), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); } diff --git a/packages/firebase_app_check/firebase_app_check/example/integration_test/e2e_test.dart b/packages/firebase_app_check/firebase_app_check/example/integration_test/e2e_test.dart index db9f90b0508f..88d0dd3e5cda 100644 --- a/packages/firebase_app_check/firebase_app_check/example/integration_test/e2e_test.dart +++ b/packages/firebase_app_check/firebase_app_check/example/integration_test/e2e_test.dart @@ -13,8 +13,9 @@ import 'package:firebase_app_check_example/firebase_options.dart'; import 'report_test_results.dart'; -const androidDebugToken = - String.fromEnvironment('APP_CHECK_ANDROID_DEBUG_TOKEN'); +const androidDebugToken = String.fromEnvironment( + 'APP_CHECK_ANDROID_DEBUG_TOKEN', +); const appleDebugToken = String.fromEnvironment('APP_CHECK_APPLE_DEBUG_TOKEN'); @@ -22,205 +23,171 @@ void main() { final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized(); reportTestResultsToDriver(binding); - group( - 'firebase_app_check', - () { - setUpAll(() async { - // The native SDK may already have configured [DEFAULT] from a bundled - // GoogleService-Info.plist (the plugin registrant does this before any - // Dart runs). Dart's Firebase.apps cannot see that app until the first - // platform-channel call, so the only reliable guard is catching the - // duplicate-app error and keeping the natively configured instance. - try { - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); - } on FirebaseException catch (e) { - if (e.code != 'duplicate-app') { - rethrow; - } + group('firebase_app_check', () { + setUpAll(() async { + // The native SDK may already have configured [DEFAULT] from a bundled + // GoogleService-Info.plist (the plugin registrant does this before any + // Dart runs). Dart's Firebase.apps cannot see that app until the first + // platform-channel call, so the only reliable guard is catching the + // duplicate-app error and keeping the natively configured instance. + try { + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + } on FirebaseException catch (e) { + if (e.code != 'duplicate-app') { + rethrow; } - }); - - test( - 'activate', - () async { - await expectLater( - FirebaseAppCheck.instance.activate( - providerWeb: ReCaptchaV3Provider( - '6Lemcn0dAAAAABLkf6aiiHvpGD6x-zF3nOSDU2M8', - ), - ), - completes, - ); - }, + } + }); + + test('activate', () async { + await expectLater( + FirebaseAppCheck.instance.activate( + providerWeb: ReCaptchaV3Provider( + '6Lemcn0dAAAAABLkf6aiiHvpGD6x-zF3nOSDU2M8', + ), + ), + completes, ); - - test( - 'getToken', - () async { - try { - await FirebaseAppCheck.instance.getToken(true); - } catch (exception) { - // Needs a debug token pasted in the Firebase console to work so we catch the exception. - expect(exception, isA()); + }); + + test('getToken', () async { + try { + await FirebaseAppCheck.instance.getToken(true); + } catch (exception) { + // Needs a debug token pasted in the Firebase console to work so we catch the exception. + expect(exception, isA()); + } + }); + + test('getTokenResult', () async { + try { + final result = await FirebaseAppCheck.instance.getTokenResult(true); + if (result != null) { + expect(result.token, isNotEmpty); + if (!kIsWeb) { + expect(result.expirationTime, isNotNull); + expect(result.expirationTime!.isAfter(DateTime.now()), isTrue); } - }, - ); - - test( - 'getTokenResult', - () async { - try { - final result = await FirebaseAppCheck.instance.getTokenResult(true); - if (result != null) { - expect(result.token, isNotEmpty); - if (!kIsWeb) { - expect(result.expirationTime, isNotNull); - expect(result.expirationTime!.isAfter(DateTime.now()), isTrue); - } - } - } catch (exception) { - // Needs a debug token pasted in the Firebase console to work so we catch the exception. - expect(exception, isA()); - } - }, - ); - - test( - 'setTokenAutoRefreshEnabled', - () async { - await expectLater( - FirebaseAppCheck.instance.setTokenAutoRefreshEnabled(true), - completes, - ); - }, + } + } catch (exception) { + // Needs a debug token pasted in the Firebase console to work so we catch the exception. + expect(exception, isA()); + } + }); + + test('setTokenAutoRefreshEnabled', () async { + await expectLater( + FirebaseAppCheck.instance.setTokenAutoRefreshEnabled(true), + completes, ); - - test('onTokenChange', () async { - final stream = FirebaseAppCheck.instance.onTokenChange; - expect(stream, isA>()); - }); - - test( - 'getLimitedUseToken', - () async { - try { - await FirebaseAppCheck.instance.getLimitedUseToken(); - } catch (exception) { - // Needs a debug token pasted in the Firebase console to work so we catch the exception. - expect(exception, isA()); - } - }, + }); + + test('onTokenChange', () async { + final stream = FirebaseAppCheck.instance.onTokenChange; + expect(stream, isA>()); + }); + + test('getLimitedUseToken', () async { + try { + await FirebaseAppCheck.instance.getLimitedUseToken(); + } catch (exception) { + // Needs a debug token pasted in the Firebase console to work so we catch the exception. + expect(exception, isA()); + } + }); + + test('debugToken on Android', () async { + await expectLater( + FirebaseAppCheck.instance.activate( + providerAndroid: const AndroidDebugProvider(), + ), + completes, ); - - test( - 'debugToken on Android', - () async { - await expectLater( - FirebaseAppCheck.instance.activate( - providerAndroid: const AndroidDebugProvider(), - ), - completes, - ); - }, - skip: defaultTargetPlatform != TargetPlatform.android, + }, skip: defaultTargetPlatform != TargetPlatform.android); + + test('debugToken on iOS', () async { + await expectLater( + FirebaseAppCheck.instance.activate( + providerApple: const AppleDebugProvider(), + ), + completes, ); - - test( - 'debugToken on iOS', - () async { - await expectLater( - FirebaseAppCheck.instance.activate( - providerApple: const AppleDebugProvider(), - ), - completes, - ); - }, - skip: defaultTargetPlatform != TargetPlatform.iOS, - ); - - test( - 'appAttestWithDeviceCheckFallback falls back rather than erroring', - () async { - await FirebaseAppCheck.instance.activate( - providerApple: - const AppleAppAttestWithDeviceCheckFallbackProvider(), - ); - - // On devices without App Attest support — most Macs, and every - // simulator — the provider has to fall back to DeviceCheck. It used - // to pick App Attest purely on OS version and fail with "The - // attestation provider AppAttestProvider is not supported on current - // platform and OS version", so App Attest must not be the provider - // named in any error. Fetching a token can still fail beyond that - // (simulators do not support DeviceCheck either, and there is no - // debug token configured), which is fine here. - try { - await FirebaseAppCheck.instance.getToken(true); - } on FirebaseException catch (e) { - expect( - '${e.message}', - isNot(contains('AppAttestProvider')), - reason: 'the DeviceCheck fallback did not engage', - ); - } - }, - skip: defaultTargetPlatform != TargetPlatform.macOS && - defaultTargetPlatform != TargetPlatform.iOS - ? 'Apple platforms only.' - : null, - ); - - test( - 'uses Apple debug token when both Android and Apple debug tokens are configured', - () async { - await FirebaseAppCheck.instance.activate( - providerAndroid: const AndroidDebugProvider( - debugToken: androidDebugToken, - ), - providerApple: const AppleDebugProvider( - debugToken: appleDebugToken, - ), - ); - - await expectLater( - FirebaseAppCheck.instance.getToken(true), - completes, + }, skip: defaultTargetPlatform != TargetPlatform.iOS); + + test( + 'appAttestWithDeviceCheckFallback falls back rather than erroring', + () async { + await FirebaseAppCheck.instance.activate( + providerApple: const AppleAppAttestWithDeviceCheckFallbackProvider(), + ); + + // On devices without App Attest support — most Macs, and every + // simulator — the provider has to fall back to DeviceCheck. It used + // to pick App Attest purely on OS version and fail with "The + // attestation provider AppAttestProvider is not supported on current + // platform and OS version", so App Attest must not be the provider + // named in any error. Fetching a token can still fail beyond that + // (simulators do not support DeviceCheck either, and there is no + // debug token configured), which is fine here. + try { + await FirebaseAppCheck.instance.getToken(true); + } on FirebaseException catch (e) { + expect( + '${e.message}', + isNot(contains('AppAttestProvider')), + reason: 'the DeviceCheck fallback did not engage', ); - }, - skip: defaultTargetPlatform != TargetPlatform.iOS || - androidDebugToken.isEmpty || - appleDebugToken.isEmpty - ? 'Requires iOS plus APP_CHECK_ANDROID_DEBUG_TOKEN and ' + } + }, + skip: + defaultTargetPlatform != TargetPlatform.macOS && + defaultTargetPlatform != TargetPlatform.iOS + ? 'Apple platforms only.' + : null, + ); + + test( + 'uses Apple debug token when both Android and Apple debug tokens are configured', + () async { + await FirebaseAppCheck.instance.activate( + providerAndroid: const AndroidDebugProvider( + debugToken: androidDebugToken, + ), + providerApple: const AppleDebugProvider(debugToken: appleDebugToken), + ); + + await expectLater(FirebaseAppCheck.instance.getToken(true), completes); + }, + skip: + defaultTargetPlatform != TargetPlatform.iOS || + androidDebugToken.isEmpty || + appleDebugToken.isEmpty + ? 'Requires iOS plus APP_CHECK_ANDROID_DEBUG_TOKEN and ' 'APP_CHECK_APPLE_DEBUG_TOKEN dart-defines.' - : null, - ); - - test( - 'uses Android debug token when both Android and Apple debug tokens are configured', - () async { - await FirebaseAppCheck.instance.activate( - providerAndroid: const AndroidDebugProvider( - debugToken: androidDebugToken, - ), - providerApple: const AppleDebugProvider( - debugToken: appleDebugToken, - ), - ); - - await expectLater( - FirebaseAppCheck.instance.getToken(true), - completes, - ); - }, - skip: defaultTargetPlatform != TargetPlatform.android || - androidDebugToken.isEmpty || - appleDebugToken.isEmpty - ? 'Requires Android plus APP_CHECK_ANDROID_DEBUG_TOKEN and ' + : null, + ); + + test( + 'uses Android debug token when both Android and Apple debug tokens are configured', + () async { + await FirebaseAppCheck.instance.activate( + providerAndroid: const AndroidDebugProvider( + debugToken: androidDebugToken, + ), + providerApple: const AppleDebugProvider(debugToken: appleDebugToken), + ); + + await expectLater(FirebaseAppCheck.instance.getToken(true), completes); + }, + skip: + defaultTargetPlatform != TargetPlatform.android || + androidDebugToken.isEmpty || + appleDebugToken.isEmpty + ? 'Requires Android plus APP_CHECK_ANDROID_DEBUG_TOKEN and ' 'APP_CHECK_APPLE_DEBUG_TOKEN dart-defines.' - : null, - ); - }, - ); + : null, + ); + }); } diff --git a/packages/firebase_app_check/firebase_app_check/example/integration_test/report_test_results.dart b/packages/firebase_app_check/firebase_app_check/example/integration_test/report_test_results.dart index fb80e3ba19f7..db17f5dab066 100644 --- a/packages/firebase_app_check/firebase_app_check/example/integration_test/report_test_results.dart +++ b/packages/firebase_app_check/firebase_app_check/example/integration_test/report_test_results.dart @@ -26,8 +26,9 @@ void reportTestResultsToDriver(IntegrationTestWidgetsFlutterBinding binding) { for (final entry in binding.results.entries) if (entry.value is Failure) entry.key, ]; - bool didFail(String name) => failures - .any((failure) => name == failure || name.endsWith(' $failure')); + bool didFail(String name) => failures.any( + (failure) => name == failure || name.endsWith(' $failure'), + ); binding.reportData ??= {}; binding.reportData!['testResults'] = { diff --git a/packages/firebase_app_check/firebase_app_check/example/lib/firebase_options.dart b/packages/firebase_app_check/firebase_app_check/example/lib/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/firebase_app_check/firebase_app_check/example/lib/firebase_options.dart +++ b/packages/firebase_app_check/firebase_app_check/example/lib/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/firebase_app_check/firebase_app_check/example/lib/main.dart b/packages/firebase_app_check/firebase_app_check/example/lib/main.dart index 6e9c8225546c..06b9aec5940d 100644 --- a/packages/firebase_app_check/firebase_app_check/example/lib/main.dart +++ b/packages/firebase_app_check/firebase_app_check/example/lib/main.dart @@ -27,9 +27,7 @@ const kWindowsDebugToken = String.fromEnvironment( Future main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); + await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); // Activate app check after initialization, but before // usage of any Firebase services. @@ -66,10 +64,7 @@ class MyApp extends StatelessWidget { } class FirebaseAppCheckExample extends StatefulWidget { - FirebaseAppCheckExample({ - Key? key, - required this.title, - }) : super(key: key); + FirebaseAppCheckExample({Key? key, required this.title}) : super(key: key); final String title; @@ -134,7 +129,8 @@ class _FirebaseAppCheck extends State { providerWeb: web ?? ReCaptchaV3Provider(kWebRecaptchaSiteKey), providerWindows: windows ?? const WindowsDebugProvider(), ); - final providerName = windows?.runtimeType.toString() ?? + final providerName = + windows?.runtimeType.toString() ?? apple?.runtimeType.toString() ?? android?.runtimeType.toString() ?? web?.runtimeType.toString() ?? @@ -148,9 +144,7 @@ class _FirebaseAppCheck extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), + appBar: AppBar(title: Text(widget.title)), body: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( @@ -166,8 +160,9 @@ class _FirebaseAppCheck extends State { android: const AndroidDebugProvider(), apple: const AppleDebugProvider(), windows: WindowsDebugProvider( - debugToken: - kWindowsDebugToken.isNotEmpty ? kWindowsDebugToken : null, + debugToken: kWindowsDebugToken.isNotEmpty + ? kWindowsDebugToken + : null, ), ), child: const Text('activate(Debug)'), @@ -181,9 +176,8 @@ class _FirebaseAppCheck extends State { ), if (!kIsWeb) ElevatedButton( - onPressed: () => _activate( - apple: const AppleAppAttestProvider(), - ), + onPressed: () => + _activate(apple: const AppleAppAttestProvider()), child: const Text('activate(AppAttest)'), ), if (!kIsWeb) @@ -191,9 +185,7 @@ class _FirebaseAppCheck extends State { onPressed: () => _activate( apple: const AppleAppAttestWithDeviceCheckFallbackProvider(), ), - child: const Text( - 'activate(AppAttest + DeviceCheck fallback)', - ), + child: const Text('activate(AppAttest + DeviceCheck fallback)'), ), const SizedBox(height: 8), TextField( @@ -234,9 +226,7 @@ class _FirebaseAppCheck extends State { onPressed: () async { try { final token = await appCheck.getLimitedUseToken(); - setMessage( - 'Limited use token: ${token.substring(0, 20)}...', - ); + setMessage('Limited use token: ${token.substring(0, 20)}...'); } catch (e) { setMessage('getLimitedUseToken error: $e'); } diff --git a/packages/firebase_app_check/firebase_app_check/example/pubspec.yaml b/packages/firebase_app_check/firebase_app_check/example/pubspec.yaml index cac951ec6127..3b3762b318b3 100644 --- a/packages/firebase_app_check/firebase_app_check/example/pubspec.yaml +++ b/packages/firebase_app_check/firebase_app_check/example/pubspec.yaml @@ -7,8 +7,8 @@ version: 1.0.0+1 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: cloud_firestore: ^6.9.0 diff --git a/packages/firebase_app_check/firebase_app_check/example/test_driver/integration_test.dart b/packages/firebase_app_check/firebase_app_check/example/test_driver/integration_test.dart index 691723cbbfe1..9ccbcc26ab97 100644 --- a/packages/firebase_app_check/firebase_app_check/example/test_driver/integration_test.dart +++ b/packages/firebase_app_check/firebase_app_check/example/test_driver/integration_test.dart @@ -7,28 +7,32 @@ import 'dart:io'; import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver( - writeResponseOnFailure: true, - responseDataCallback: (Map? data) async { - final results = - (data?['testResults'] as Map?)?.cast() ?? - const {}; - var passed = 0; - var failed = 0; - for (final entry in results.entries) { - final ok = entry.value == 'success'; - ok ? passed++ : failed++; - // ignore: avoid_print - print('${ok ? '✅' : '❌'} ${entry.key}'); - } - // ignore: avoid_print - print('Web e2e summary: $passed passed, $failed failed, ' - '${results.length} total'); - if (results.isEmpty) { - // ignore: avoid_print - print('[E] No tests reported by the app - treating as ' - 'infrastructure failure.'); - exit(1); - } - await writeResponseData(data); - }, + writeResponseOnFailure: true, + responseDataCallback: (Map? data) async { + final results = + (data?['testResults'] as Map?)?.cast() ?? + const {}; + var passed = 0; + var failed = 0; + for (final entry in results.entries) { + final ok = entry.value == 'success'; + ok ? passed++ : failed++; + // ignore: avoid_print + print('${ok ? '✅' : '❌'} ${entry.key}'); + } + // ignore: avoid_print + print( + 'Web e2e summary: $passed passed, $failed failed, ' + '${results.length} total', ); + if (results.isEmpty) { + // ignore: avoid_print + print( + '[E] No tests reported by the app - treating as ' + 'infrastructure failure.', + ); + exit(1); + } + await writeResponseData(data); + }, +); diff --git a/packages/firebase_app_check/firebase_app_check/lib/src/firebase_app_check.dart b/packages/firebase_app_check/firebase_app_check/lib/src/firebase_app_check.dart index 0dabfbe90c3f..597a7523e94c 100644 --- a/packages/firebase_app_check/firebase_app_check/lib/src/firebase_app_check.dart +++ b/packages/firebase_app_check/firebase_app_check/lib/src/firebase_app_check.dart @@ -9,7 +9,7 @@ class FirebaseAppCheck extends FirebasePlugin implements FirebaseService { static Map _firebaseAppCheckInstances = {}; FirebaseAppCheck._({required this.app}) - : super(app.name, 'plugins.flutter.io/firebase_app_check'); + : super(app.name, 'plugins.flutter.io/firebase_app_check'); /// The [FirebaseApp] for this current [FirebaseAppCheck] instance. FirebaseApp app; @@ -24,9 +24,7 @@ class FirebaseAppCheck extends FirebasePlugin implements FirebaseService { /// If called and no [_delegatePackingProperty] exists, it will first be /// created and assigned before returning the delegate. FirebaseAppCheckPlatform get _delegate { - _delegatePackingProperty ??= FirebaseAppCheckPlatform.instanceFor( - app: app, - ); + _delegatePackingProperty ??= FirebaseAppCheckPlatform.instanceFor(app: app); return _delegatePackingProperty!; } diff --git a/packages/firebase_app_check/firebase_app_check/pubspec.yaml b/packages/firebase_app_check/firebase_app_check/pubspec.yaml index ee3b4e2954f3..e08225d82dfd 100644 --- a/packages/firebase_app_check/firebase_app_check/pubspec.yaml +++ b/packages/firebase_app_check/firebase_app_check/pubspec.yaml @@ -14,8 +14,8 @@ false_secrets: - example/** environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_app_check_platform_interface: ^0.4.2+1 diff --git a/packages/firebase_app_check/firebase_app_check/test/firebase_app_check_test.dart b/packages/firebase_app_check/firebase_app_check/test/firebase_app_check_test.dart index f939040d5708..3769df046102 100755 --- a/packages/firebase_app_check/firebase_app_check/test/firebase_app_check_test.dart +++ b/packages/firebase_app_check/firebase_app_check/test/firebase_app_check_test.dart @@ -43,37 +43,39 @@ void main() { expect(appCheck.app.name, 'secondaryApp'); }); - test('creates a fresh instance after app delete and reinitialize', - () async { - const appName = 'delete-reinit-app-check'; - const options = FirebaseOptions( - appId: '1:1234567890:ios:42424242424242', - apiKey: '123', - projectId: '123', - messagingSenderId: '1234567890', - ); - final app = await Firebase.initializeApp( - name: appName, - options: options, - ); - final appCheck1 = FirebaseAppCheck.instanceFor(app: app); + test( + 'creates a fresh instance after app delete and reinitialize', + () async { + const appName = 'delete-reinit-app-check'; + const options = FirebaseOptions( + appId: '1:1234567890:ios:42424242424242', + apiKey: '123', + projectId: '123', + messagingSenderId: '1234567890', + ); + final app = await Firebase.initializeApp( + name: appName, + options: options, + ); + final appCheck1 = FirebaseAppCheck.instanceFor(app: app); - expect(app.getService(), same(appCheck1)); + expect(app.getService(), same(appCheck1)); - await app.delete(); + await app.delete(); - final app2 = await Firebase.initializeApp( - name: appName, - options: options, - ); - addTearDown(app2.delete); + final app2 = await Firebase.initializeApp( + name: appName, + options: options, + ); + addTearDown(app2.delete); - final appCheck2 = FirebaseAppCheck.instanceFor(app: app2); + final appCheck2 = FirebaseAppCheck.instanceFor(app: app2); - expect(appCheck2, isNot(same(appCheck1))); - expect(appCheck2.app, app2); - expect(app2.getService(), same(appCheck2)); - }); + expect(appCheck2, isNot(same(appCheck1))); + expect(appCheck2.app, app2); + expect(app2.getService(), same(appCheck2)); + }, + ); }); }); } diff --git a/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/android_provider.dart b/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/android_provider.dart index 93cfdf5c012d..89002a40748b 100644 --- a/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/android_provider.dart +++ b/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/android_provider.dart @@ -7,5 +7,5 @@ enum AndroidProvider { // The debug provider debug, // The play integrity provider (Firebase recommended) - playIntegrity + playIntegrity, } diff --git a/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/app_check_token_result.dart b/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/app_check_token_result.dart index bbe2a05dbe89..75b2015f964b 100644 --- a/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/app_check_token_result.dart +++ b/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/app_check_token_result.dart @@ -5,10 +5,7 @@ /// An App Check token and its associated metadata. class AppCheckTokenResult { /// Creates an App Check token result. - const AppCheckTokenResult({ - required this.token, - this.expirationTime, - }); + const AppCheckTokenResult({required this.token, this.expirationTime}); /// The App Check token JWT string. final String token; diff --git a/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/apple_provider.dart b/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/apple_provider.dart index 810e2660d673..114f73097c2e 100644 --- a/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/apple_provider.dart +++ b/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/apple_provider.dart @@ -16,5 +16,5 @@ enum AppleProvider { /// appAttest provider is only available on iOS 14.0+, macOS 14.0+ so this will fall back to deviceCheck provider if appAtest provider /// is not available - appAttestWithDeviceCheckFallback + appAttestWithDeviceCheckFallback, } diff --git a/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/apple_providers.dart b/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/apple_providers.dart index 9b74b145aa76..a84679abd2e9 100644 --- a/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/apple_providers.dart +++ b/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/apple_providers.dart @@ -52,7 +52,7 @@ class AppleAppAttestProvider extends AppleAppCheckProvider { class AppleAppAttestWithDeviceCheckFallbackProvider extends AppleAppCheckProvider { const AppleAppAttestWithDeviceCheckFallbackProvider() - : super('appAttestWithDeviceCheckFallback'); + : super('appAttestWithDeviceCheckFallback'); } /// reCAPTCHA provider for Apple platforms. diff --git a/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/method_channel/method_channel_firebase_app_check.dart b/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/method_channel/method_channel_firebase_app_check.dart index be033a61b73f..dfbe12b06c8b 100644 --- a/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/method_channel/method_channel_firebase_app_check.dart +++ b/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/method_channel/method_channel_firebase_app_check.dart @@ -17,7 +17,7 @@ import 'utils/provider_to_string.dart'; class MethodChannelFirebaseAppCheck extends FirebaseAppCheckPlatform { /// Create an instance of [MethodChannelFirebaseAppCheck]. MethodChannelFirebaseAppCheck({required FirebaseApp app}) - : super(appInstance: app) { + : super(appInstance: app) { _tokenChangesListeners[app.name] = StreamController.broadcast(); _listenerRegistration = _registerTokenListener(app); } @@ -33,13 +33,13 @@ class MethodChannelFirebaseAppCheck extends FirebaseAppCheckPlatform { _subscription = events .receiveGuardedBroadcastStream(onError: convertPlatformException) .listen((arguments) { - // ignore: close_sinks - final controller = _tokenChangesListeners[app.name]; - if (!_isDisposed && controller != null) { - Map result = arguments; - controller.add(result['token'] as String?); - } - }); + // ignore: close_sinks + final controller = _tokenChangesListeners[app.name]; + if (!_isDisposed && controller != null) { + Map result = arguments; + controller.add(result['token'] as String?); + } + }); // ignore: avoid_catches_without_on_clauses } catch (_) { // Silently ignore errors during token listener registration. @@ -51,7 +51,7 @@ class MethodChannelFirebaseAppCheck extends FirebaseAppCheckPlatform { {}; static Map - _methodChannelFirebaseAppCheckInstances = + _methodChannelFirebaseAppCheckInstances = {}; /// The Pigeon API used for platform communication. diff --git a/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/pigeon/messages.pigeon.dart b/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/pigeon/messages.pigeon.dart index 6033bf98471a..4c751114e278 100644 --- a/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/pigeon/messages.pigeon.dart +++ b/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/pigeon/messages.pigeon.dart @@ -49,8 +49,9 @@ bool _deepEquals(Object? a, Object? b) { } if (a is List && b is List) { return a.length == b.length && - a.indexed - .every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1])); + a.indexed.every( + ((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]), + ); } if (a is Map && b is Map) { if (a.length != b.length) { @@ -100,20 +101,14 @@ int _deepHash(Object? value) { } class InternalAppCheckTokenResult { - InternalAppCheckTokenResult({ - required this.token, - this.expirationTimestamp, - }); + InternalAppCheckTokenResult({required this.token, this.expirationTimestamp}); String token; int? expirationTimestamp; List _toList() { - return [ - token, - expirationTimestamp, - ]; + return [token, expirationTimestamp]; } Object encode() { @@ -177,11 +172,13 @@ class FirebaseAppCheckHostApi { /// Constructor for [FirebaseAppCheckHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - FirebaseAppCheckHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + FirebaseAppCheckHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -189,11 +186,12 @@ class FirebaseAppCheckHostApi { final String pigeonVar_messageChannelSuffix; Future activate( - String appName, - String? androidProvider, - String? appleProvider, - String? debugToken, - String? recaptchaSiteKey) async { + String appName, + String? androidProvider, + String? appleProvider, + String? debugToken, + String? recaptchaSiteKey, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.activate$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -201,14 +199,15 @@ class FirebaseAppCheckHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel - .send([ - appName, - androidProvider, - appleProvider, - debugToken, - recaptchaSiteKey - ]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [ + appName, + androidProvider, + appleProvider, + debugToken, + recaptchaSiteKey, + ], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -226,8 +225,9 @@ class FirebaseAppCheckHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName, forceRefresh]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName, forceRefresh], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -239,7 +239,9 @@ class FirebaseAppCheckHostApi { } Future getTokenResult( - String appName, bool forceRefresh) async { + String appName, + bool forceRefresh, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.getTokenResult$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -247,8 +249,9 @@ class FirebaseAppCheckHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName, forceRefresh]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName, forceRefresh], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -260,7 +263,9 @@ class FirebaseAppCheckHostApi { } Future setTokenAutoRefreshEnabled( - String appName, bool isTokenAutoRefreshEnabled) async { + String appName, + bool isTokenAutoRefreshEnabled, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.setTokenAutoRefreshEnabled$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -268,8 +273,9 @@ class FirebaseAppCheckHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName, isTokenAutoRefreshEnabled]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName, isTokenAutoRefreshEnabled], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -287,8 +293,9 @@ class FirebaseAppCheckHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -307,8 +314,9 @@ class FirebaseAppCheckHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( diff --git a/packages/firebase_app_check/firebase_app_check_platform_interface/pigeons/messages.dart b/packages/firebase_app_check/firebase_app_check_platform_interface/pigeons/messages.dart index bdd4d0673002..0afbe211ae9e 100644 --- a/packages/firebase_app_check/firebase_app_check_platform_interface/pigeons/messages.dart +++ b/packages/firebase_app_check/firebase_app_check_platform_interface/pigeons/messages.dart @@ -5,10 +5,7 @@ import 'package:pigeon/pigeon.dart'; class InternalAppCheckTokenResult { - InternalAppCheckTokenResult({ - required this.token, - this.expirationTimestamp, - }); + InternalAppCheckTokenResult({required this.token, this.expirationTimestamp}); String token; diff --git a/packages/firebase_app_check/firebase_app_check_platform_interface/pubspec.yaml b/packages/firebase_app_check/firebase_app_check_platform_interface/pubspec.yaml index d0ed97c6ba1b..c76e31acaa0a 100644 --- a/packages/firebase_app_check/firebase_app_check_platform_interface/pubspec.yaml +++ b/packages/firebase_app_check/firebase_app_check_platform_interface/pubspec.yaml @@ -5,8 +5,8 @@ version: 0.4.2+1 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_app_check/firebase_app_check_platform_interface/test/method_channel_tests/method_channel_firebase_app_check_test.dart b/packages/firebase_app_check/firebase_app_check_platform_interface/test/method_channel_tests/method_channel_firebase_app_check_test.dart index e64bff5f1f9c..fceefde85c84 100644 --- a/packages/firebase_app_check/firebase_app_check_platform_interface/test/method_channel_tests/method_channel_firebase_app_check_test.dart +++ b/packages/firebase_app_check/firebase_app_check_platform_interface/test/method_channel_tests/method_channel_firebase_app_check_test.dart @@ -33,19 +33,19 @@ void main() { debugDefaultTargetPlatformOverride = null; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMessageHandler( - 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.activate', - null, - ); + 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.activate', + null, + ); TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMessageHandler( - 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.getToken', - null, - ); + 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.getToken', + null, + ); TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMessageHandler( - 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.getTokenResult', - null, - ); + 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.getTokenResult', + null, + ); }); group('delegateFor()', () { @@ -73,35 +73,36 @@ void main() { setUp(() { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMessageHandler( - 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.getToken', - (ByteData? message) async { - return FirebaseAppCheckHostApi.pigeonChannelCodec.encodeMessage( - ['test-token'], + 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.getToken', + (ByteData? message) async { + return FirebaseAppCheckHostApi.pigeonChannelCodec.encodeMessage( + ['test-token'], + ); + }, ); - }, - ); TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMessageHandler( - 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.getTokenResult', - (ByteData? message) async { - return FirebaseAppCheckHostApi.pigeonChannelCodec.encodeMessage( - [ - InternalAppCheckTokenResult( - token: 'test-token', - expirationTimestamp: expirationTimestamp, - ), - ], + 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.getTokenResult', + (ByteData? message) async { + return FirebaseAppCheckHostApi.pigeonChannelCodec + .encodeMessage([ + InternalAppCheckTokenResult( + token: 'test-token', + expirationTimestamp: expirationTimestamp, + ), + ]); + }, ); - }, - ); }); - test('returns the token string without changing the existing API', - () async { - final appCheck = MethodChannelFirebaseAppCheck(app: secondaryApp); + test( + 'returns the token string without changing the existing API', + () async { + final appCheck = MethodChannelFirebaseAppCheck(app: secondaryApp); - expect(await appCheck.getToken(true), 'test-token'); - }); + expect(await appCheck.getToken(true), 'test-token'); + }, + ); test('returns token metadata', () async { final appCheck = MethodChannelFirebaseAppCheck(app: secondaryApp); @@ -122,17 +123,19 @@ void main() { final calls = >[]; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMessageHandler( - 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.activate', - (ByteData? message) async { - calls.add( - FirebaseAppCheckHostApi.pigeonChannelCodec.decodeMessage(message)! - as List, + 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.activate', + (ByteData? message) async { + calls.add( + FirebaseAppCheckHostApi.pigeonChannelCodec.decodeMessage( + message, + )! + as List, + ); + return FirebaseAppCheckHostApi.pigeonChannelCodec.encodeMessage( + [], + ); + }, ); - return FirebaseAppCheckHostApi.pigeonChannelCodec.encodeMessage( - [], - ); - }, - ); final appCheck = MethodChannelFirebaseAppCheck(app: secondaryApp); @@ -154,17 +157,19 @@ void main() { final calls = >[]; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMessageHandler( - 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.activate', - (ByteData? message) async { - calls.add( - FirebaseAppCheckHostApi.pigeonChannelCodec.decodeMessage(message)! - as List, + 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.activate', + (ByteData? message) async { + calls.add( + FirebaseAppCheckHostApi.pigeonChannelCodec.decodeMessage( + message, + )! + as List, + ); + return FirebaseAppCheckHostApi.pigeonChannelCodec.encodeMessage( + [], + ); + }, ); - return FirebaseAppCheckHostApi.pigeonChannelCodec.encodeMessage( - [], - ); - }, - ); final appCheck = MethodChannelFirebaseAppCheck(app: secondaryApp); @@ -190,15 +195,17 @@ void main() { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMessageHandler( - 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.activate', - (message) async { - final list = const StandardMessageCodec().decodeMessage(message) - as List; - log.add(list); - return const StandardMessageCodec() - .encodeMessage([null]); // Return success - }, - ); + 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.activate', + (message) async { + final list = + const StandardMessageCodec().decodeMessage(message) + as List; + log.add(list); + return const StandardMessageCodec().encodeMessage([ + null, + ]); // Return success + }, + ); await appCheck.activate( providerAndroid: const AndroidReCaptchaProvider('test-site-key'), @@ -218,15 +225,17 @@ void main() { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMessageHandler( - 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.activate', - (message) async { - final list = const StandardMessageCodec().decodeMessage(message) - as List; - log.add(list); - return const StandardMessageCodec() - .encodeMessage([null]); // Return success - }, - ); + 'dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.activate', + (message) async { + final list = + const StandardMessageCodec().decodeMessage(message) + as List; + log.add(list); + return const StandardMessageCodec().encodeMessage([ + null, + ]); // Return success + }, + ); await appCheck.activate( providerApple: const AppleReCaptchaProvider('test-site-key'), diff --git a/packages/firebase_app_check/firebase_app_check_platform_interface/test/method_channel_tests/utils/provider_to_string_test.dart b/packages/firebase_app_check/firebase_app_check_platform_interface/test/method_channel_tests/utils/provider_to_string_test.dart index 63f7eded20cd..04b31362dfce 100644 --- a/packages/firebase_app_check/firebase_app_check_platform_interface/test/method_channel_tests/utils/provider_to_string_test.dart +++ b/packages/firebase_app_check/firebase_app_check_platform_interface/test/method_channel_tests/utils/provider_to_string_test.dart @@ -12,34 +12,37 @@ import 'package:flutter_test/flutter_test.dart'; void main() { group('getAndroidProviderString', () { test( - 'returns new provider type when both providers are provided and legacy is default', - () { - final result = getAndroidProviderString( - legacyProvider: AndroidProvider.playIntegrity, - newProvider: const AndroidPlayIntegrityProvider(), - ); - expect(result, 'playIntegrity'); - }); + 'returns new provider type when both providers are provided and legacy is default', + () { + final result = getAndroidProviderString( + legacyProvider: AndroidProvider.playIntegrity, + newProvider: const AndroidPlayIntegrityProvider(), + ); + expect(result, 'playIntegrity'); + }, + ); test( - 'returns legacy provider when explicitly set to debug and new provider is default', - () { - final result = getAndroidProviderString( - legacyProvider: AndroidProvider.debug, - newProvider: const AndroidPlayIntegrityProvider(), - ); - expect(result, 'debug'); - }); + 'returns legacy provider when explicitly set to debug and new provider is default', + () { + final result = getAndroidProviderString( + legacyProvider: AndroidProvider.debug, + newProvider: const AndroidPlayIntegrityProvider(), + ); + expect(result, 'debug'); + }, + ); test( - 'returns new provider type when only new provider is provided and legacy is default', - () { - final result = getAndroidProviderString( - legacyProvider: AndroidProvider.playIntegrity, - newProvider: const AndroidDebugProvider(), - ); - expect(result, 'debug'); - }); + 'returns new provider type when only new provider is provided and legacy is default', + () { + final result = getAndroidProviderString( + legacyProvider: AndroidProvider.playIntegrity, + newProvider: const AndroidDebugProvider(), + ); + expect(result, 'debug'); + }, + ); test('returns default when neither provider is provided', () { final result = getAndroidProviderString(); @@ -57,54 +60,59 @@ void main() { }); test( - 'returns legacy provider when explicitly set to debug and new provider is default', - () { - final result = getAppleProviderString( - legacyProvider: AppleProvider.debug, - newProvider: const AppleDeviceCheckProvider(), - ); - expect(result, 'debug'); - }); + 'returns legacy provider when explicitly set to debug and new provider is default', + () { + final result = getAppleProviderString( + legacyProvider: AppleProvider.debug, + newProvider: const AppleDeviceCheckProvider(), + ); + expect(result, 'debug'); + }, + ); test( - 'returns legacy provider when explicitly set to appAttest and new provider is default', - () { - final result = getAppleProviderString( - legacyProvider: AppleProvider.appAttest, - newProvider: const AppleDeviceCheckProvider(), - ); - expect(result, 'appAttest'); - }); + 'returns legacy provider when explicitly set to appAttest and new provider is default', + () { + final result = getAppleProviderString( + legacyProvider: AppleProvider.appAttest, + newProvider: const AppleDeviceCheckProvider(), + ); + expect(result, 'appAttest'); + }, + ); test( - 'returns legacy provider when explicitly set to appAttestWithDeviceCheckFallback and new provider is default', - () { - final result = getAppleProviderString( - legacyProvider: AppleProvider.appAttestWithDeviceCheckFallback, - newProvider: const AppleDeviceCheckProvider(), - ); - expect(result, 'appAttestWithDeviceCheckFallback'); - }); + 'returns legacy provider when explicitly set to appAttestWithDeviceCheckFallback and new provider is default', + () { + final result = getAppleProviderString( + legacyProvider: AppleProvider.appAttestWithDeviceCheckFallback, + newProvider: const AppleDeviceCheckProvider(), + ); + expect(result, 'appAttestWithDeviceCheckFallback'); + }, + ); test( - 'returns new provider type when new provider is provided and legacy is default', - () { - final result = getAppleProviderString( - legacyProvider: AppleProvider.deviceCheck, - newProvider: const AppleDebugProvider(), - ); - expect(result, 'debug'); - }); + 'returns new provider type when new provider is provided and legacy is default', + () { + final result = getAppleProviderString( + legacyProvider: AppleProvider.deviceCheck, + newProvider: const AppleDebugProvider(), + ); + expect(result, 'debug'); + }, + ); test( - 'returns legacy provider when new provider is provided and legacy is default', - () { - final result = getAppleProviderString( - legacyProvider: AppleProvider.deviceCheck, - newProvider: const AppleAppAttestProvider(), - ); - expect(result, 'appAttest'); - }); + 'returns legacy provider when new provider is provided and legacy is default', + () { + final result = getAppleProviderString( + legacyProvider: AppleProvider.deviceCheck, + newProvider: const AppleAppAttestProvider(), + ); + expect(result, 'appAttest'); + }, + ); test('returns default when neither provider is provided', () { final result = getAppleProviderString(); @@ -112,13 +120,14 @@ void main() { }); test( - 'returns new provider when explicitly set to appAttestWithDeviceCheckFallback', - () { - final result = getAppleProviderString( - legacyProvider: AppleProvider.deviceCheck, - newProvider: const AppleAppAttestWithDeviceCheckFallbackProvider(), - ); - expect(result, 'appAttestWithDeviceCheckFallback'); - }); + 'returns new provider when explicitly set to appAttestWithDeviceCheckFallback', + () { + final result = getAppleProviderString( + legacyProvider: AppleProvider.deviceCheck, + newProvider: const AppleAppAttestWithDeviceCheckFallbackProvider(), + ); + expect(result, 'appAttestWithDeviceCheckFallback'); + }, + ); }); } diff --git a/packages/firebase_app_check/firebase_app_check_platform_interface/test/platform_interface_tests/platform_interface_app_check_test.dart b/packages/firebase_app_check/firebase_app_check_platform_interface/test/platform_interface_tests/platform_interface_app_check_test.dart index 21f7050abd23..0a494cf1dca1 100644 --- a/packages/firebase_app_check/firebase_app_check_platform_interface/test/platform_interface_tests/platform_interface_app_check_test.dart +++ b/packages/firebase_app_check/firebase_app_check_platform_interface/test/platform_interface_tests/platform_interface_app_check_test.dart @@ -30,9 +30,7 @@ void main() { ), ); - firebaseAppCheckPlatform = TestFirebaseAppCheckPlatform( - app, - ); + firebaseAppCheckPlatform = TestFirebaseAppCheckPlatform(app); }); test('Constructor', () { @@ -52,8 +50,9 @@ void main() { }); test('set.instance', () { - FirebaseAppCheckPlatform.instance = - TestFirebaseAppCheckPlatform(secondaryApp); + FirebaseAppCheckPlatform.instance = TestFirebaseAppCheckPlatform( + secondaryApp, + ); expect( FirebaseAppCheckPlatform.instance, diff --git a/packages/firebase_app_check/firebase_app_check_web/lib/firebase_app_check_web.dart b/packages/firebase_app_check/firebase_app_check_web/lib/firebase_app_check_web.dart index 7b1abae9f041..de2763de8057 100644 --- a/packages/firebase_app_check/firebase_app_check_web/lib/firebase_app_check_web.dart +++ b/packages/firebase_app_check/firebase_app_check_web/lib/firebase_app_check_web.dart @@ -27,9 +27,7 @@ class FirebaseAppCheckWeb extends FirebaseAppCheckPlatform { /// Stub initializer to allow the [registerWith] to create an instance without /// registering the web delegates or listeners. - FirebaseAppCheckWeb._() - : _webAppCheck = null, - super(appInstance: null); + FirebaseAppCheckWeb._() : _webAppCheck = null, super(appInstance: null); /// The entry point for the [FirebaseAuthWeb] class. FirebaseAppCheckWeb({required FirebaseApp app}) : super(appInstance: app); @@ -42,26 +40,32 @@ class FirebaseAppCheckWeb extends FirebaseAppCheckPlatform { 'app-check', productNameOverride: 'app_check', ensurePluginInitialized: (firebaseApp) async { - final instance = - FirebaseAppCheckWeb(app: Firebase.app(firebaseApp.name)); - var recaptchaType = web.window.localStorage - .getItem(_sessionKeyRecaptchaType(firebaseApp.name)); - var recaptchaSiteKey = web.window.localStorage - .getItem(_sessionKeyRecaptchaSiteKey(firebaseApp.name)); + final instance = FirebaseAppCheckWeb( + app: Firebase.app(firebaseApp.name), + ); + var recaptchaType = web.window.localStorage.getItem( + _sessionKeyRecaptchaType(firebaseApp.name), + ); + var recaptchaSiteKey = web.window.localStorage.getItem( + _sessionKeyRecaptchaSiteKey(firebaseApp.name), + ); // For backwards compatibility, with previously used session storage if (recaptchaType == null || recaptchaSiteKey == null) { - recaptchaType = web.window.sessionStorage - .getItem(_sessionKeyRecaptchaType(firebaseApp.name)); - recaptchaSiteKey = web.window.sessionStorage - .getItem(_sessionKeyRecaptchaSiteKey(firebaseApp.name)); + recaptchaType = web.window.sessionStorage.getItem( + _sessionKeyRecaptchaType(firebaseApp.name), + ); + recaptchaSiteKey = web.window.sessionStorage.getItem( + _sessionKeyRecaptchaSiteKey(firebaseApp.name), + ); } if (recaptchaType != null) { final WebProvider provider; if (recaptchaType == recaptchaTypeDebug) { - final debugToken = - recaptchaSiteKey?.isNotEmpty ?? false ? recaptchaSiteKey : null; + final debugToken = recaptchaSiteKey?.isNotEmpty ?? false + ? recaptchaSiteKey + : null; provider = WebDebugProvider(debugToken: debugToken); } else if (recaptchaSiteKey != null) { if (recaptchaType == recaptchaTypeV3) { @@ -102,7 +106,8 @@ class FirebaseAppCheckWeb extends FirebaseAppCheckPlatform { app_check_interop.AppCheck? get _delegate { if (_webAppCheck == null) { throw Exception( - "Before using other Firebase App Check APIs, FirebaseAppCheck.instance.activate() must be called first once you've initialized your Firebase app."); + "Before using other Firebase App Check APIs, FirebaseAppCheck.instance.activate() must be called first once you've initialized your Firebase app.", + ); } return _webAppCheck; } @@ -146,19 +151,24 @@ class FirebaseAppCheckWeb extends FirebaseAppCheckPlatform { } else { throw Exception('Invalid web provider: $webProvider'); } - web.window.localStorage - .setItem(_sessionKeyRecaptchaType(app.name), recaptchaType); web.window.localStorage.setItem( - _sessionKeyRecaptchaSiteKey(app.name), - webProvider is WebDebugProvider - ? webProvider.debugToken ?? '' - : webProvider.siteKey); + _sessionKeyRecaptchaType(app.name), + recaptchaType, + ); + web.window.localStorage.setItem( + _sessionKeyRecaptchaSiteKey(app.name), + webProvider is WebDebugProvider + ? webProvider.debugToken ?? '' + : webProvider.siteKey, + ); } // activate API no longer exists, recaptcha key has to be passed on initialization of app-check instance. return convertWebExceptions>(() async { _webAppCheck ??= app_check_interop.getAppCheckInstance( - core_interop.app(app.name), webProvider); + core_interop.app(app.name), + webProvider, + ); _initialiseStreamController(); }); } @@ -172,18 +182,20 @@ class FirebaseAppCheckWeb extends FirebaseAppCheckPlatform { _delegate!.idTokenChangedController?.close(); }, ); - _delegate!.onTokenChanged(app.name).listen( - (event) { - _tokenChangesListeners[app.name]!.add(event.token.toDart); - }, - // Forward JS SDK errors (e.g. network failures during background - // token refresh) to the broadcast controller instead of letting them - // surface as unhandled zone errors. If nobody is listening on the - // broadcast stream the error is silently dropped. - onError: (Object error) { - _tokenChangesListeners[app.name]?.addError(error); - }, - ); + _delegate! + .onTokenChanged(app.name) + .listen( + (event) { + _tokenChangesListeners[app.name]!.add(event.token.toDart); + }, + // Forward JS SDK errors (e.g. network failures during background + // token refresh) to the broadcast controller instead of letting them + // surface as unhandled zone errors. If nobody is listening on the + // broadcast stream the error is silently dropped. + onError: (Object error) { + _tokenChangesListeners[app.name]?.addError(error); + }, + ); } } @@ -195,8 +207,8 @@ class FirebaseAppCheckWeb extends FirebaseAppCheckPlatform { @override Future getTokenResult(bool forceRefresh) async { return convertWebExceptions>(() async { - app_check_interop.AppCheckTokenResultJsImpl result = - await _delegate!.getToken(forceRefresh); + app_check_interop.AppCheckTokenResultJsImpl result = await _delegate! + .getToken(forceRefresh); return AppCheckTokenResult(token: result.token.toDart); }); } @@ -204,8 +216,8 @@ class FirebaseAppCheckWeb extends FirebaseAppCheckPlatform { @override Future getLimitedUseToken() async { return convertWebExceptions>(() async { - app_check_interop.AppCheckTokenResultJsImpl result = - await _delegate!.getLimitedUseToken(); + app_check_interop.AppCheckTokenResultJsImpl result = await _delegate! + .getLimitedUseToken(); return result.token.toDart; }); } @@ -223,8 +235,6 @@ class FirebaseAppCheckWeb extends FirebaseAppCheckPlatform { @override Stream get onTokenChange { _initialiseStreamController(); - return convertWebExceptions( - () => _tokenChangesListeners[app.name]!.stream, - ); + return convertWebExceptions(() => _tokenChangesListeners[app.name]!.stream); } } diff --git a/packages/firebase_app_check/firebase_app_check_web/lib/src/interop/app_check.dart b/packages/firebase_app_check/firebase_app_check_web/lib/src/interop/app_check.dart index a22243af3e2e..648f96b86e61 100644 --- a/packages/firebase_app_check/firebase_app_check_web/lib/src/interop/app_check.dart +++ b/packages/firebase_app_check/firebase_app_check_web/lib/src/interop/app_check.dart @@ -40,8 +40,9 @@ AppCheck? getAppCheckInstance([App? app, WebProvider? provider]) { } else if (provider is ReCaptchaV3Provider) { jsProvider = app_check_interop.ReCaptchaV3Provider(provider.siteKey.toJS); } else if (provider is ReCaptchaEnterpriseProvider) { - jsProvider = - app_check_interop.ReCaptchaEnterpriseProvider(provider.siteKey.toJS); + jsProvider = app_check_interop.ReCaptchaEnterpriseProvider( + provider.siteKey.toJS, + ); } else { throw ArgumentError( 'A `WebProvider` is required for `activate()` to initialise App Check on the web platform', @@ -69,7 +70,7 @@ class AppCheck extends JsObjectWrapper { } AppCheck._fromJsObject(app_check_interop.AppCheckJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); void setTokenAutoRefreshEnabled(bool isTokenAutoRefreshEnabled) => app_check_interop.setTokenAutoRefreshEnabled( @@ -79,8 +80,7 @@ class AppCheck extends JsObjectWrapper { Future getToken( bool? forceRefresh, - ) => - app_check_interop.getToken(jsObject, forceRefresh?.toJS).toDart; + ) => app_check_interop.getToken(jsObject, forceRefresh?.toJS).toDart; Future getLimitedUseToken() => app_check_interop.getLimitedUseToken(jsObject).toDart; @@ -88,11 +88,11 @@ class AppCheck extends JsObjectWrapper { JSFunction? _idTokenChangedUnsubscribe; StreamController? - get idTokenChangedController => _idTokenChangedController; + get idTokenChangedController => _idTokenChangedController; StreamController? - // ignore: close_sinks - _idTokenChangedController; + // ignore: close_sinks + _idTokenChangedController; // purely for debug mode and tracking listeners to clean up on "hot restart" final Map _tokenListeners = {}; @@ -117,11 +117,12 @@ class AppCheck extends JsObjectWrapper { if (_idTokenChangedController == null) { final nextWrapper = ((app_check_interop.AppCheckTokenResultJsImpl result) { - _idTokenChangedController!.add(result); - }).toJS; + _idTokenChangedController!.add(result); + }).toJS; - final errorWrapper = - ((JSError e) => _idTokenChangedController!.addError(e)).toJS; + final errorWrapper = ((JSError e) => _idTokenChangedController!.addError( + e, + )).toJS; void startListen() { _idTokenChangedUnsubscribe = app_check_interop.onTokenChanged( @@ -139,12 +140,10 @@ class AppCheck extends JsObjectWrapper { removeWindowsListener(appCheckWindowsKey); } - _idTokenChangedController = StreamController< - app_check_interop.AppCheckTokenResultJsImpl>.broadcast( - onListen: startListen, - onCancel: stopListen, - sync: true, - ); + _idTokenChangedController = + StreamController< + app_check_interop.AppCheckTokenResultJsImpl + >.broadcast(onListen: startListen, onCancel: stopListen, sync: true); } return _idTokenChangedController!.stream; diff --git a/packages/firebase_app_check/firebase_app_check_web/pubspec.yaml b/packages/firebase_app_check/firebase_app_check_web/pubspec.yaml index 5d254ce78f11..913d5924d549 100644 --- a/packages/firebase_app_check/firebase_app_check_web/pubspec.yaml +++ b/packages/firebase_app_check/firebase_app_check_web/pubspec.yaml @@ -5,8 +5,8 @@ version: 0.2.6+1 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.22.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_app_check/firebase_app_check_web/test/firebase_app_check_web_test.dart b/packages/firebase_app_check/firebase_app_check_web/test/firebase_app_check_web_test.dart index dd91f9bde80a..6f5bcfc8ab25 100644 --- a/packages/firebase_app_check/firebase_app_check_web/test/firebase_app_check_web_test.dart +++ b/packages/firebase_app_check/firebase_app_check_web/test/firebase_app_check_web_test.dart @@ -34,27 +34,15 @@ void main() { test('activate with ReCaptchaV3Provider', () async { final provider = ReCaptchaV3Provider('key'); - await appCheck.activate( - webProvider: provider, - ); - verify( - appCheck.activate( - webProvider: provider, - ), - ); + await appCheck.activate(webProvider: provider); + verify(appCheck.activate(webProvider: provider)); verifyNoMoreInteractions(appCheck); }); test('activate with ReCaptchaEnterpriseProvider', () async { final provider = ReCaptchaEnterpriseProvider('key'); - await appCheck.activate( - webProvider: provider, - ); - verify( - appCheck.activate( - webProvider: provider, - ), - ); + await appCheck.activate(webProvider: provider); + verify(appCheck.activate(webProvider: provider)); verifyNoMoreInteractions(appCheck); }); diff --git a/packages/firebase_app_check/firebase_app_check_web/test/firebase_app_check_web_test.mocks.dart b/packages/firebase_app_check/firebase_app_check_web/test/firebase_app_check_web_test.mocks.dart index 357b30beeca5..323f705b7d26 100644 --- a/packages/firebase_app_check/firebase_app_check_web/test/firebase_app_check_web_test.mocks.dart +++ b/packages/firebase_app_check/firebase_app_check_web/test/firebase_app_check_web_test.mocks.dart @@ -30,35 +30,20 @@ import 'package:mockito/src/dummies.dart' as _i6; // ignore_for_file: subtype_of_sealed_class class _FakeFirebaseApp_0 extends _i1.SmartFake implements _i2.FirebaseApp { - _FakeFirebaseApp_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeFirebaseApp_0(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeFirebaseAppCheckPlatform_1 extends _i1.SmartFake implements _i3.FirebaseAppCheckPlatform { - _FakeFirebaseAppCheckPlatform_1( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeFirebaseAppCheckPlatform_1(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeFirebaseAppCheckWeb_2 extends _i1.SmartFake implements _i4.FirebaseAppCheckWeb { - _FakeFirebaseAppCheckWeb_2( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeFirebaseAppCheckWeb_2(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } /// A class which mocks [FirebaseAppCheckWeb]. @@ -67,72 +52,55 @@ class _FakeFirebaseAppCheckWeb_2 extends _i1.SmartFake class MockFirebaseAppCheckWeb extends _i1.Mock implements _i4.FirebaseAppCheckWeb { @override - _i5.Stream get onTokenChange => (super.noSuchMethod( - Invocation.getter(#onTokenChange), - returnValue: _i5.Stream.empty(), - returnValueForMissingStub: _i5.Stream.empty(), - ) as _i5.Stream); + _i5.Stream get onTokenChange => + (super.noSuchMethod( + Invocation.getter(#onTokenChange), + returnValue: _i5.Stream.empty(), + returnValueForMissingStub: _i5.Stream.empty(), + ) + as _i5.Stream); @override - _i2.FirebaseApp get app => (super.noSuchMethod( - Invocation.getter(#app), - returnValue: _FakeFirebaseApp_0( - this, - Invocation.getter(#app), - ), - returnValueForMissingStub: _FakeFirebaseApp_0( - this, - Invocation.getter(#app), - ), - ) as _i2.FirebaseApp); + _i2.FirebaseApp get app => + (super.noSuchMethod( + Invocation.getter(#app), + returnValue: _FakeFirebaseApp_0(this, Invocation.getter(#app)), + returnValueForMissingStub: _FakeFirebaseApp_0( + this, + Invocation.getter(#app), + ), + ) + as _i2.FirebaseApp); @override _i3.FirebaseAppCheckPlatform delegateFor({required _i2.FirebaseApp? app}) => (super.noSuchMethod( - Invocation.method( - #delegateFor, - [], - {#app: app}, - ), - returnValue: _FakeFirebaseAppCheckPlatform_1( - this, - Invocation.method( - #delegateFor, - [], - {#app: app}, - ), - ), - returnValueForMissingStub: _FakeFirebaseAppCheckPlatform_1( - this, - Invocation.method( - #delegateFor, - [], - {#app: app}, - ), - ), - ) as _i3.FirebaseAppCheckPlatform); + Invocation.method(#delegateFor, [], {#app: app}), + returnValue: _FakeFirebaseAppCheckPlatform_1( + this, + Invocation.method(#delegateFor, [], {#app: app}), + ), + returnValueForMissingStub: _FakeFirebaseAppCheckPlatform_1( + this, + Invocation.method(#delegateFor, [], {#app: app}), + ), + ) + as _i3.FirebaseAppCheckPlatform); @override - _i4.FirebaseAppCheckWeb setInitialValues() => (super.noSuchMethod( - Invocation.method( - #setInitialValues, - [], - ), - returnValue: _FakeFirebaseAppCheckWeb_2( - this, - Invocation.method( - #setInitialValues, - [], - ), - ), - returnValueForMissingStub: _FakeFirebaseAppCheckWeb_2( - this, - Invocation.method( - #setInitialValues, - [], - ), - ), - ) as _i4.FirebaseAppCheckWeb); + _i4.FirebaseAppCheckWeb setInitialValues() => + (super.noSuchMethod( + Invocation.method(#setInitialValues, []), + returnValue: _FakeFirebaseAppCheckWeb_2( + this, + Invocation.method(#setInitialValues, []), + ), + returnValueForMissingStub: _FakeFirebaseAppCheckWeb_2( + this, + Invocation.method(#setInitialValues, []), + ), + ) + as _i4.FirebaseAppCheckWeb); @override _i5.Future activate({ @@ -144,64 +112,57 @@ class MockFirebaseAppCheckWeb extends _i1.Mock _i3.WindowsAppCheckProvider? providerWindows, }) => (super.noSuchMethod( - Invocation.method( - #activate, - [], - { - #webProvider: webProvider, - #androidProvider: androidProvider, - #appleProvider: appleProvider, - #providerAndroid: providerAndroid, - #providerApple: providerApple, - #providerWindows: providerWindows, - }, - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#activate, [], { + #webProvider: webProvider, + #androidProvider: androidProvider, + #appleProvider: appleProvider, + #providerAndroid: providerAndroid, + #providerApple: providerApple, + #providerWindows: providerWindows, + }), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override - _i5.Future getToken(bool? forceRefresh) => (super.noSuchMethod( - Invocation.method( - #getToken, - [forceRefresh], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + _i5.Future getToken(bool? forceRefresh) => + (super.noSuchMethod( + Invocation.method(#getToken, [forceRefresh]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override - _i5.Future getLimitedUseToken() => (super.noSuchMethod( - Invocation.method( - #getLimitedUseToken, - [], - ), - returnValue: _i5.Future.value(_i6.dummyValue( - this, - Invocation.method( - #getLimitedUseToken, - [], - ), - )), - returnValueForMissingStub: - _i5.Future.value(_i6.dummyValue( - this, - Invocation.method( - #getLimitedUseToken, - [], - ), - )), - ) as _i5.Future); + _i5.Future getLimitedUseToken() => + (super.noSuchMethod( + Invocation.method(#getLimitedUseToken, []), + returnValue: _i5.Future.value( + _i6.dummyValue( + this, + Invocation.method(#getLimitedUseToken, []), + ), + ), + returnValueForMissingStub: _i5.Future.value( + _i6.dummyValue( + this, + Invocation.method(#getLimitedUseToken, []), + ), + ), + ) + as _i5.Future); @override _i5.Future setTokenAutoRefreshEnabled( - bool? isTokenAutoRefreshEnabled) => + bool? isTokenAutoRefreshEnabled, + ) => (super.noSuchMethod( - Invocation.method( - #setTokenAutoRefreshEnabled, - [isTokenAutoRefreshEnabled], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#setTokenAutoRefreshEnabled, [ + isTokenAutoRefreshEnabled, + ]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); } diff --git a/packages/firebase_app_installations/firebase_app_installations/example/integration_test/e2e_test.dart b/packages/firebase_app_installations/firebase_app_installations/example/integration_test/e2e_test.dart index 23e6382de3a3..1967f04babe0 100644 --- a/packages/firebase_app_installations/firebase_app_installations/example/integration_test/e2e_test.dart +++ b/packages/firebase_app_installations/firebase_app_installations/example/integration_test/e2e_test.dart @@ -21,104 +21,90 @@ final isCI = const String.fromEnvironment('CI').isNotEmpty; void main() { final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized(); reportTestResultsToDriver(binding); - group( - 'firebase_app_installations', - () { - setUpAll(() async { - // The native SDK may already have configured [DEFAULT] from a bundled - // GoogleService-Info.plist (the plugin registrant does this before any - // Dart runs). Dart's Firebase.apps cannot see that app until the first - // platform-channel call, so the only reliable guard is catching the - // duplicate-app error and keeping the natively configured instance. - try { - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); - } on FirebaseException catch (e) { - if (e.code != 'duplicate-app') { - rethrow; - } - } - if (defaultTargetPlatform == TargetPlatform.android) { - // Android Installations can deadlock if token/id APIs race native - // heartbeat initialization immediately after manual app init. - await Future.delayed(const Duration(seconds: 2)); + group('firebase_app_installations', () { + setUpAll(() async { + // The native SDK may already have configured [DEFAULT] from a bundled + // GoogleService-Info.plist (the plugin registrant does this before any + // Dart runs). Dart's Firebase.apps cannot see that app until the first + // platform-channel call, so the only reliable guard is catching the + // duplicate-app error and keeping the natively configured instance. + try { + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + } on FirebaseException catch (e) { + if (e.code != 'duplicate-app') { + rethrow; } - }); + } + if (defaultTargetPlatform == TargetPlatform.android) { + // Android Installations can deadlock if token/id APIs race native + // heartbeat initialization immediately after manual app init. + await Future.delayed(const Duration(seconds: 2)); + } + }); - test( - '.getId', - () async { - final id = await FirebaseInstallations.instance.getId(); - expect(id, isNotEmpty); - // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 - }, - skip: defaultTargetPlatform == TargetPlatform.macOS, - ); + test('.getId', () async { + final id = await FirebaseInstallations.instance.getId(); + expect(id, isNotEmpty); + // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 + }, skip: defaultTargetPlatform == TargetPlatform.macOS); - test( - 'running get id in parallel', - () async { - final ids = await Future.wait([ - FirebaseInstallations.instance.getId(), - FirebaseInstallations.instance.getId(), - FirebaseInstallations.instance.getId(), - FirebaseInstallations.instance.getId(), - FirebaseInstallations.instance.getId(), - ]); - expect(ids, isNotNull); - }, - skip: defaultTargetPlatform == TargetPlatform.macOS && isCI, - ); + test('running get id in parallel', () async { + final ids = await Future.wait([ + FirebaseInstallations.instance.getId(), + FirebaseInstallations.instance.getId(), + FirebaseInstallations.instance.getId(), + FirebaseInstallations.instance.getId(), + FirebaseInstallations.instance.getId(), + ]); + expect(ids, isNotNull); + }, skip: defaultTargetPlatform == TargetPlatform.macOS && isCI); - test( - '.getToken', - () async { - final token = await FirebaseInstallations.instance.getToken(); - expect(token, isNotEmpty); - // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 - }, - // TODO(ci): getToken deadlocks (5-minute timeout, reproducibly) on the - // Android emulator since the suite moved into this standalone example - - // likely the token/heartbeat initialization race the setUpAll delay - // guards, hitting differently on a cold single-plugin app. Needs - // investigation before re-enabling on Android. - skip: defaultTargetPlatform == TargetPlatform.macOS || - defaultTargetPlatform == TargetPlatform.android, - ); + test( + '.getToken', + () async { + final token = await FirebaseInstallations.instance.getToken(); + expect(token, isNotEmpty); + // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 + }, + // TODO(ci): getToken deadlocks (5-minute timeout, reproducibly) on the + // Android emulator since the suite moved into this standalone example - + // likely the token/heartbeat initialization race the setUpAll delay + // guards, hitting differently on a cold single-plugin app. Needs + // investigation before re-enabling on Android. + skip: + defaultTargetPlatform == TargetPlatform.macOS || + defaultTargetPlatform == TargetPlatform.android, + ); - test( - '.delete', - () async { - final id = await FirebaseInstallations.instance.getId(); + test('.delete', () async { + final id = await FirebaseInstallations.instance.getId(); - // Retry delete in case of delete-pending state - for (var attempt = 0; attempt < 5; attempt++) { - try { - await FirebaseInstallations.instance.delete(); - break; - } catch (e) { - if (attempt == 4) rethrow; - await Future.delayed(const Duration(seconds: 2)); - } - } + // Retry delete in case of delete-pending state + for (var attempt = 0; attempt < 5; attempt++) { + try { + await FirebaseInstallations.instance.delete(); + break; + } catch (e) { + if (attempt == 4) rethrow; + await Future.delayed(const Duration(seconds: 2)); + } + } - // Retry getId in case of delete-pending state - String? newId; - for (var attempt = 0; attempt < 5; attempt++) { - try { - newId = await FirebaseInstallations.instance.getId(); - break; - } catch (e) { - if (attempt == 4) rethrow; - await Future.delayed(const Duration(seconds: 2)); - } - } - expect(newId, isNot(equals(id))); - // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 - }, - skip: defaultTargetPlatform == TargetPlatform.macOS, - ); - }, - ); + // Retry getId in case of delete-pending state + String? newId; + for (var attempt = 0; attempt < 5; attempt++) { + try { + newId = await FirebaseInstallations.instance.getId(); + break; + } catch (e) { + if (attempt == 4) rethrow; + await Future.delayed(const Duration(seconds: 2)); + } + } + expect(newId, isNot(equals(id))); + // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 + }, skip: defaultTargetPlatform == TargetPlatform.macOS); + }); } diff --git a/packages/firebase_app_installations/firebase_app_installations/example/integration_test/report_test_results.dart b/packages/firebase_app_installations/firebase_app_installations/example/integration_test/report_test_results.dart index fb80e3ba19f7..db17f5dab066 100644 --- a/packages/firebase_app_installations/firebase_app_installations/example/integration_test/report_test_results.dart +++ b/packages/firebase_app_installations/firebase_app_installations/example/integration_test/report_test_results.dart @@ -26,8 +26,9 @@ void reportTestResultsToDriver(IntegrationTestWidgetsFlutterBinding binding) { for (final entry in binding.results.entries) if (entry.value is Failure) entry.key, ]; - bool didFail(String name) => failures - .any((failure) => name == failure || name.endsWith(' $failure')); + bool didFail(String name) => failures.any( + (failure) => name == failure || name.endsWith(' $failure'), + ); binding.reportData ??= {}; binding.reportData!['testResults'] = { diff --git a/packages/firebase_app_installations/firebase_app_installations/example/lib/firebase_options.dart b/packages/firebase_app_installations/firebase_app_installations/example/lib/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/firebase_app_installations/firebase_app_installations/example/lib/firebase_options.dart +++ b/packages/firebase_app_installations/firebase_app_installations/example/lib/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/firebase_app_installations/firebase_app_installations/example/lib/main.dart b/packages/firebase_app_installations/firebase_app_installations/example/lib/main.dart index eb64f6a490f1..3dd81582fe43 100644 --- a/packages/firebase_app_installations/firebase_app_installations/example/lib/main.dart +++ b/packages/firebase_app_installations/firebase_app_installations/example/lib/main.dart @@ -13,9 +13,7 @@ import 'firebase_options.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); + await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); runApp(const MyApp()); } @@ -28,9 +26,7 @@ class MyApp extends StatelessWidget { return MaterialApp( theme: ThemeData(primarySwatch: Colors.amber), home: Scaffold( - appBar: AppBar( - title: const Text('Firebase Installations'), - ), + appBar: AppBar(title: const Text('Firebase Installations')), body: const InstallationsCard(), ), ); @@ -51,22 +47,26 @@ class _InstallationsCardState extends State { init(); // Listen to changes - FirebaseInstallations.instance.onIdChange.listen((event) { - setState(() { - id = event; - }); - - // Make sure that the Auth Token is updated once the Installation Id is updated - getAuthToken(); - - // ignore: use_build_context_synchronously - ScaffoldMessenger.of(context).showSnackBar(const SnackBar( - content: Text('New Firebase Installations Id generated 🎉'), - backgroundColor: Colors.green, - )); - }).onError((error) { - log("$error"); - }); + FirebaseInstallations.instance.onIdChange + .listen((event) { + setState(() { + id = event; + }); + + // Make sure that the Auth Token is updated once the Installation Id is updated + getAuthToken(); + + // ignore: use_build_context_synchronously + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('New Firebase Installations Id generated 🎉'), + backgroundColor: Colors.green, + ), + ); + }) + .onError((error) { + log("$error"); + }); } String id = 'None'; @@ -133,25 +133,15 @@ class _InstallationsCardState extends State { Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Expanded( - child: Text("Installation Id: "), - ), - Expanded( - flex: 2, - child: Text(id), - ), + const Expanded(child: Text("Installation Id: ")), + Expanded(flex: 2, child: Text(id)), ], ), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Expanded( - child: Text("Auth Token: "), - ), - Expanded( - flex: 2, - child: Text(authToken), - ), + const Expanded(child: Text("Auth Token: ")), + Expanded(flex: 2, child: Text(authToken)), ], ), ], @@ -183,9 +173,9 @@ class _InstallationsCardState extends State { onPressed: getId, child: const Text("Get ID"), ), - ) + ), ], - ) + ), ], ), ), diff --git a/packages/firebase_app_installations/firebase_app_installations/example/pubspec.yaml b/packages/firebase_app_installations/firebase_app_installations/example/pubspec.yaml index 75a16ddf8ef5..a66075164c1a 100644 --- a/packages/firebase_app_installations/firebase_app_installations/example/pubspec.yaml +++ b/packages/firebase_app_installations/firebase_app_installations/example/pubspec.yaml @@ -7,8 +7,8 @@ version: 1.0.0+1 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core: ^4.14.0 diff --git a/packages/firebase_app_installations/firebase_app_installations/example/test_driver/integration_test.dart b/packages/firebase_app_installations/firebase_app_installations/example/test_driver/integration_test.dart index 691723cbbfe1..9ccbcc26ab97 100644 --- a/packages/firebase_app_installations/firebase_app_installations/example/test_driver/integration_test.dart +++ b/packages/firebase_app_installations/firebase_app_installations/example/test_driver/integration_test.dart @@ -7,28 +7,32 @@ import 'dart:io'; import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver( - writeResponseOnFailure: true, - responseDataCallback: (Map? data) async { - final results = - (data?['testResults'] as Map?)?.cast() ?? - const {}; - var passed = 0; - var failed = 0; - for (final entry in results.entries) { - final ok = entry.value == 'success'; - ok ? passed++ : failed++; - // ignore: avoid_print - print('${ok ? '✅' : '❌'} ${entry.key}'); - } - // ignore: avoid_print - print('Web e2e summary: $passed passed, $failed failed, ' - '${results.length} total'); - if (results.isEmpty) { - // ignore: avoid_print - print('[E] No tests reported by the app - treating as ' - 'infrastructure failure.'); - exit(1); - } - await writeResponseData(data); - }, + writeResponseOnFailure: true, + responseDataCallback: (Map? data) async { + final results = + (data?['testResults'] as Map?)?.cast() ?? + const {}; + var passed = 0; + var failed = 0; + for (final entry in results.entries) { + final ok = entry.value == 'success'; + ok ? passed++ : failed++; + // ignore: avoid_print + print('${ok ? '✅' : '❌'} ${entry.key}'); + } + // ignore: avoid_print + print( + 'Web e2e summary: $passed passed, $failed failed, ' + '${results.length} total', ); + if (results.isEmpty) { + // ignore: avoid_print + print( + '[E] No tests reported by the app - treating as ' + 'infrastructure failure.', + ); + exit(1); + } + await writeResponseData(data); + }, +); diff --git a/packages/firebase_app_installations/firebase_app_installations/lib/src/firebase_app_installations.dart b/packages/firebase_app_installations/firebase_app_installations/lib/src/firebase_app_installations.dart index fa21dd564810..d3490d443c6b 100644 --- a/packages/firebase_app_installations/firebase_app_installations/lib/src/firebase_app_installations.dart +++ b/packages/firebase_app_installations/firebase_app_installations/lib/src/firebase_app_installations.dart @@ -6,7 +6,7 @@ part of '../firebase_app_installations.dart'; class FirebaseInstallations extends FirebasePlugin { FirebaseInstallations._({required this.app}) - : super(app.name, 'plugins.flutter.io/firebase_app_installations'); + : super(app.name, 'plugins.flutter.io/firebase_app_installations'); // Cached and lazily loaded instance of [FirebaseAppInstallationsPlatform] to avoid // creating a [MethodChannelFirebaseInstallations] when not needed or creating an @@ -27,9 +27,7 @@ class FirebaseInstallations extends FirebasePlugin { /// Returns an instance using the default [FirebaseApp] and region. static FirebaseInstallations get instance { - return FirebaseInstallations.instanceFor( - app: Firebase.app(), - ); + return FirebaseInstallations.instanceFor(app: Firebase.app()); } /// Returns an instance using a specified [FirebaseApp]. diff --git a/packages/firebase_app_installations/firebase_app_installations/pubspec.yaml b/packages/firebase_app_installations/firebase_app_installations/pubspec.yaml index 087fbb045dcc..87ed30016664 100644 --- a/packages/firebase_app_installations/firebase_app_installations/pubspec.yaml +++ b/packages/firebase_app_installations/firebase_app_installations/pubspec.yaml @@ -14,8 +14,8 @@ false_secrets: - example/** environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_app_installations_platform_interface: ^0.1.5 diff --git a/packages/firebase_app_installations/firebase_app_installations/test/firebase_installations_test.dart b/packages/firebase_app_installations/firebase_app_installations/test/firebase_installations_test.dart index 5440ae72ac6b..e8db4dc87000 100644 --- a/packages/firebase_app_installations/firebase_app_installations/test/firebase_installations_test.dart +++ b/packages/firebase_app_installations/firebase_app_installations/test/firebase_installations_test.dart @@ -24,12 +24,12 @@ void main() { setUpAll(() async { await Firebase.initializeApp(); installations = FirebaseInstallations.instance; - when(mockInstallations.delegateFor( - app: anyNamed('app'), - )).thenAnswer((_) => mockInstallations); - when(mockInstallations.getId()).thenAnswer( - (_) => Future.value('some-id'), - ); + when( + mockInstallations.delegateFor(app: anyNamed('app')), + ).thenAnswer((_) => mockInstallations); + when( + mockInstallations.getId(), + ).thenAnswer((_) => Future.value('some-id')); }); test('getId', () async { @@ -57,8 +57,7 @@ class MockFirebaseInstallations extends Mock with // ignore: prefer_mixin MockPlatformInterfaceMixin - implements - TestFirebaseAppInstallationsPlatform { + implements TestFirebaseAppInstallationsPlatform { @override TestFirebaseAppInstallationsPlatform delegateFor({FirebaseApp? app}) { return super.noSuchMethod( diff --git a/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/method_channel/method_channel_firebase_app_installations.dart b/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/method_channel/method_channel_firebase_app_installations.dart index b6286cb80325..189ff59ca44f 100644 --- a/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/method_channel/method_channel_firebase_app_installations.dart +++ b/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/method_channel/method_channel_firebase_app_installations.dart @@ -28,24 +28,28 @@ class MethodChannelFirebaseAppInstallations /// Creates a new [MethodChannelFirebaseAppInstallations] instance with an [app]. MethodChannelFirebaseAppInstallations({required FirebaseApp app}) - : super(app) { + : super(app) { final controller = _idTokenChangesListeners[app.name] = StreamController.broadcast(); - _api.registerIdChangeListener(app.name).then((channelName) { - final events = EventChannel(channelName); + _api + .registerIdChangeListener(app.name) + .then((channelName) { + final events = EventChannel(channelName); - events - .receiveGuardedBroadcastStream(onError: convertPlatformException) - .listen( - (Object? arguments) => controller.add((arguments as Map)['token']), - onError: controller.addError, - ); - // ignore: avoid_catches_without_on_clauses - }).catchError((_) { - // Silently ignore errors during listener registration. - // This can happen in test environments where the host API is not set up. - }); + events + .receiveGuardedBroadcastStream(onError: convertPlatformException) + .listen( + (Object? arguments) => + controller.add((arguments as Map)['token']), + onError: controller.addError, + ); + // ignore: avoid_catches_without_on_clauses + }) + .catchError((_) { + // Silently ignore errors during listener registration. + // This can happen in test environments where the host API is not set up. + }); } /// Internal stub class initializer. diff --git a/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/pigeon/messages.pigeon.dart b/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/pigeon/messages.pigeon.dart index 4b1471f70f57..42e9abb49924 100644 --- a/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/pigeon/messages.pigeon.dart +++ b/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/pigeon/messages.pigeon.dart @@ -62,11 +62,13 @@ class FirebaseAppInstallationsHostApi { /// Constructor for [FirebaseAppInstallationsHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - FirebaseAppInstallationsHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + FirebaseAppInstallationsHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -81,8 +83,9 @@ class FirebaseAppInstallationsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -100,8 +103,9 @@ class FirebaseAppInstallationsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -120,8 +124,9 @@ class FirebaseAppInstallationsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName, forceRefresh]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName, forceRefresh], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -140,8 +145,9 @@ class FirebaseAppInstallationsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( diff --git a/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/platform_interface/firebase_app_installations_platform_interface.dart b/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/platform_interface/firebase_app_installations_platform_interface.dart index 5cef18038727..640ed0e1533d 100644 --- a/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/platform_interface/firebase_app_installations_platform_interface.dart +++ b/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/platform_interface/firebase_app_installations_platform_interface.dart @@ -20,8 +20,9 @@ abstract class FirebaseAppInstallationsPlatform extends PlatformInterface { final FirebaseApp? app; /// Create an instance using [app] using the existing implementation - factory FirebaseAppInstallationsPlatform.instanceFor( - {required FirebaseApp app}) { + factory FirebaseAppInstallationsPlatform.instanceFor({ + required FirebaseApp app, + }) { return FirebaseAppInstallationsPlatform.instance.delegateFor(app: app); } diff --git a/packages/firebase_app_installations/firebase_app_installations_platform_interface/pubspec.yaml b/packages/firebase_app_installations/firebase_app_installations_platform_interface/pubspec.yaml index 8eaed935e317..c74c394a4ccf 100644 --- a/packages/firebase_app_installations/firebase_app_installations_platform_interface/pubspec.yaml +++ b/packages/firebase_app_installations/firebase_app_installations_platform_interface/pubspec.yaml @@ -6,8 +6,8 @@ homepage: https://github.com/firebase/flutterfire/tree/main/packages/firebase_ap repository: https://github.com/firebase/flutterfire/tree/main/packages/firebase_app_installations/firebase_app_installations_platform_interface environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_app_installations/firebase_app_installations_platform_interface/test/method_channel/method_channel_firebase_app_installations_test.dart b/packages/firebase_app_installations/firebase_app_installations_platform_interface/test/method_channel/method_channel_firebase_app_installations_test.dart index 3f7f41f8664c..2c8c8c79b5a1 100644 --- a/packages/firebase_app_installations/firebase_app_installations_platform_interface/test/method_channel/method_channel_firebase_app_installations_test.dart +++ b/packages/firebase_app_installations/firebase_app_installations_platform_interface/test/method_channel/method_channel_firebase_app_installations_test.dart @@ -34,17 +34,18 @@ void main() { setUpAll(() async { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMessageHandler('$_hostApiPrefix.registerIdChangeListener', ( - ByteData? message, - ) async { - final List args = - FirebaseAppInstallationsHostApi.pigeonChannelCodec.decodeMessage( - message, - ) as List; - lastRegisterAppName = args[0]! as String; - return encodeSuccess( - 'plugins.flutter.io/firebase_app_installations/token/$lastRegisterAppName', - ); - }); + ByteData? message, + ) async { + final List args = + FirebaseAppInstallationsHostApi.pigeonChannelCodec.decodeMessage( + message, + ) + as List; + lastRegisterAppName = args[0]! as String; + return encodeSuccess( + 'plugins.flutter.io/firebase_app_installations/token/$lastRegisterAppName', + ); + }); app = await Firebase.initializeApp(); installations = MethodChannelFirebaseAppInstallations(app: app); @@ -54,9 +55,9 @@ void main() { tearDownAll(() { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMessageHandler( - '$_hostApiPrefix.registerIdChangeListener', - null, - ); + '$_hostApiPrefix.registerIdChangeListener', + null, + ); }); setUp(() { @@ -66,39 +67,44 @@ void main() { lastForceRefresh = null; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMessageHandler('$_hostApiPrefix.delete', - (ByteData? message) async { - final List args = - FirebaseAppInstallationsHostApi.pigeonChannelCodec.decodeMessage( - message, - ) as List; - lastDeleteAppName = args[0]! as String; - return encodeSuccess(); - }); + .setMockMessageHandler('$_hostApiPrefix.delete', ( + ByteData? message, + ) async { + final List args = + FirebaseAppInstallationsHostApi.pigeonChannelCodec.decodeMessage( + message, + ) + as List; + lastDeleteAppName = args[0]! as String; + return encodeSuccess(); + }); TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMessageHandler('$_hostApiPrefix.getId', - (ByteData? message) async { - final List args = - FirebaseAppInstallationsHostApi.pigeonChannelCodec.decodeMessage( - message, - ) as List; - lastGetIdAppName = args[0]! as String; - return encodeSuccess('test-installation-id'); - }); + .setMockMessageHandler('$_hostApiPrefix.getId', ( + ByteData? message, + ) async { + final List args = + FirebaseAppInstallationsHostApi.pigeonChannelCodec.decodeMessage( + message, + ) + as List; + lastGetIdAppName = args[0]! as String; + return encodeSuccess('test-installation-id'); + }); TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMessageHandler('$_hostApiPrefix.getToken', ( - ByteData? message, - ) async { - final List args = - FirebaseAppInstallationsHostApi.pigeonChannelCodec.decodeMessage( - message, - ) as List; - lastGetTokenAppName = args[0]! as String; - lastForceRefresh = args[1]! as bool; - return encodeSuccess('test-installation-token'); - }); + ByteData? message, + ) async { + final List args = + FirebaseAppInstallationsHostApi.pigeonChannelCodec.decodeMessage( + message, + ) + as List; + lastGetTokenAppName = args[0]! as String; + lastForceRefresh = args[1]! as bool; + return encodeSuccess('test-installation-token'); + }); }); tearDown(() { diff --git a/packages/firebase_app_installations/firebase_app_installations_web/lib/firebase_app_installations_web.dart b/packages/firebase_app_installations/firebase_app_installations_web/lib/firebase_app_installations_web.dart index 1a0e7be3c013..93fe34510372 100644 --- a/packages/firebase_app_installations/firebase_app_installations_web/lib/firebase_app_installations_web.dart +++ b/packages/firebase_app_installations/firebase_app_installations_web/lib/firebase_app_installations_web.dart @@ -22,17 +22,16 @@ class FirebaseAppInstallationsWeb extends FirebaseAppInstallationsPlatform { /// Stub initializer to allow the [registerWith] to create an instance without /// registering the web delegates or listeners. - FirebaseAppInstallationsWeb._() - : _webInstallations = null, - super(null); + FirebaseAppInstallationsWeb._() : _webInstallations = null, super(null); /// Instance of installations from the web plugin. installations_interop.Installations? _webInstallations; /// Lazily initialize [_webFunctions] on first method call installations_interop.Installations get _delegate { - return _webInstallations ??= installations_interop - .getInstallationsInstance(core_interop.app(app?.name)); + return _webInstallations ??= installations_interop.getInstallationsInstance( + core_interop.app(app?.name), + ); } /// Create the default instance of the [FirebaseAppInstallationsPlatform] as a [FirebaseAppInstallationsWeb] diff --git a/packages/firebase_app_installations/firebase_app_installations_web/lib/src/interop/installations.dart b/packages/firebase_app_installations/firebase_app_installations_web/lib/src/interop/installations.dart index d374a331f654..79237c2fb166 100644 --- a/packages/firebase_app_installations/firebase_app_installations_web/lib/src/interop/installations.dart +++ b/packages/firebase_app_installations/firebase_app_installations_web/lib/src/interop/installations.dart @@ -12,9 +12,11 @@ import 'installations_interop.dart' as installations_interop; export 'installations_interop.dart'; Installations getInstallationsInstance([App? app]) { - return Installations.getInstance(app != null - ? installations_interop.getInstallations(app.jsObject) - : installations_interop.getInstallations()); + return Installations.getInstance( + app != null + ? installations_interop.getInstallations(app.jsObject) + : installations_interop.getInstallations(), + ); } class Installations @@ -23,7 +25,8 @@ class Installations /// Creates a new Installations from a [jsObject]. static Installations getInstance( - installations_interop.InstallationsJsImpl jsObject) { + installations_interop.InstallationsJsImpl jsObject, + ) { return _expando[jsObject] ??= Installations._fromJsObject(jsObject); } @@ -32,14 +35,15 @@ class Installations Future delete() => (installations_interop.deleteInstallations(jsObject)).toDart; - Future getId() => (installations_interop.getId(jsObject)) - .toDart - .then((value) => value.toDart); + Future getId() => (installations_interop.getId( + jsObject, + )).toDart.then((value) => value.toDart); Future getToken([bool forceRefresh = false]) => - (installations_interop.getToken(jsObject, forceRefresh.toJS)) - .toDart - .then((value) => value.toDart); + (installations_interop.getToken( + jsObject, + forceRefresh.toJS, + )).toDart.then((value) => value.toDart); JSFunction? _onIdChangedUnsubscribe; @@ -53,8 +57,10 @@ class Installations void startListen() { assert(_onIdChangedUnsubscribe == null); - _onIdChangedUnsubscribe = - installations_interop.onIdChange(jsObject, wrapper); + _onIdChangedUnsubscribe = installations_interop.onIdChange( + jsObject, + wrapper, + ); } void stopListen() { diff --git a/packages/firebase_app_installations/firebase_app_installations_web/lib/src/interop/installations_interop.dart b/packages/firebase_app_installations/firebase_app_installations_web/lib/src/interop/installations_interop.dart index 00f72ab66cd8..31f43aae1622 100644 --- a/packages/firebase_app_installations/firebase_app_installations_web/lib/src/interop/installations_interop.dart +++ b/packages/firebase_app_installations/firebase_app_installations_web/lib/src/interop/installations_interop.dart @@ -19,13 +19,16 @@ external JSPromise getId(InstallationsJsImpl installations); @JS() @staticInterop -external JSPromise getToken(InstallationsJsImpl installations, - [JSBoolean? forceRefresh]); +external JSPromise getToken( + InstallationsJsImpl installations, [ + JSBoolean? forceRefresh, +]); @JS() @staticInterop external JSPromise /* void */ deleteInstallations( - InstallationsJsImpl installations); + InstallationsJsImpl installations, +); @JS() @staticInterop diff --git a/packages/firebase_app_installations/firebase_app_installations_web/pubspec.yaml b/packages/firebase_app_installations/firebase_app_installations_web/pubspec.yaml index 1c21648f05b4..2bce14386bcd 100644 --- a/packages/firebase_app_installations/firebase_app_installations_web/pubspec.yaml +++ b/packages/firebase_app_installations/firebase_app_installations_web/pubspec.yaml @@ -6,8 +6,8 @@ homepage: https://github.com/firebase/flutterfire/tree/main/packages/firebase_ap repository: https://github.com/firebase/flutterfire/tree/main/packages/firebase_app_installations/firebase_app_installations_web environment: - sdk: '^3.6.0' - flutter: '>=3.22.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_auth/firebase_auth/example/integration_test/e2e_test.dart b/packages/firebase_auth/firebase_auth/example/integration_test/e2e_test.dart index 0cc35bf1870c..3e09ecded06e 100644 --- a/packages/firebase_auth/firebase_auth/example/integration_test/e2e_test.dart +++ b/packages/firebase_auth/firebase_auth/example/integration_test/e2e_test.dart @@ -36,11 +36,14 @@ void main() { } } - await FirebaseAuth.instance - .useAuthEmulator(testEmulatorHost, testEmulatorPort); + await FirebaseAuth.instance.useAuthEmulator( + testEmulatorHost, + testEmulatorPort, + ); if (defaultTargetPlatform != TargetPlatform.windows) { - await FirebaseAuth.instance - .setSettings(appVerificationDisabledForTesting: true); + await FirebaseAuth.instance.setSettings( + appVerificationDisabledForTesting: true, + ); } }); @@ -64,11 +67,11 @@ void main() { } try { - final disabledUserCredential = - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: testDisabledEmail, - password: testPassword, - ); + final disabledUserCredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( + email: testDisabledEmail, + password: testPassword, + ); await emulatorDisableUser(disabledUserCredential.user!.uid); } on FirebaseAuthException catch (e) { if (e.code != 'email-already-in-use' && e.code != 'keychain-error') { diff --git a/packages/firebase_auth/firebase_auth/example/integration_test/firebase_auth_instance_e2e_test.dart b/packages/firebase_auth/firebase_auth/example/integration_test/firebase_auth_instance_e2e_test.dart index 6f90fcf6fd5d..c1bccbb83891 100644 --- a/packages/firebase_auth/firebase_auth/example/integration_test/firebase_auth_instance_e2e_test.dart +++ b/packages/firebase_auth/firebase_auth/example/integration_test/firebase_auth_instance_e2e_test.dart @@ -49,39 +49,41 @@ void main() { await ensureSignedOut(); }); - test('calls callback with the current user and when auth state changes', - () async { - await ensureSignedIn(testEmail); - String uid = FirebaseAuth.instance.currentUser!.uid; - - Stream stream = FirebaseAuth.instance.authStateChanges(); - int call = 0; - - subscription = stream.listen( - expectAsync1( - (User? user) { - call++; - if (call == 1) { - expect(user!.uid, isA()); - expect(user.uid, equals(uid)); // initial user - } else if (call == 2) { - expect(user, isNull); // logged out - } else if (call == 3) { - expect(user!.uid, isA()); - expect(user.uid != uid, isTrue); // anonymous user - } else { - fail('Should not have been called'); - } - }, - count: 3, - reason: 'Stream should only have been called 3 times', - ), - ); + test( + 'calls callback with the current user and when auth state changes', + () async { + await ensureSignedIn(testEmail); + String uid = FirebaseAuth.instance.currentUser!.uid; - // Prevent race condition where signOut is called before the stream hits - await FirebaseAuth.instance.signOut(); - await FirebaseAuth.instance.signInAnonymously(); - }); + Stream stream = FirebaseAuth.instance.authStateChanges(); + int call = 0; + + subscription = stream.listen( + expectAsync1( + (User? user) { + call++; + if (call == 1) { + expect(user!.uid, isA()); + expect(user.uid, equals(uid)); // initial user + } else if (call == 2) { + expect(user, isNull); // logged out + } else if (call == 3) { + expect(user!.uid, isA()); + expect(user.uid != uid, isTrue); // anonymous user + } else { + fail('Should not have been called'); + } + }, + count: 3, + reason: 'Stream should only have been called 3 times', + ), + ); + + // Prevent race condition where signOut is called before the stream hits + await FirebaseAuth.instance.signOut(); + await FirebaseAuth.instance.signInAnonymously(); + }, + ); }); group('idTokenChanges()', () { @@ -92,85 +94,87 @@ void main() { await ensureSignedOut(); }); - test('calls callback with the current user and when auth state changes', - () async { - await ensureSignedIn(testEmail); - String uid = FirebaseAuth.instance.currentUser!.uid; - - Stream stream = FirebaseAuth.instance.idTokenChanges(); - int call = 0; - - subscription = stream.listen( - expectAsync1( - (User? user) { - call++; - if (call == 1) { - expect(user!.uid, equals(uid)); // initial user - } else if (call == 2) { - expect(user, isNull); // logged out - } else if (call == 3) { - expect(user!.uid, isA()); - expect(user.uid != uid, isTrue); // anonymous user - } else { - fail('Should not have been called'); - } - }, - count: 3, - reason: 'Stream should only have been called 3 times', - ), - ); + test( + 'calls callback with the current user and when auth state changes', + () async { + await ensureSignedIn(testEmail); + String uid = FirebaseAuth.instance.currentUser!.uid; - // Prevent race condition where signOut is called before the stream hits - await FirebaseAuth.instance.signOut(); - await FirebaseAuth.instance.signInAnonymously(); - }); + Stream stream = FirebaseAuth.instance.idTokenChanges(); + int call = 0; + + subscription = stream.listen( + expectAsync1( + (User? user) { + call++; + if (call == 1) { + expect(user!.uid, equals(uid)); // initial user + } else if (call == 2) { + expect(user, isNull); // logged out + } else if (call == 3) { + expect(user!.uid, isA()); + expect(user.uid != uid, isTrue); // anonymous user + } else { + fail('Should not have been called'); + } + }, + count: 3, + reason: 'Stream should only have been called 3 times', + ), + ); + + // Prevent race condition where signOut is called before the stream hits + await FirebaseAuth.instance.signOut(); + await FirebaseAuth.instance.signInAnonymously(); + }, + ); }); - group( - 'userChanges()', - () { - late StreamSubscription subscription; - tearDown(() async { - await subscription.cancel(); - }); + group('userChanges()', () { + late StreamSubscription subscription; + tearDown(() async { + await subscription.cancel(); + }); - test( - 'fires once on first initialization of FirebaseAuth', - () async { - // Fixes a very specific bug: https://github.com/firebase/flutterfire/issues/3628 - // If the first initialization of FirebaseAuth involves the listeners userChanges() or idTokenChanges() - // the user will receive two events. Why? The native SDK listener will always fire an event upon initial - // listen. FirebaseAuth also sends an initial synthetic event. We send a synthetic event because, ordinarily, the user will - // not use a listener as the first occurrence of FirebaseAuth. We, therefore, mimic native behavior by sending an - // event. This test proves the logic of PR: https://github.com/firebase/flutterfire/pull/6560 - - // Requires a fresh app. - FirebaseApp second = await Firebase.initializeApp( - name: 'test-init', - options: DefaultFirebaseOptions.currentPlatform, - ); + test( + 'fires once on first initialization of FirebaseAuth', + () async { + // Fixes a very specific bug: https://github.com/firebase/flutterfire/issues/3628 + // If the first initialization of FirebaseAuth involves the listeners userChanges() or idTokenChanges() + // the user will receive two events. Why? The native SDK listener will always fire an event upon initial + // listen. FirebaseAuth also sends an initial synthetic event. We send a synthetic event because, ordinarily, the user will + // not use a listener as the first occurrence of FirebaseAuth. We, therefore, mimic native behavior by sending an + // event. This test proves the logic of PR: https://github.com/firebase/flutterfire/pull/6560 + + // Requires a fresh app. + FirebaseApp second = await Firebase.initializeApp( + name: 'test-init', + options: DefaultFirebaseOptions.currentPlatform, + ); - Stream stream = - FirebaseAuth.instanceFor(app: second).userChanges(); + Stream stream = FirebaseAuth.instanceFor( + app: second, + ).userChanges(); - subscription = stream.listen( - expectAsync1( - (User? user) {}, - reason: 'Stream should only call once', - ), - ); + subscription = stream.listen( + expectAsync1( + (User? user) {}, + reason: 'Stream should only call once', + ), + ); - await Future.delayed(const Duration(seconds: 2)); - }, - skip: defaultTargetPlatform == TargetPlatform.macOS || - defaultTargetPlatform == TargetPlatform.windows || - // TODO(SelaseKay): this is crashing iOS app when running on CI - defaultTargetPlatform == TargetPlatform.iOS, - ); + await Future.delayed(const Duration(seconds: 2)); + }, + skip: + defaultTargetPlatform == TargetPlatform.macOS || + defaultTargetPlatform == TargetPlatform.windows || + // TODO(SelaseKay): this is crashing iOS app when running on CI + defaultTargetPlatform == TargetPlatform.iOS, + ); - test( - 'calls callback with the current user and when user state changes', - () async { + test( + 'calls callback with the current user and when user state changes', + () async { await ensureSignedIn(testEmail); Stream stream = FirebaseAuth.instance.userChanges(); @@ -196,53 +200,58 @@ void main() { ), ); - await FirebaseAuth.instance.currentUser! - .updateDisplayName('updatedName'); + await FirebaseAuth.instance.currentUser!.updateDisplayName( + 'updatedName', + ); expect( FirebaseAuth.instance.currentUser!.displayName, equals('updatedName'), ); - }); - }, - skip: !kIsWeb && (Platform.isWindows || Platform.isMacOS), - ); + }, + ); + }, skip: !kIsWeb && (Platform.isWindows || Platform.isMacOS)); group('test all stream listeners', () { Matcher containsExactlyThreeUsers() => predicate( - (list) => list.whereType().length == 3, - 'a list containing exactly 3 User instances', - ); - test('create, cancel and reopen all user event stream handlers', - () async { - final auth = FirebaseAuth.instance; - final events = []; - final streamHandler = events.add; + (list) => list.whereType().length == 3, + 'a list containing exactly 3 User instances', + ); + test( + 'create, cancel and reopen all user event stream handlers', + () async { + final auth = FirebaseAuth.instance; + final events = []; + final streamHandler = events.add; - StreamSubscription userChanges = - auth.userChanges().listen(streamHandler); + StreamSubscription userChanges = auth.userChanges().listen( + streamHandler, + ); - StreamSubscription authStateChanges = - auth.authStateChanges().listen(streamHandler); + StreamSubscription authStateChanges = auth + .authStateChanges() + .listen(streamHandler); - StreamSubscription idTokenChanges = - auth.idTokenChanges().listen(streamHandler); + StreamSubscription idTokenChanges = auth + .idTokenChanges() + .listen(streamHandler); - await userChanges.cancel(); - await authStateChanges.cancel(); - await idTokenChanges.cancel(); + await userChanges.cancel(); + await authStateChanges.cancel(); + await idTokenChanges.cancel(); - userChanges = auth.userChanges().listen(streamHandler); - authStateChanges = auth.authStateChanges().listen(streamHandler); - idTokenChanges = auth.idTokenChanges().listen(streamHandler); + userChanges = auth.userChanges().listen(streamHandler); + authStateChanges = auth.authStateChanges().listen(streamHandler); + idTokenChanges = auth.idTokenChanges().listen(streamHandler); - await auth.signInWithEmailAndPassword( - email: testEmail, - password: testPassword, - ); + await auth.signInWithEmailAndPassword( + email: testEmail, + password: testPassword, + ); - expect(events, containsExactlyThreeUsers()); - }); + expect(events, containsExactlyThreeUsers()); + }, + ); }); group('currentUser', () { @@ -253,129 +262,115 @@ void main() { }); }); - group( - 'applyActionCode', - () { - test('throws if invalid code', () async { - try { - await FirebaseAuth.instance.applyActionCode('!!!!!!'); - fail('Should have thrown'); - } on FirebaseException catch (e) { - expect(e.code, equals('invalid-action-code')); - } catch (e) { - fail(e.toString()); - } - }); - }, - skip: !kIsWeb && Platform.isWindows, - ); + group('applyActionCode', () { + test('throws if invalid code', () async { + try { + await FirebaseAuth.instance.applyActionCode('!!!!!!'); + fail('Should have thrown'); + } on FirebaseException catch (e) { + expect(e.code, equals('invalid-action-code')); + } catch (e) { + fail(e.toString()); + } + }); + }, skip: !kIsWeb && Platform.isWindows); - group( - 'checkActionCode()', - () { - test('throws on invalid code', () async { - try { - await FirebaseAuth.instance.checkActionCode('!!!!!!'); - fail('Should have thrown'); - } on FirebaseException catch (e) { - expect(e.code, equals('invalid-action-code')); - } catch (e) { - fail(e.toString()); - } - }); + group('checkActionCode()', () { + test('throws on invalid code', () async { + try { + await FirebaseAuth.instance.checkActionCode('!!!!!!'); + fail('Should have thrown'); + } on FirebaseException catch (e) { + expect(e.code, equals('invalid-action-code')); + } catch (e) { + fail(e.toString()); + } + }); - test( - 'returns correct operation for verifyEmail action code', - () async { - final email = generateRandomEmail(); - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); + test( + 'returns correct operation for verifyEmail action code', + () async { + final email = generateRandomEmail(); + await FirebaseAuth.instance.createUserWithEmailAndPassword( + email: email, + password: testPassword, + ); - await FirebaseAuth.instance.currentUser!.sendEmailVerification(); + await FirebaseAuth.instance.currentUser!.sendEmailVerification(); - final oobCode = await emulatorOutOfBandCode( - email, - EmulatorOobCodeType.verifyEmail, - ); - expect(oobCode, isNotNull); + final oobCode = await emulatorOutOfBandCode( + email, + EmulatorOobCodeType.verifyEmail, + ); + expect(oobCode, isNotNull); - final actionCodeInfo = - await FirebaseAuth.instance.checkActionCode( - oobCode!.oobCode!, - ); + final actionCodeInfo = await FirebaseAuth.instance.checkActionCode( + oobCode!.oobCode!, + ); - expect( - actionCodeInfo.operation, - equals(ActionCodeInfoOperation.verifyEmail), - ); - }, - // Windows skipped like the enclosing group (checkActionCode is not - // implemented there); a per-test skip REPLACES the group skip in - // package:test metadata merging, so it must repeat that condition. - // macOS skipped because createUserWithEmailAndPassword needs the - // keychain sharing entitlement, which requires a provisioning - // profile CI's ad-hoc signing cannot provide. - // See: https://github.com/firebase/flutterfire/issues/9538 - skip: !kIsWeb && (Platform.isWindows || Platform.isMacOS), - ); + expect( + actionCodeInfo.operation, + equals(ActionCodeInfoOperation.verifyEmail), + ); + }, + // Windows skipped like the enclosing group (checkActionCode is not + // implemented there); a per-test skip REPLACES the group skip in + // package:test metadata merging, so it must repeat that condition. + // macOS skipped because createUserWithEmailAndPassword needs the + // keychain sharing entitlement, which requires a provisioning + // profile CI's ad-hoc signing cannot provide. + // See: https://github.com/firebase/flutterfire/issues/9538 + skip: !kIsWeb && (Platform.isWindows || Platform.isMacOS), + ); - test( - 'returns correct operation for passwordReset action code', - () async { - final email = generateRandomEmail(); - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); - await ensureSignedOut(); + test( + 'returns correct operation for passwordReset action code', + () async { + final email = generateRandomEmail(); + await FirebaseAuth.instance.createUserWithEmailAndPassword( + email: email, + password: testPassword, + ); + await ensureSignedOut(); - await FirebaseAuth.instance.sendPasswordResetEmail(email: email); + await FirebaseAuth.instance.sendPasswordResetEmail(email: email); - final oobCode = await emulatorOutOfBandCode( - email, - EmulatorOobCodeType.passwordReset, - ); - expect(oobCode, isNotNull); + final oobCode = await emulatorOutOfBandCode( + email, + EmulatorOobCodeType.passwordReset, + ); + expect(oobCode, isNotNull); - final actionCodeInfo = - await FirebaseAuth.instance.checkActionCode( - oobCode!.oobCode!, - ); + final actionCodeInfo = await FirebaseAuth.instance.checkActionCode( + oobCode!.oobCode!, + ); - expect( - actionCodeInfo.operation, - equals(ActionCodeInfoOperation.passwordReset), - ); - }, - // macOS skipped for the same keychain reason as the verifyEmail - // test above. See: https://github.com/firebase/flutterfire/issues/9538 - skip: !kIsWeb && (Platform.isWindows || Platform.isMacOS), - ); - }, - skip: !kIsWeb && Platform.isWindows, - ); + expect( + actionCodeInfo.operation, + equals(ActionCodeInfoOperation.passwordReset), + ); + }, + // macOS skipped for the same keychain reason as the verifyEmail + // test above. See: https://github.com/firebase/flutterfire/issues/9538 + skip: !kIsWeb && (Platform.isWindows || Platform.isMacOS), + ); + }, skip: !kIsWeb && Platform.isWindows); - group( - 'confirmPasswordReset()', - () { - test('throws on invalid code', () async { - try { - await FirebaseAuth.instance.confirmPasswordReset( - code: '!!!!!!', - newPassword: 'thingamajig', - ); - fail('Should have thrown'); - } on FirebaseException catch (e) { - expect(e.code, equals('invalid-action-code')); - } catch (e) { - fail(e.toString()); - } - }); - }, - skip: !kIsWeb && Platform.isWindows, - ); + group('confirmPasswordReset()', () { + test('throws on invalid code', () async { + try { + await FirebaseAuth.instance.confirmPasswordReset( + code: '!!!!!!', + newPassword: 'thingamajig', + ); + fail('Should have thrown'); + } on FirebaseException catch (e) { + expect(e.code, equals('invalid-action-code')); + } catch (e) { + fail(e.toString()); + } + }); + }, skip: !kIsWeb && Platform.isWindows); group('createUserWithEmailAndPassword', () { test('should create a user with an email and password', () async { @@ -488,87 +483,75 @@ void main() { }); }); - group( - 'sendPasswordResetEmail()', - () { - test( - 'should not error', - () async { - var email = generateRandomEmail(); - - try { - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); - - await FirebaseAuth.instance - .sendPasswordResetEmail(email: email); - await FirebaseAuth.instance.currentUser!.delete(); - } catch (e) { - await FirebaseAuth.instance.currentUser!.delete(); - fail(e.toString()); - } - }, - skip: !kIsWeb && (Platform.isWindows || Platform.isMacOS), - ); - - test('fails if the user could not be found', () async { - try { - await FirebaseAuth.instance - .sendPasswordResetEmail(email: 'does-not-exist@bar.com'); - fail('Should have thrown'); - } on FirebaseAuthException catch (e) { - expect(e.code, equals('user-not-found')); - } catch (e) { - fail(e.toString()); - } - }); - }, - skip: !kIsWeb && Platform.isWindows, - ); - - group( - 'sendSignInLinkToEmail()', - () { - test('should send email successfully', () async { - const email = 'email-signin-test@example.com'; - const continueUrl = 'http://action-code-test.com'; + group('sendPasswordResetEmail()', () { + test('should not error', () async { + var email = generateRandomEmail(); + try { await FirebaseAuth.instance.createUserWithEmailAndPassword( email: email, password: testPassword, ); - final actionCodeSettings = ActionCodeSettings( - url: continueUrl, - handleCodeInApp: true, - ); + await FirebaseAuth.instance.sendPasswordResetEmail(email: email); + await FirebaseAuth.instance.currentUser!.delete(); + } catch (e) { + await FirebaseAuth.instance.currentUser!.delete(); + fail(e.toString()); + } + }, skip: !kIsWeb && (Platform.isWindows || Platform.isMacOS)); - await FirebaseAuth.instance.sendSignInLinkToEmail( - email: email, - actionCodeSettings: actionCodeSettings, + test('fails if the user could not be found', () async { + try { + await FirebaseAuth.instance.sendPasswordResetEmail( + email: 'does-not-exist@bar.com', ); + fail('Should have thrown'); + } on FirebaseAuthException catch (e) { + expect(e.code, equals('user-not-found')); + } catch (e) { + fail(e.toString()); + } + }); + }, skip: !kIsWeb && Platform.isWindows); - // Confirm with the emulator that it triggered an email sending code. - final oobCode = await emulatorOutOfBandCode( - email, - EmulatorOobCodeType.emailSignIn, - ); - expect(oobCode, isNotNull); - expect(oobCode?.email, email); - expect(oobCode?.type, EmulatorOobCodeType.emailSignIn); + group('sendSignInLinkToEmail()', () { + test('should send email successfully', () async { + const email = 'email-signin-test@example.com'; + const continueUrl = 'http://action-code-test.com'; - // Confirm the continue url was passed through to backend correctly. - final url = Uri.parse(oobCode!.oobLink!); - expect( - url.queryParameters['continueUrl'], - Uri.encodeFull(continueUrl), - ); - }); - }, - skip: !kIsWeb && (Platform.isWindows || Platform.isMacOS), - ); + await FirebaseAuth.instance.createUserWithEmailAndPassword( + email: email, + password: testPassword, + ); + + final actionCodeSettings = ActionCodeSettings( + url: continueUrl, + handleCodeInApp: true, + ); + + await FirebaseAuth.instance.sendSignInLinkToEmail( + email: email, + actionCodeSettings: actionCodeSettings, + ); + + // Confirm with the emulator that it triggered an email sending code. + final oobCode = await emulatorOutOfBandCode( + email, + EmulatorOobCodeType.emailSignIn, + ); + expect(oobCode, isNotNull); + expect(oobCode?.email, email); + expect(oobCode?.type, EmulatorOobCodeType.emailSignIn); + + // Confirm the continue url was passed through to backend correctly. + final url = Uri.parse(oobCode!.oobLink!); + expect( + url.queryParameters['continueUrl'], + Uri.encodeFull(continueUrl), + ); + }); + }, skip: !kIsWeb && (Platform.isWindows || Platform.isMacOS)); group('languageCode', () { test('should change the language code', () async { @@ -591,80 +574,60 @@ void main() { ); }); - group( - 'setPersistence()', - () { - test( - 'throw an unimplemented error', - () async { - try { - await FirebaseAuth.instance.setPersistence(Persistence.LOCAL); - fail('Should have thrown'); - } catch (e) { - expect(e, isInstanceOf()); - } - }, - skip: kIsWeb || defaultTargetPlatform == TargetPlatform.macOS, - ); + group('setPersistence()', () { + test('throw an unimplemented error', () async { + try { + await FirebaseAuth.instance.setPersistence(Persistence.LOCAL); + fail('Should have thrown'); + } catch (e) { + expect(e, isInstanceOf()); + } + }, skip: kIsWeb || defaultTargetPlatform == TargetPlatform.macOS); - test( - 'should set persistence', - () async { - try { - await FirebaseAuth.instance.setPersistence(Persistence.LOCAL); - } catch (e) { - fail('unexpected error thrown'); - } - }, - skip: !kIsWeb, - ); - }, - skip: !kIsWeb && Platform.isWindows, - ); + test('should set persistence', () async { + try { + await FirebaseAuth.instance.setPersistence(Persistence.LOCAL); + } catch (e) { + fail('unexpected error thrown'); + } + }, skip: !kIsWeb); + }, skip: !kIsWeb && Platform.isWindows); group('signInAnonymously()', () { - test( - 'should sign in anonymously', - () async { - Future successCallback(UserCredential currentUserCredential) async { - final currentUser = currentUserCredential.user; - - expect(currentUser, isA()); - expect(currentUser?.uid, isA()); - expect(currentUser?.email, isNull); - expect(currentUser?.isAnonymous, isTrue); - expect( - currentUser?.uid, - equals(FirebaseAuth.instance.currentUser!.uid), - ); + test('should sign in anonymously', () async { + Future successCallback(UserCredential currentUserCredential) async { + final currentUser = currentUserCredential.user; + + expect(currentUser, isA()); + expect(currentUser?.uid, isA()); + expect(currentUser?.email, isNull); + expect(currentUser?.isAnonymous, isTrue); + expect( + currentUser?.uid, + equals(FirebaseAuth.instance.currentUser!.uid), + ); - var additionalUserInfo = currentUserCredential.additionalUserInfo; - expect(additionalUserInfo, isInstanceOf()); + var additionalUserInfo = currentUserCredential.additionalUserInfo; + expect(additionalUserInfo, isInstanceOf()); - await FirebaseAuth.instance.signOut(); - } + await FirebaseAuth.instance.signOut(); + } - final userCred = await FirebaseAuth.instance.signInAnonymously(); - await successCallback(userCred); - }, - skip: !kIsWeb && (Platform.isWindows || Platform.isMacOS), - ); + final userCred = await FirebaseAuth.instance.signInAnonymously(); + await successCallback(userCred); + }, skip: !kIsWeb && (Platform.isWindows || Platform.isMacOS)); }); group('signInWithCredential()', () { - test( - 'should login with email and password', - () async { - final credential = EmailAuthProvider.credential( - email: testEmail, - password: testPassword, - ); - await FirebaseAuth.instance - .signInWithCredential(credential) - .then(commonSuccessCallback); - }, - skip: !kIsWeb && (Platform.isWindows || Platform.isMacOS), - ); + test('should login with email and password', () async { + final credential = EmailAuthProvider.credential( + email: testEmail, + password: testPassword, + ); + await FirebaseAuth.instance + .signInWithCredential(credential) + .then(commonSuccessCallback); + }, skip: !kIsWeb && (Platform.isWindows || Platform.isMacOS)); test('throws if login user is disabled', () async { final credential = EmailAuthProvider.credential( @@ -679,9 +642,7 @@ void main() { expect(e.code, equals('user-disabled')); expect( e.message, - equals( - 'The user account has been disabled by an administrator.', - ), + equals('The user account has been disabled by an administrator.'), ); } catch (e) { fail(e.toString()); @@ -731,78 +692,75 @@ void main() { }); test( - 'throw Exception when using incorrect auth details with GoogleAuthProvider', - () async { - final credential = GoogleAuthProvider.credential( - idToken: 'incorrect idToken', - ); + 'throw Exception when using incorrect auth details with GoogleAuthProvider', + () async { + final credential = GoogleAuthProvider.credential( + idToken: 'incorrect idToken', + ); - await expectLater( - FirebaseAuth.instance.signInWithCredential(credential), - throwsA( - isA().having( - (e) => e.code, - 'code', - contains('invalid-credential'), + await expectLater( + FirebaseAuth.instance.signInWithCredential(credential), + throwsA( + isA().having( + (e) => e.code, + 'code', + contains('invalid-credential'), + ), ), - ), - ); + ); - final credential2 = GoogleAuthProvider.credential( - accessToken: 'incorrect accessToken', - ); + final credential2 = GoogleAuthProvider.credential( + accessToken: 'incorrect accessToken', + ); - await expectLater( - FirebaseAuth.instance.signInWithCredential(credential2), - throwsA( - isA(), - // Live project has this error code, emulator throws "internal-error" - // .having( - // (e) => e.code, - // 'code', - // contains('invalid-credential'), - // ), - ), - ); - }); + await expectLater( + FirebaseAuth.instance.signInWithCredential(credential2), + throwsA( + isA(), + // Live project has this error code, emulator throws "internal-error" + // .having( + // (e) => e.code, + // 'code', + // contains('invalid-credential'), + // ), + ), + ); + }, + ); }); - group( - 'signInWithCustomToken()', - () { - test('signs in with custom auth token', () async { - final userCredential = - await FirebaseAuth.instance.signInAnonymously(); - final uid = userCredential.user!.uid; - final claims = { - 'roles': [ - {'role': 'member'}, - {'role': 'admin'}, - ], - }; + group('signInWithCustomToken()', () { + test('signs in with custom auth token', () async { + final userCredential = await FirebaseAuth.instance + .signInAnonymously(); + final uid = userCredential.user!.uid; + final claims = { + 'roles': [ + {'role': 'member'}, + {'role': 'admin'}, + ], + }; - await ensureSignedOut(); + await ensureSignedOut(); - expect(FirebaseAuth.instance.currentUser, null); + expect(FirebaseAuth.instance.currentUser, null); - final customToken = emulatorCreateCustomToken(uid, claims: claims); + final customToken = emulatorCreateCustomToken(uid, claims: claims); - final customTokenUserCredential = - await FirebaseAuth.instance.signInWithCustomToken(customToken); + final customTokenUserCredential = await FirebaseAuth.instance + .signInWithCustomToken(customToken); - expect(customTokenUserCredential.user!.uid, equals(uid)); - expect(FirebaseAuth.instance.currentUser!.uid, equals(uid)); + expect(customTokenUserCredential.user!.uid, equals(uid)); + expect(FirebaseAuth.instance.currentUser!.uid, equals(uid)); - final idTokenResult = - await FirebaseAuth.instance.currentUser!.getIdTokenResult(); + final idTokenResult = await FirebaseAuth.instance.currentUser! + .getIdTokenResult(); - expect(idTokenResult.claims!['roles'], isA()); - expect(idTokenResult.claims!['roles'][0], isA()); - expect(idTokenResult.claims!['roles'][0]['role'], 'member'); - }); - }, - skip: !kIsWeb && (Platform.isWindows || Platform.isMacOS), - ); + expect(idTokenResult.claims!['roles'], isA()); + expect(idTokenResult.claims!['roles'][0], isA()); + expect(idTokenResult.claims!['roles'][0]['role'], 'member'); + }); + }, skip: !kIsWeb && (Platform.isWindows || Platform.isMacOS)); group('signInWithEmailAndPassword()', () { test('should login with email and password', () async { @@ -825,9 +783,7 @@ void main() { expect(e.code, equals('user-disabled')); expect( e.message, - equals( - 'The user account has been disabled by an administrator.', - ), + equals('The user account has been disabled by an administrator.'), ); } catch (e) { fail(e.toString()); @@ -910,7 +866,8 @@ void main() { } }, // TODO(SelaseKay): this needs to be investigated as now failing on android - skip: defaultTargetPlatform == TargetPlatform.iOS || + skip: + defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.android, ); @@ -960,7 +917,8 @@ void main() { } }); }, - skip: defaultTargetPlatform == TargetPlatform.macOS || + skip: + defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.windows, ); @@ -1005,94 +963,88 @@ void main() { expect(exception.code, equals('invalid-phone-number')); }); - test( - 'should auto verify phone number', - () async { - String testPhoneNumber = '+447444555666'; - String testSmsCode = '123456'; - await FirebaseAuth.instance.signInAnonymously(); - - Future getCredential() async { - final completer = Completer(); - - unawaited( - FirebaseAuth.instance.verifyPhoneNumber( - phoneNumber: testPhoneNumber, - // ignore: invalid_use_of_visible_for_testing_member - autoRetrievedSmsCodeForTesting: testSmsCode, - verificationCompleted: (PhoneAuthCredential credential) { - if (credential.smsCode != testSmsCode) { - return completer - .completeError(Exception('SMS code did not match')); - } - - completer.complete(credential); - }, - verificationFailed: (FirebaseException e) { - return completer.completeError( - Exception('Should not have been called'), - ); - }, - codeSent: (String verificationId, int? resetToken) { - return completer.completeError( - Exception('Should not have been called'), - ); - }, - codeAutoRetrievalTimeout: (String foo) { + test('should auto verify phone number', () async { + String testPhoneNumber = '+447444555666'; + String testSmsCode = '123456'; + await FirebaseAuth.instance.signInAnonymously(); + + Future getCredential() async { + final completer = Completer(); + + unawaited( + FirebaseAuth.instance.verifyPhoneNumber( + phoneNumber: testPhoneNumber, + // ignore: invalid_use_of_visible_for_testing_member + autoRetrievedSmsCodeForTesting: testSmsCode, + verificationCompleted: (PhoneAuthCredential credential) { + if (credential.smsCode != testSmsCode) { return completer.completeError( - Exception('Should not have been called'), + Exception('SMS code did not match'), ); - }, - ), - ); + } + + completer.complete(credential); + }, + verificationFailed: (FirebaseException e) { + return completer.completeError( + Exception('Should not have been called'), + ); + }, + codeSent: (String verificationId, int? resetToken) { + return completer.completeError( + Exception('Should not have been called'), + ); + }, + codeAutoRetrievalTimeout: (String foo) { + return completer.completeError( + Exception('Should not have been called'), + ); + }, + ), + ); - return completer.future.timeout(_completerTimeout); - } + return completer.future.timeout(_completerTimeout); + } - PhoneAuthCredential credential = await getCredential(); - expect(credential, isA()); - }, - skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android, - ); + PhoneAuthCredential credential = await getCredential(); + expect(credential, isA()); + }, skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android); }, - skip: defaultTargetPlatform == TargetPlatform.macOS || + skip: + defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.windows || kIsWeb, ); group('setSettings()', () { - test( - 'migrates the current user when changing access groups', - () async { - const accessGroup = - 'YYX2P3XVJ7.io.flutter.plugins.firebase.auth.example'; - final auth = FirebaseAuth.instance; + test('migrates the current user when changing access groups', () async { + const accessGroup = + 'YYX2P3XVJ7.io.flutter.plugins.firebase.auth.example'; + final auth = FirebaseAuth.instance; - await auth.signOut(); - final credential = await auth.signInAnonymously(); - final uid = credential.user!.uid; + await auth.signOut(); + final credential = await auth.signInAnonymously(); + final uid = credential.user!.uid; - try { - await auth.setSettings( - userAccessGroup: accessGroup, - migrateCurrentUser: true, - ); + try { + await auth.setSettings( + userAccessGroup: accessGroup, + migrateCurrentUser: true, + ); - // Prefer the reconciled Dart cache from setSettings, then prove - // the native session survived with a token round-trip. - expect(auth.currentUser, isNotNull); - expect(auth.currentUser!.uid, uid); - expect(auth.currentUser!.isAnonymous, isTrue); - final token = await auth.currentUser!.getIdToken(); - expect(token, isNotEmpty); - } finally { - // Leave later tests without this anonymous session. Access-group - // resets are not supported via null today (pre-existing). - await auth.signOut(); - } - }, - skip: kIsWeb || defaultTargetPlatform != TargetPlatform.iOS, - ); + // Prefer the reconciled Dart cache from setSettings, then prove + // the native session survived with a token round-trip. + expect(auth.currentUser, isNotNull); + expect(auth.currentUser!.uid, uid); + expect(auth.currentUser!.isAnonymous, isTrue); + final token = await auth.currentUser!.getIdToken(); + expect(token, isNotEmpty); + } finally { + // Leave later tests without this anonymous session. Access-group + // resets are not supported via null today (pre-existing). + await auth.signOut(); + } + }, skip: kIsWeb || defaultTargetPlatform != TargetPlatform.iOS); test( 'throws argument error if phoneNumber & smsCode have not been set simultaneously', @@ -1102,16 +1054,22 @@ void main() { await expectLater( FirebaseAuth.instance.setSettings(phoneNumber: '123456'), throwsA( - isA() - .having((e) => e.message, 'message', contains(message)), + isA().having( + (e) => e.message, + 'message', + contains(message), + ), ), ); await expectLater( FirebaseAuth.instance.setSettings(smsCode: '123456'), throwsA( - isA() - .having((e) => e.message, 'message', contains(message)), + isA().having( + (e) => e.message, + 'message', + contains(message), + ), ), ); }, @@ -1147,20 +1105,24 @@ void main() { expect(status.meetsMinPasswordLength, isFalse); }); - test('should not validate a password that has no uppercase characters', - () async { - final PasswordValidationStatus status = await FirebaseAuth.instance - .validatePassword(FirebaseAuth.instance, invalidPassword2); - expect(status.isValid, isFalse); - expect(status.meetsUppercaseRequirement, isFalse); - }); + test( + 'should not validate a password that has no uppercase characters', + () async { + final PasswordValidationStatus status = await FirebaseAuth.instance + .validatePassword(FirebaseAuth.instance, invalidPassword2); + expect(status.isValid, isFalse); + expect(status.meetsUppercaseRequirement, isFalse); + }, + ); - test('should not validate a password that has no lowercase characters', - () async { - final PasswordValidationStatus status = await FirebaseAuth.instance - .validatePassword(FirebaseAuth.instance, invalidPassword3); - expect(status.isValid, isFalse); - }); + test( + 'should not validate a password that has no lowercase characters', + () async { + final PasswordValidationStatus status = await FirebaseAuth.instance + .validatePassword(FirebaseAuth.instance, invalidPassword3); + expect(status.isValid, isFalse); + }, + ); test('should not validate a password that has no digits', () async { final PasswordValidationStatus status = await FirebaseAuth.instance diff --git a/packages/firebase_auth/firebase_auth/example/integration_test/firebase_auth_multi_factor_e2e_test.dart b/packages/firebase_auth/firebase_auth/example/integration_test/firebase_auth_multi_factor_e2e_test.dart index 25dff54524c0..c61f0aedc0a7 100644 --- a/packages/firebase_auth/firebase_auth/example/integration_test/firebase_auth_multi_factor_e2e_test.dart +++ b/packages/firebase_auth/firebase_auth/example/integration_test/firebase_auth_multi_factor_e2e_test.dart @@ -19,630 +19,582 @@ const _completerTimeout = Duration(seconds: 60); void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - group( - '$MultiFactor', - () { - String email = generateRandomEmail(); - - group('multiFactor', () { - test('should return an empty enrolled factor', () async { - // Setup - User? user; - UserCredential userCredential; - - userCredential = - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); - user = userCredential.user; + group('$MultiFactor', () { + String email = generateRandomEmail(); - final multiFactor = user!.multiFactor; + group('multiFactor', () { + test('should return an empty enrolled factor', () async { + // Setup + User? user; + UserCredential userCredential; - // Assertions - expect((await multiFactor.getEnrolledFactors()).length, 0); - }); - }); - - group('session', () { - test('should return an empty enrolled factor', () async { - // Setup - User? user; - UserCredential userCredential; - - userCredential = - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); - user = userCredential.user; - - final multiFactor = user!.multiFactor; + userCredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( + email: email, + password: testPassword, + ); + user = userCredential.user; - final session = await multiFactor.getSession(); + final multiFactor = user!.multiFactor; - // Assertions - expect(session.id, isNotNull); - }); + // Assertions + expect((await multiFactor.getEnrolledFactors()).length, 0); }); + }); - group('enrollFactor', () { - test( - 'should enroll and unenroll factor', - () async { - String testPhoneNumber = '+441444555666'; - User? user; - UserCredential userCredential; + group('session', () { + test('should return an empty enrolled factor', () async { + // Setup + User? user; + UserCredential userCredential; - userCredential = - await FirebaseAuth.instance.createUserWithEmailAndPassword( + userCredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( email: email, password: testPassword, ); - user = userCredential.user; - - await user!.sendEmailVerification(); - final oobCode = (await emulatorOutOfBandCode( - email, - EmulatorOobCodeType.verifyEmail, - ))!; + user = userCredential.user; - await emulatorVerifyEmail( - oobCode.oobCode!, - ); + final multiFactor = user!.multiFactor; - final multiFactor = user.multiFactor; - final session = await multiFactor.getSession(); - - Future getCredential() async { - Completer completer = Completer(); - - unawaited( - FirebaseAuth.instance.verifyPhoneNumber( - phoneNumber: testPhoneNumber, - multiFactorSession: session, - verificationCompleted: (PhoneAuthCredential credential) { - if (!completer.isCompleted) { - return completer.completeError( - Exception( - 'verificationCompleted should not have been called', - ), - ); - } - }, - verificationFailed: (FirebaseException e) { - if (!completer.isCompleted) { - return completer.completeError( - Exception( - 'verificationFailed should not have been called', - ), - ); - } - }, - codeSent: (String verificationId, int? resetToken) { - completer.complete(verificationId); - }, - codeAutoRetrievalTimeout: (String foo) { - if (!completer.isCompleted) { - return completer.completeError( - Exception( - 'codeAutoRetrievalTimeout should not have been called', - ), - ); - } - }, - ), - ); + final session = await multiFactor.getSession(); - return completer.future.timeout(_completerTimeout) - as FutureOr; - } - - final verificationId = await getCredential(); + // Assertions + expect(session.id, isNotNull); + }); + }); - final smsCode = await emulatorPhoneVerificationCode( - testPhoneNumber, - ); + group('enrollFactor', () { + test('should enroll and unenroll factor', () async { + String testPhoneNumber = '+441444555666'; + User? user; + UserCredential userCredential; - final credential = PhoneAuthProvider.credential( - verificationId: verificationId, - smsCode: smsCode!, + userCredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( + email: email, + password: testPassword, ); + user = userCredential.user; + + await user!.sendEmailVerification(); + final oobCode = (await emulatorOutOfBandCode( + email, + EmulatorOobCodeType.verifyEmail, + ))!; + + await emulatorVerifyEmail(oobCode.oobCode!); + + final multiFactor = user.multiFactor; + final session = await multiFactor.getSession(); + + Future getCredential() async { + Completer completer = Completer(); + + unawaited( + FirebaseAuth.instance.verifyPhoneNumber( + phoneNumber: testPhoneNumber, + multiFactorSession: session, + verificationCompleted: (PhoneAuthCredential credential) { + if (!completer.isCompleted) { + return completer.completeError( + Exception( + 'verificationCompleted should not have been called', + ), + ); + } + }, + verificationFailed: (FirebaseException e) { + if (!completer.isCompleted) { + return completer.completeError( + Exception('verificationFailed should not have been called'), + ); + } + }, + codeSent: (String verificationId, int? resetToken) { + completer.complete(verificationId); + }, + codeAutoRetrievalTimeout: (String foo) { + if (!completer.isCompleted) { + return completer.completeError( + Exception( + 'codeAutoRetrievalTimeout should not have been called', + ), + ); + } + }, + ), + ); - expect(credential, isA()); - - await user.multiFactor.enroll( - PhoneMultiFactorGenerator.getAssertion( - credential, - ), - displayName: 'My phone number', - ); + return completer.future.timeout(_completerTimeout) + as FutureOr; + } - final enrolledFactors = await multiFactor.getEnrolledFactors(); + final verificationId = await getCredential(); - // Assertions - expect(enrolledFactors.length, 1); - expect(enrolledFactors.first.displayName, 'My phone number'); + final smsCode = await emulatorPhoneVerificationCode(testPhoneNumber); - await user.multiFactor.unenroll( - multiFactorInfo: enrolledFactors.first, - ); + final credential = PhoneAuthProvider.credential( + verificationId: verificationId, + smsCode: smsCode!, + ); - final enrolledFactorsAfter = await multiFactor.getEnrolledFactors(); + expect(credential, isA()); - // Assertions - expect(enrolledFactorsAfter.length, 0); - }, - skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android, + await user.multiFactor.enroll( + PhoneMultiFactorGenerator.getAssertion(credential), + displayName: 'My phone number', ); - test( - 'should enroll and unenroll factor with signing out in the middle', - () async { - String email = generateRandomEmail(); + final enrolledFactors = await multiFactor.getEnrolledFactors(); - String testPhoneNumber = '+441444555626'; - User? user; - UserCredential userCredential; + // Assertions + expect(enrolledFactors.length, 1); + expect(enrolledFactors.first.displayName, 'My phone number'); - userCredential = - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); - user = userCredential.user; + await user.multiFactor.unenroll(multiFactorInfo: enrolledFactors.first); - await user!.sendEmailVerification(); - final oobCode = (await emulatorOutOfBandCode( - email, - EmulatorOobCodeType.verifyEmail, - ))!; + final enrolledFactorsAfter = await multiFactor.getEnrolledFactors(); - await emulatorVerifyEmail( - oobCode.oobCode!, - ); + // Assertions + expect(enrolledFactorsAfter.length, 0); + }, skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android); - await FirebaseAuth.instance.signOut(); + test( + 'should enroll and unenroll factor with signing out in the middle', + () async { + String email = generateRandomEmail(); - await FirebaseAuth.instance.signInWithEmailAndPassword( - email: email, - password: testPassword, - ); + String testPhoneNumber = '+441444555626'; + User? user; + UserCredential userCredential; - final multiFactor = user.multiFactor; - final session = await multiFactor.getSession(); - - Future getCredential() async { - Completer completer = Completer(); - - unawaited( - FirebaseAuth.instance.verifyPhoneNumber( - phoneNumber: testPhoneNumber, - multiFactorSession: session, - verificationCompleted: (PhoneAuthCredential credential) { - if (!completer.isCompleted) { - return completer.completeError( - Exception( - 'verificationCompleted should not have been called', - ), - ); - } - }, - verificationFailed: (FirebaseException e) { - if (!completer.isCompleted) { - return completer.completeError( - Exception( - 'verificationFailed should not have been called', - ), - ); - } - }, - codeSent: (String verificationId, int? resetToken) { - completer.complete(verificationId); - }, - codeAutoRetrievalTimeout: (String foo) { - if (!completer.isCompleted) { - return completer.completeError( - Exception( - 'codeAutoRetrievalTimeout should not have been called', - ), - ); - } - }, - ), + userCredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( + email: email, + password: testPassword, ); + user = userCredential.user; - return completer.future.timeout(_completerTimeout) - as FutureOr; - } + await user!.sendEmailVerification(); + final oobCode = (await emulatorOutOfBandCode( + email, + EmulatorOobCodeType.verifyEmail, + ))!; - final verificationId = await getCredential(); + await emulatorVerifyEmail(oobCode.oobCode!); - final smsCode = await emulatorPhoneVerificationCode( - testPhoneNumber, - ); + await FirebaseAuth.instance.signOut(); - final credential = PhoneAuthProvider.credential( - verificationId: verificationId, - smsCode: smsCode!, - ); + await FirebaseAuth.instance.signInWithEmailAndPassword( + email: email, + password: testPassword, + ); - expect(credential, isA()); + final multiFactor = user.multiFactor; + final session = await multiFactor.getSession(); - await user.multiFactor.enroll( - PhoneMultiFactorGenerator.getAssertion( - credential, + Future getCredential() async { + Completer completer = Completer(); + + unawaited( + FirebaseAuth.instance.verifyPhoneNumber( + phoneNumber: testPhoneNumber, + multiFactorSession: session, + verificationCompleted: (PhoneAuthCredential credential) { + if (!completer.isCompleted) { + return completer.completeError( + Exception( + 'verificationCompleted should not have been called', + ), + ); + } + }, + verificationFailed: (FirebaseException e) { + if (!completer.isCompleted) { + return completer.completeError( + Exception( + 'verificationFailed should not have been called', + ), + ); + } + }, + codeSent: (String verificationId, int? resetToken) { + completer.complete(verificationId); + }, + codeAutoRetrievalTimeout: (String foo) { + if (!completer.isCompleted) { + return completer.completeError( + Exception( + 'codeAutoRetrievalTimeout should not have been called', + ), + ); + } + }, ), - displayName: 'My phone number', ); - final enrolledFactors = await multiFactor.getEnrolledFactors(); + return completer.future.timeout(_completerTimeout) + as FutureOr; + } - // Assertions - expect(enrolledFactors.length, 1); - expect(enrolledFactors.first.displayName, 'My phone number'); + final verificationId = await getCredential(); - await user.multiFactor.unenroll( - multiFactorInfo: enrolledFactors.first, - ); + final smsCode = await emulatorPhoneVerificationCode(testPhoneNumber); - final enrolledFactorsAfter = await multiFactor.getEnrolledFactors(); + final credential = PhoneAuthProvider.credential( + verificationId: verificationId, + smsCode: smsCode!, + ); - // Assertions - expect(enrolledFactorsAfter.length, 0); - }, - skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android, - ); + expect(credential, isA()); - test( - 'should enroll and throw if trying to unenroll an unknown factor', - () async { - final email = generateRandomEmail(); - String testPhoneNumber = '+441444555667'; - User? user; - UserCredential userCredential; + await user.multiFactor.enroll( + PhoneMultiFactorGenerator.getAssertion(credential), + displayName: 'My phone number', + ); - userCredential = - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); - user = userCredential.user; + final enrolledFactors = await multiFactor.getEnrolledFactors(); - await user!.sendEmailVerification(); - final oobCode = (await emulatorOutOfBandCode( - email, - EmulatorOobCodeType.verifyEmail, - ))!; + // Assertions + expect(enrolledFactors.length, 1); + expect(enrolledFactors.first.displayName, 'My phone number'); - await emulatorVerifyEmail( - oobCode.oobCode!, - ); + await user.multiFactor.unenroll( + multiFactorInfo: enrolledFactors.first, + ); - final multiFactor = user.multiFactor; - final session = await multiFactor.getSession(); - - Future getCredential() async { - Completer completer = Completer(); - - unawaited( - FirebaseAuth.instance.verifyPhoneNumber( - phoneNumber: testPhoneNumber, - multiFactorSession: session, - verificationCompleted: (PhoneAuthCredential credential) { - if (!completer.isCompleted) { - return completer.completeError( - Exception( - 'verificationCompleted should not have been called', - ), - ); - } - }, - verificationFailed: (FirebaseException e) { - if (!completer.isCompleted) { - return completer.completeError( - Exception( - 'verificationFailed should not have been called', - ), - ); - } - }, - codeSent: (String verificationId, int? resetToken) { - completer.complete(verificationId); - }, - codeAutoRetrievalTimeout: (String foo) { - if (!completer.isCompleted) { - return completer.completeError( - Exception( - 'codeAutoRetrievalTimeout should not have been called', - ), - ); - } - }, - ), - ); + final enrolledFactorsAfter = await multiFactor.getEnrolledFactors(); - return completer.future.timeout(_completerTimeout) - as FutureOr; - } + // Assertions + expect(enrolledFactorsAfter.length, 0); + }, + skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android, + ); + + test( + 'should enroll and throw if trying to unenroll an unknown factor', + () async { + final email = generateRandomEmail(); + String testPhoneNumber = '+441444555667'; + User? user; + UserCredential userCredential; - final verificationId = await getCredential(); + userCredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( + email: email, + password: testPassword, + ); + user = userCredential.user; - final smsCode = await emulatorPhoneVerificationCode( - testPhoneNumber, - ); + await user!.sendEmailVerification(); + final oobCode = (await emulatorOutOfBandCode( + email, + EmulatorOobCodeType.verifyEmail, + ))!; - final credential = PhoneAuthProvider.credential( - verificationId: verificationId, - smsCode: smsCode!, - ); + await emulatorVerifyEmail(oobCode.oobCode!); - expect(credential, isA()); + final multiFactor = user.multiFactor; + final session = await multiFactor.getSession(); - await user.multiFactor.enroll( - PhoneMultiFactorGenerator.getAssertion( - credential, + Future getCredential() async { + Completer completer = Completer(); + + unawaited( + FirebaseAuth.instance.verifyPhoneNumber( + phoneNumber: testPhoneNumber, + multiFactorSession: session, + verificationCompleted: (PhoneAuthCredential credential) { + if (!completer.isCompleted) { + return completer.completeError( + Exception( + 'verificationCompleted should not have been called', + ), + ); + } + }, + verificationFailed: (FirebaseException e) { + if (!completer.isCompleted) { + return completer.completeError( + Exception( + 'verificationFailed should not have been called', + ), + ); + } + }, + codeSent: (String verificationId, int? resetToken) { + completer.complete(verificationId); + }, + codeAutoRetrievalTimeout: (String foo) { + if (!completer.isCompleted) { + return completer.completeError( + Exception( + 'codeAutoRetrievalTimeout should not have been called', + ), + ); + } + }, ), - displayName: 'My phone number', ); - final enrolledFactors = await multiFactor.getEnrolledFactors(); + return completer.future.timeout(_completerTimeout) + as FutureOr; + } - // Assertions - expect(enrolledFactors.length, 1); - expect(enrolledFactors.first.displayName, 'My phone number'); + final verificationId = await getCredential(); - await expectLater( - user.multiFactor.unenroll( - factorUid: 'unknown', - ), - throwsA(isA()), - ); + final smsCode = await emulatorPhoneVerificationCode(testPhoneNumber); - final enrolledFactorsAfter = await multiFactor.getEnrolledFactors(); + final credential = PhoneAuthProvider.credential( + verificationId: verificationId, + smsCode: smsCode!, + ); - // Assertions - expect(enrolledFactorsAfter.length, 1); - }, - // iOS is skipped due to Recaptcha trying to load on a simulator in CI - skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android, - ); + expect(credential, isA()); + + await user.multiFactor.enroll( + PhoneMultiFactorGenerator.getAssertion(credential), + displayName: 'My phone number', + ); + + final enrolledFactors = await multiFactor.getEnrolledFactors(); + + // Assertions + expect(enrolledFactors.length, 1); + expect(enrolledFactors.first.displayName, 'My phone number'); + + await expectLater( + user.multiFactor.unenroll(factorUid: 'unknown'), + throwsA(isA()), + ); - test( - 'should not enroll factor if email not verifed', - () async { - String testPhoneNumber = '+448444555666'; - User? user; - UserCredential userCredential; - final email = generateRandomEmail(); + final enrolledFactorsAfter = await multiFactor.getEnrolledFactors(); - userCredential = - await FirebaseAuth.instance.createUserWithEmailAndPassword( + // Assertions + expect(enrolledFactorsAfter.length, 1); + }, + // iOS is skipped due to Recaptcha trying to load on a simulator in CI + skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android, + ); + + test('should not enroll factor if email not verifed', () async { + String testPhoneNumber = '+448444555666'; + User? user; + UserCredential userCredential; + final email = generateRandomEmail(); + + userCredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( email: email, password: testPassword, ); - user = userCredential.user; - - final multiFactor = user!.multiFactor; - final session = await multiFactor.getSession(); - - Future getCredential() async { - Completer completer = Completer(); - - unawaited( - FirebaseAuth.instance.verifyPhoneNumber( - phoneNumber: testPhoneNumber, - multiFactorSession: session, - verificationCompleted: (PhoneAuthCredential credential) { - if (!completer.isCompleted) { - return completer.completeError( - Exception('Should not have been called'), - ); - } - }, - verificationFailed: (FirebaseException e) { - completer.complete(e); - }, - codeSent: (String verificationId, int? resetToken) { - if (!completer.isCompleted) { - return completer.completeError( - Exception('Should not have been called'), - ); - } - }, - codeAutoRetrievalTimeout: (String foo) { - if (!completer.isCompleted) { - return completer.completeError( - Exception('Should not have been called'), - ); - } - }, - ), - ); + user = userCredential.user; + + final multiFactor = user!.multiFactor; + final session = await multiFactor.getSession(); + + Future getCredential() async { + Completer completer = Completer(); + + unawaited( + FirebaseAuth.instance.verifyPhoneNumber( + phoneNumber: testPhoneNumber, + multiFactorSession: session, + verificationCompleted: (PhoneAuthCredential credential) { + if (!completer.isCompleted) { + return completer.completeError( + Exception('Should not have been called'), + ); + } + }, + verificationFailed: (FirebaseException e) { + completer.complete(e); + }, + codeSent: (String verificationId, int? resetToken) { + if (!completer.isCompleted) { + return completer.completeError( + Exception('Should not have been called'), + ); + } + }, + codeAutoRetrievalTimeout: (String foo) { + if (!completer.isCompleted) { + return completer.completeError( + Exception('Should not have been called'), + ); + } + }, + ), + ); - return completer.future.timeout(_completerTimeout) - as FutureOr; - } + return completer.future.timeout(_completerTimeout) + as FutureOr; + } - final exception = await getCredential(); + final exception = await getCredential(); - expect(exception, isNotNull); - }, - ); + expect(exception, isNotNull); }); + }); - group('signIn', () { - test( - 'should sign in with 2 factors', - () async { - String testPhoneNumber = '+449444555666'; - User? user; - UserCredential userCredential; + group('signIn', () { + test('should sign in with 2 factors', () async { + String testPhoneNumber = '+449444555666'; + User? user; + UserCredential userCredential; - userCredential = - await FirebaseAuth.instance.createUserWithEmailAndPassword( + userCredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( email: email, password: testPassword, ); - user = userCredential.user; - - await user!.sendEmailVerification(); - final oobCode = (await emulatorOutOfBandCode( - email, - EmulatorOobCodeType.verifyEmail, - ))!; - - await emulatorVerifyEmail( - oobCode.oobCode!, - ); - - final multiFactor = user.multiFactor; - final session = await multiFactor.getSession(); - - Future getCredential() async { - Completer completer = Completer(); - - unawaited( - FirebaseAuth.instance.verifyPhoneNumber( - phoneNumber: testPhoneNumber, - multiFactorSession: session, - verificationCompleted: (PhoneAuthCredential credential) { - if (!completer.isCompleted) { - return completer.completeError( - Exception('Should not have been called'), - ); - } - }, - verificationFailed: (FirebaseException e) { - if (!completer.isCompleted) { - return completer.completeError( - Exception('Should not have been called'), - ); - } - }, - codeSent: (String verificationId, int? resetToken) { - completer.complete(verificationId); - }, - codeAutoRetrievalTimeout: (String foo) { - if (!completer.isCompleted) { - return completer.completeError( - Exception('Should not have been called'), - ); - } - }, - ), - ); + user = userCredential.user; + + await user!.sendEmailVerification(); + final oobCode = (await emulatorOutOfBandCode( + email, + EmulatorOobCodeType.verifyEmail, + ))!; + + await emulatorVerifyEmail(oobCode.oobCode!); + + final multiFactor = user.multiFactor; + final session = await multiFactor.getSession(); + + Future getCredential() async { + Completer completer = Completer(); + + unawaited( + FirebaseAuth.instance.verifyPhoneNumber( + phoneNumber: testPhoneNumber, + multiFactorSession: session, + verificationCompleted: (PhoneAuthCredential credential) { + if (!completer.isCompleted) { + return completer.completeError( + Exception('Should not have been called'), + ); + } + }, + verificationFailed: (FirebaseException e) { + if (!completer.isCompleted) { + return completer.completeError( + Exception('Should not have been called'), + ); + } + }, + codeSent: (String verificationId, int? resetToken) { + completer.complete(verificationId); + }, + codeAutoRetrievalTimeout: (String foo) { + if (!completer.isCompleted) { + return completer.completeError( + Exception('Should not have been called'), + ); + } + }, + ), + ); - return completer.future.timeout(_completerTimeout) - as FutureOr; - } + return completer.future.timeout(_completerTimeout) + as FutureOr; + } - final verificationId = await getCredential(); + final verificationId = await getCredential(); - final smsCode = await emulatorPhoneVerificationCode( - testPhoneNumber, - ); + final smsCode = await emulatorPhoneVerificationCode(testPhoneNumber); - final credential = PhoneAuthProvider.credential( - verificationId: verificationId, - smsCode: smsCode!, - ); + final credential = PhoneAuthProvider.credential( + verificationId: verificationId, + smsCode: smsCode!, + ); - expect(credential, isA()); + expect(credential, isA()); - await user.multiFactor.enroll( - PhoneMultiFactorGenerator.getAssertion( - credential, - ), - displayName: 'My phone number', - ); + await user.multiFactor.enroll( + PhoneMultiFactorGenerator.getAssertion(credential), + displayName: 'My phone number', + ); - await FirebaseAuth.instance.signOut(); + await FirebaseAuth.instance.signOut(); - Exception? exception; + Exception? exception; - try { - userCredential = - await FirebaseAuth.instance.signInWithEmailAndPassword( - email: email, - password: testPassword, - ); - } catch (e) { - exception = e as Exception; - } + try { + userCredential = await FirebaseAuth.instance + .signInWithEmailAndPassword(email: email, password: testPassword); + } catch (e) { + exception = e as Exception; + } - expect(exception, isA()); + expect(exception, isA()); - if (exception == null) { - throw Exception('Should not be null'); - } + if (exception == null) { + throw Exception('Should not be null'); + } - final FirebaseAuthMultiFactorException multiFactorException = - exception as FirebaseAuthMultiFactorException; + final FirebaseAuthMultiFactorException multiFactorException = + exception as FirebaseAuthMultiFactorException; - Future getCredentialSignIn() async { - Completer completer = Completer(); + Future getCredentialSignIn() async { + Completer completer = Completer(); - unawaited( - FirebaseAuth.instance.verifyPhoneNumber( - multiFactorInfo: multiFactorException.resolver.hints.first + unawaited( + FirebaseAuth.instance.verifyPhoneNumber( + multiFactorInfo: + multiFactorException.resolver.hints.first as PhoneMultiFactorInfo, - multiFactorSession: multiFactorException.resolver.session, - verificationCompleted: (PhoneAuthCredential credential) { - if (!completer.isCompleted) { - return completer.completeError( - Exception('Should not have been called'), - ); - } - }, - verificationFailed: (FirebaseException e) { - if (!completer.isCompleted) { - return completer.completeError( - Exception('Should not have been called'), - ); - } - }, - codeSent: (String verificationId, int? resetToken) { - completer.complete(verificationId); - }, - codeAutoRetrievalTimeout: (String foo) { - if (!completer.isCompleted) { - return completer.completeError( - Exception('Should not have been called'), - ); - } - }, - ), - ); - - return completer.future.timeout(_completerTimeout) - as FutureOr; - } + multiFactorSession: multiFactorException.resolver.session, + verificationCompleted: (PhoneAuthCredential credential) { + if (!completer.isCompleted) { + return completer.completeError( + Exception('Should not have been called'), + ); + } + }, + verificationFailed: (FirebaseException e) { + if (!completer.isCompleted) { + return completer.completeError( + Exception('Should not have been called'), + ); + } + }, + codeSent: (String verificationId, int? resetToken) { + completer.complete(verificationId); + }, + codeAutoRetrievalTimeout: (String foo) { + if (!completer.isCompleted) { + return completer.completeError( + Exception('Should not have been called'), + ); + } + }, + ), + ); - final verificationIdSignIn = await getCredentialSignIn(); + return completer.future.timeout(_completerTimeout) + as FutureOr; + } - final smsCodeSignIn = await emulatorPhoneVerificationCode( - testPhoneNumber, - ); + final verificationIdSignIn = await getCredentialSignIn(); - final credentialSignIn = PhoneAuthProvider.credential( - verificationId: verificationIdSignIn, - smsCode: smsCodeSignIn!, - ); + final smsCodeSignIn = await emulatorPhoneVerificationCode( + testPhoneNumber, + ); - expect(credentialSignIn, isA()); + final credentialSignIn = PhoneAuthProvider.credential( + verificationId: verificationIdSignIn, + smsCode: smsCodeSignIn!, + ); - await exception.resolver.resolveSignIn( - PhoneMultiFactorGenerator.getAssertion( - credentialSignIn, - ), - ); + expect(credentialSignIn, isA()); - expect(FirebaseAuth.instance.currentUser, isNotNull); - }, + await exception.resolver.resolveSignIn( + PhoneMultiFactorGenerator.getAssertion(credentialSignIn), ); + + expect(FirebaseAuth.instance.currentUser, isNotNull); }); - }, - skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android, - ); + }); + }, skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android); } diff --git a/packages/firebase_auth/firebase_auth/example/integration_test/firebase_auth_user_e2e_test.dart b/packages/firebase_auth/firebase_auth/example/integration_test/firebase_auth_user_e2e_test.dart index 0339d95da4d2..f41670661217 100644 --- a/packages/firebase_auth/firebase_auth/example/integration_test/firebase_auth_user_e2e_test.dart +++ b/packages/firebase_auth/firebase_auth/example/integration_test/firebase_auth_user_e2e_test.dart @@ -32,11 +32,11 @@ void main() { User? user; UserCredential userCredential; - userCredential = - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); + userCredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( + email: email, + password: testPassword, + ); user = userCredential.user; // Test @@ -46,46 +46,50 @@ void main() { expect(token?.length, greaterThan(24)); }); - test('should return a token using `getIdToken()` after sign in', - () async { - // Demonstrate fix for this issue works: https://github.com/firebase/flutterfire/issues/11297 - String email = generateRandomEmail(); + test( + 'should return a token using `getIdToken()` after sign in', + () async { + // Demonstrate fix for this issue works: https://github.com/firebase/flutterfire/issues/11297 + String email = generateRandomEmail(); - final userCredential = - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); + final userCredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( + email: email, + password: testPassword, + ); - String? token = await userCredential.user!.getIdToken(true); + String? token = await userCredential.user!.getIdToken(true); - expect(token?.length, greaterThan(24)); - }); + expect(token?.length, greaterThan(24)); + }, + ); - test('should return a token using `getIdTokenResult()` after sign in', - () async { - // Demonstrate fix for this issue works: https://github.com/firebase/flutterfire/issues/11297 - String email = generateRandomEmail(); + test( + 'should return a token using `getIdTokenResult()` after sign in', + () async { + // Demonstrate fix for this issue works: https://github.com/firebase/flutterfire/issues/11297 + String email = generateRandomEmail(); - final userCredential = - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); + final userCredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( + email: email, + password: testPassword, + ); - IdTokenResult result = - await userCredential.user!.getIdTokenResult(true); + IdTokenResult result = await userCredential.user! + .getIdTokenResult(true); - expect(result.token?.length, greaterThan(24)); - }); + expect(result.token?.length, greaterThan(24)); + }, + ); test('should catch error', () async { // Setup - final userCredential = - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); + final userCredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( + email: email, + password: testPassword, + ); final user = userCredential.user!; // needed for method to throw an error @@ -102,7 +106,8 @@ void main() { fail('should have thrown an error'); }); }, - skip: !kIsWeb && + skip: + !kIsWeb && (defaultTargetPlatform == TargetPlatform.windows || defaultTargetPlatform == TargetPlatform.macOS), ); @@ -112,11 +117,11 @@ void main() { 'should return a valid IdTokenResult Object', () async { // Setup - final userCredential = - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); + final userCredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( + email: email, + password: testPassword, + ); final user = userCredential.user!; // Test @@ -130,7 +135,8 @@ void main() { expect(idTokenResult.token!.length, greaterThan(24)); expect(idTokenResult.signInProvider, equals('password')); }, - skip: !kIsWeb && + skip: + !kIsWeb && (defaultTargetPlatform == TargetPlatform.windows || defaultTargetPlatform == TargetPlatform.macOS), ); @@ -144,13 +150,15 @@ void main() { await FirebaseAuth.instance.signInAnonymously(); final currentUID = FirebaseAuth.instance.currentUser!.uid; - final linkedUserCredential = - await FirebaseAuth.instance.currentUser!.linkWithCredential( - EmailAuthProvider.credential( - email: email, - password: testPassword, - ), - ); + final linkedUserCredential = await FirebaseAuth + .instance + .currentUser! + .linkWithCredential( + EmailAuthProvider.credential( + email: email, + password: testPassword, + ), + ); final linkedUser = linkedUserCredential.user!; expect(linkedUser.email, equals(email)); @@ -162,39 +170,41 @@ void main() { expect(linkedUser.isAnonymous, isFalse); }); - test('should error on link anon <-> email if email already exists', - () async { - // Setup - - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); - await FirebaseAuth.instance.signInAnonymously(); + test( + 'should error on link anon <-> email if email already exists', + () async { + // Setup - // Test - try { - await FirebaseAuth.instance.currentUser!.linkWithCredential( - EmailAuthProvider.credential( - email: email, - password: testPassword, - ), - ); - } on FirebaseAuthException catch (e) { - // Assertions - expect(e.code, 'email-already-in-use'); - expect( - e.message, - 'The email address is already in use by another account.', + await FirebaseAuth.instance.createUserWithEmailAndPassword( + email: email, + password: testPassword, ); + await FirebaseAuth.instance.signInAnonymously(); - // clean up - await FirebaseAuth.instance.currentUser!.delete(); - return; - } + // Test + try { + await FirebaseAuth.instance.currentUser!.linkWithCredential( + EmailAuthProvider.credential( + email: email, + password: testPassword, + ), + ); + } on FirebaseAuthException catch (e) { + // Assertions + expect(e.code, 'email-already-in-use'); + expect( + e.message, + 'The email address is already in use by another account.', + ); - fail('should have thrown an error'); - }); + // clean up + await FirebaseAuth.instance.currentUser!.delete(); + return; + } + + fail('should have thrown an error'); + }, + ); test( 'should link anonymous account <-> phone account', @@ -230,8 +240,9 @@ void main() { await FirebaseAuth.instance.currentUser!.linkWithCredential( PhoneAuthProvider.credential( verificationId: storedVerificationId, - smsCode: - (await emulatorPhoneVerificationCode(testPhoneNumber))!, + smsCode: (await emulatorPhoneVerificationCode( + testPhoneNumber, + ))!, ), ); expect(FirebaseAuth.instance.currentUser, equals(isA())); @@ -252,11 +263,13 @@ void main() { equals(isA()), ); expect(FirebaseAuth.instance.currentUser!.isAnonymous, isFalse); - await FirebaseAuth.instance.currentUser - ?.unlink(PhoneAuthProvider.PROVIDER_ID); + await FirebaseAuth.instance.currentUser?.unlink( + PhoneAuthProvider.PROVIDER_ID, + ); await FirebaseAuth.instance.currentUser?.delete(); }, - skip: kIsWeb || + skip: + kIsWeb || defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.windows, ); // verifyPhoneNumber not supported on web. @@ -289,11 +302,13 @@ void main() { fail('should have thrown an error'); }, - skip: defaultTargetPlatform == TargetPlatform.macOS || + skip: + defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.windows, ); }, - skip: !kIsWeb && + skip: + !kIsWeb && (defaultTargetPlatform == TargetPlatform.windows || defaultTargetPlatform == TargetPlatform.macOS), ); @@ -367,11 +382,11 @@ void main() { test('should throw user-not-found or user-mismatch ', () async { // Setup - final userCredential = - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); + final userCredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( + email: email, + password: testPassword, + ); final user = userCredential.user; try { @@ -457,7 +472,8 @@ void main() { ); }); }, - skip: !kIsWeb && + skip: + !kIsWeb && (defaultTargetPlatform == TargetPlatform.windows || defaultTargetPlatform == TargetPlatform.macOS), ); @@ -499,12 +515,10 @@ void main() { FirebaseAuth.instance.currentUser!.photoURL, 'http://photo.url/test.jpg', ); - expect( - FirebaseAuth.instance.currentUser!.displayName, - isNull, - ); + expect(FirebaseAuth.instance.currentUser!.displayName, isNull); }, - skip: kIsWeb || + skip: + kIsWeb || defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.windows, ); @@ -520,12 +534,10 @@ void main() { // User created without photoURL — reload should not crash await FirebaseAuth.instance.currentUser!.reload(); - expect( - FirebaseAuth.instance.currentUser!.photoURL, - isNull, - ); + expect(FirebaseAuth.instance.currentUser!.photoURL, isNull); }, - skip: kIsWeb || + skip: + kIsWeb || defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.windows, ); @@ -562,20 +574,23 @@ void main() { // Test try { - await FirebaseAuth.instance.currentUser! - .sendEmailVerification(actionCodeSettings); + await FirebaseAuth.instance.currentUser!.sendEmailVerification( + actionCodeSettings, + ); } catch (error) { fail('$error'); } expect(FirebaseAuth.instance.currentUser, isNotNull); }, // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 - skip: kIsWeb || + skip: + kIsWeb || defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.windows, ); }, - skip: !kIsWeb && + skip: + !kIsWeb && (defaultTargetPlatform == TargetPlatform.windows || defaultTargetPlatform == TargetPlatform.macOS), ); @@ -591,8 +606,9 @@ void main() { email: email, password: testPassword, ); - await FirebaseAuth.instance.currentUser! - .linkWithCredential(credential); + await FirebaseAuth.instance.currentUser!.linkWithCredential( + credential, + ); // verify user is linked final linkedUser = FirebaseAuth.instance.currentUser; @@ -601,8 +617,9 @@ void main() { expect(linkedUser?.providerData.length, equals(1)); // Test - await FirebaseAuth.instance.currentUser! - .unlink(EmailAuthProvider.PROVIDER_ID); + await FirebaseAuth.instance.currentUser!.unlink( + EmailAuthProvider.PROVIDER_ID, + ); // Assertions final unlinkedUser = FirebaseAuth.instance.currentUser; @@ -610,60 +627,67 @@ void main() { expect(unlinkedUser?.providerData.length, equals(0)); }); - test('should throw error if provider id given does not exist', - () async { - // Setup - await FirebaseAuth.instance.signInAnonymously(); + test( + 'should throw error if provider id given does not exist', + () async { + // Setup + await FirebaseAuth.instance.signInAnonymously(); - AuthCredential credential = EmailAuthProvider.credential( - email: email, - password: testPassword, - ); - await FirebaseAuth.instance.currentUser! - .linkWithCredential(credential); + AuthCredential credential = EmailAuthProvider.credential( + email: email, + password: testPassword, + ); + await FirebaseAuth.instance.currentUser!.linkWithCredential( + credential, + ); - // verify user is linked - final linkedUser = FirebaseAuth.instance.currentUser; - expect(linkedUser?.email, email); + // verify user is linked + final linkedUser = FirebaseAuth.instance.currentUser; + expect(linkedUser?.email, email); - // Test - try { - await FirebaseAuth.instance.currentUser!.unlink('invalid'); - } on FirebaseAuthException catch (e) { - expect(e.code, 'no-such-provider'); - expect( - e.message, - 'User was not linked to an account with the given provider.', - ); - return; - } catch (e) { - fail('should have thrown an FirebaseAuthException error'); - } - fail('should have thrown an error'); - }); + // Test + try { + await FirebaseAuth.instance.currentUser!.unlink('invalid'); + } on FirebaseAuthException catch (e) { + expect(e.code, 'no-such-provider'); + expect( + e.message, + 'User was not linked to an account with the given provider.', + ); + return; + } catch (e) { + fail('should have thrown an FirebaseAuthException error'); + } + fail('should have thrown an error'); + }, + ); - test('should throw error if user does not have this provider linked', - () async { - // Setup - await FirebaseAuth.instance.signInAnonymously(); - // Test - try { - await FirebaseAuth.instance.currentUser! - .unlink(EmailAuthProvider.PROVIDER_ID); - } on FirebaseAuthException catch (e) { - expect(e.code, 'no-such-provider'); - expect( - e.message, - 'User was not linked to an account with the given provider.', - ); - return; - } catch (e) { - fail('should have thrown an FirebaseAuthException error'); - } - fail('should have thrown an error'); - }); + test( + 'should throw error if user does not have this provider linked', + () async { + // Setup + await FirebaseAuth.instance.signInAnonymously(); + // Test + try { + await FirebaseAuth.instance.currentUser!.unlink( + EmailAuthProvider.PROVIDER_ID, + ); + } on FirebaseAuthException catch (e) { + expect(e.code, 'no-such-provider'); + expect( + e.message, + 'User was not linked to an account with the given provider.', + ); + return; + } catch (e) { + fail('should have thrown an FirebaseAuthException error'); + } + fail('should have thrown an error'); + }, + ); }, - skip: !kIsWeb && + skip: + !kIsWeb && (defaultTargetPlatform == TargetPlatform.windows || defaultTargetPlatform == TargetPlatform.macOS), ); @@ -675,8 +699,10 @@ void main() { String pass = '${testPassword}1'; String pass2 = '${testPassword}2'; // Setup - await FirebaseAuth.instance - .createUserWithEmailAndPassword(email: email, password: pass); + await FirebaseAuth.instance.createUserWithEmailAndPassword( + email: email, + password: pass, + ); // Update user password await FirebaseAuth.instance.currentUser!.updatePassword(pass2); @@ -685,8 +711,10 @@ void main() { await FirebaseAuth.instance.signOut(); // Log in with the new password - await FirebaseAuth.instance - .signInWithEmailAndPassword(email: email, password: pass2); + await FirebaseAuth.instance.signInWithEmailAndPassword( + email: email, + password: pass2, + ); // Assertions expect(FirebaseAuth.instance.currentUser, isA()); @@ -713,126 +741,120 @@ void main() { fail('should have thrown an error'); }); }, - skip: !kIsWeb && + skip: + !kIsWeb && (defaultTargetPlatform == TargetPlatform.windows || defaultTargetPlatform == TargetPlatform.macOS), ); - group( - 'refreshToken', - () { - test( - 'should throw an unsupported error on non web platforms', - () async { - // Setup - await FirebaseAuth.instance.signInAnonymously(); + group('refreshToken', () { + test( + 'should throw an unsupported error on non web platforms', + () async { + // Setup + await FirebaseAuth.instance.signInAnonymously(); - // Test - FirebaseAuth.instance.currentUser!.refreshToken; + // Test + FirebaseAuth.instance.currentUser!.refreshToken; - // Assertions - expect( - FirebaseAuth.instance.currentUser!.refreshToken, - isNull, - ); - }, - // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 - // iOS supports it - skip: kIsWeb || - defaultTargetPlatform == TargetPlatform.macOS || - defaultTargetPlatform == TargetPlatform.iOS, - ); + // Assertions + expect(FirebaseAuth.instance.currentUser!.refreshToken, isNull); + }, + // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 + // iOS supports it + skip: + kIsWeb || + defaultTargetPlatform == TargetPlatform.macOS || + defaultTargetPlatform == TargetPlatform.iOS, + ); - test( - 'should return a token on web', - () async { - // Setup - await FirebaseAuth.instance.signInAnonymously(); + test('should return a token on web', () async { + // Setup + await FirebaseAuth.instance.signInAnonymously(); - // Test - FirebaseAuth.instance.currentUser!.refreshToken; + // Test + FirebaseAuth.instance.currentUser!.refreshToken; - // Assertions - expect( - FirebaseAuth.instance.currentUser!.refreshToken, - isA(), - ); - expect( - FirebaseAuth.instance.currentUser!.refreshToken!.isEmpty, - isFalse, - ); - }, - skip: !kIsWeb, + // Assertions + expect( + FirebaseAuth.instance.currentUser!.refreshToken, + isA(), ); - }, - skip: !kIsWeb && defaultTargetPlatform == TargetPlatform.windows, - ); + expect( + FirebaseAuth.instance.currentUser!.refreshToken!.isEmpty, + isFalse, + ); + }, skip: !kIsWeb); + }, skip: !kIsWeb && defaultTargetPlatform == TargetPlatform.windows); group( 'user.metadata', () { test( - "should have the properties 'lastSignInTime' & 'creationTime' which are ISO strings", - () async { - // Setup - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: generateRandomEmail(), - password: testPassword, - ); - final user = FirebaseAuth.instance.currentUser; + "should have the properties 'lastSignInTime' & 'creationTime' which are ISO strings", + () async { + // Setup + await FirebaseAuth.instance.createUserWithEmailAndPassword( + email: generateRandomEmail(), + password: testPassword, + ); + final user = FirebaseAuth.instance.currentUser; - // Test - final metadata = user?.metadata; + // Test + final metadata = user?.metadata; - // Assertions - expect(metadata?.lastSignInTime, isA()); - expect(metadata?.lastSignInTime!.year, DateTime.now().year); - expect(metadata?.creationTime, isA()); - expect(metadata?.creationTime!.year, DateTime.now().year); - }); + // Assertions + expect(metadata?.lastSignInTime, isA()); + expect(metadata?.lastSignInTime!.year, DateTime.now().year); + expect(metadata?.creationTime, isA()); + expect(metadata?.creationTime!.year, DateTime.now().year); + }, + ); }, - skip: !kIsWeb && + skip: + !kIsWeb && (defaultTargetPlatform == TargetPlatform.windows || defaultTargetPlatform == TargetPlatform.macOS), ); group('updateDisplayName', () { - test('updates the user displayName without impacting the photoURL', - () async { - // First create a user with a photo - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); - await FirebaseAuth.instance.currentUser! - .updateDisplayName('Mona Lisa'); - await FirebaseAuth.instance.currentUser!.updatePhotoURL( - 'http://photo.url/test.jpg', - ); - await FirebaseAuth.instance.currentUser!.reload(); + test( + 'updates the user displayName without impacting the photoURL', + () async { + // First create a user with a photo + await FirebaseAuth.instance.createUserWithEmailAndPassword( + email: email, + password: testPassword, + ); + await FirebaseAuth.instance.currentUser!.updateDisplayName( + 'Mona Lisa', + ); + await FirebaseAuth.instance.currentUser!.updatePhotoURL( + 'http://photo.url/test.jpg', + ); + await FirebaseAuth.instance.currentUser!.reload(); - expect( - FirebaseAuth.instance.currentUser!.photoURL, - 'http://photo.url/test.jpg', - ); - expect( - FirebaseAuth.instance.currentUser!.displayName, - 'Mona Lisa', - ); + expect( + FirebaseAuth.instance.currentUser!.photoURL, + 'http://photo.url/test.jpg', + ); + expect(FirebaseAuth.instance.currentUser!.displayName, 'Mona Lisa'); - await FirebaseAuth.instance.currentUser! - .updateDisplayName('John Smith'); - await FirebaseAuth.instance.currentUser!.reload(); + await FirebaseAuth.instance.currentUser!.updateDisplayName( + 'John Smith', + ); + await FirebaseAuth.instance.currentUser!.reload(); - expect( - FirebaseAuth.instance.currentUser!.photoURL, - 'http://photo.url/test.jpg', - ); - expect( - FirebaseAuth.instance.currentUser!.displayName, - 'John Smith', - ); - }); + expect( + FirebaseAuth.instance.currentUser!.photoURL, + 'http://photo.url/test.jpg', + ); + expect( + FirebaseAuth.instance.currentUser!.displayName, + 'John Smith', + ); + }, + ); test( 'can set the displayName to null', @@ -842,39 +864,34 @@ void main() { email: email, password: testPassword, ); - await FirebaseAuth.instance.currentUser! - .updateDisplayName('Mona Lisa'); + await FirebaseAuth.instance.currentUser!.updateDisplayName( + 'Mona Lisa', + ); await FirebaseAuth.instance.currentUser!.reload(); // Just checking that the user indeed had a name before we set it to null - expect( - FirebaseAuth.instance.currentUser!.displayName, - isNotNull, - ); + expect(FirebaseAuth.instance.currentUser!.displayName, isNotNull); await FirebaseAuth.instance.currentUser!.updateDisplayName(null); await FirebaseAuth.instance.currentUser!.reload(); - expect( - FirebaseAuth.instance.currentUser!.displayName, - isNull, - ); + expect(FirebaseAuth.instance.currentUser!.displayName, isNull); // Skip apple CI because of https://github.com/firebase/firebase-ios-sdk/issues/8149 // Using `kIsWeb` because `Platform` is not available on web }, // setting `displayName` on web throws an error - skip: kIsWeb || + skip: + kIsWeb || defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.windows, ); }); - group( - 'updatePhotoURL', - () { - test('updates the photoURL without impacting the displayName', - () async { + group('updatePhotoURL', () { + test( + 'updates the photoURL without impacting the displayName', + () async { // First create a user with a photo await FirebaseAuth.instance.createUserWithEmailAndPassword( email: email, @@ -892,10 +909,7 @@ void main() { FirebaseAuth.instance.currentUser!.photoURL, 'http://photo.url/test.jpg', ); - expect( - FirebaseAuth.instance.currentUser!.displayName, - 'Mona Lisa', - ); + expect(FirebaseAuth.instance.currentUser!.displayName, 'Mona Lisa'); await FirebaseAuth.instance.currentUser!.updatePhotoURL( 'http://photo.url/dash.jpg', @@ -906,47 +920,39 @@ void main() { FirebaseAuth.instance.currentUser!.photoURL, 'http://photo.url/dash.jpg', ); - expect( - FirebaseAuth.instance.currentUser!.displayName, - 'Mona Lisa', - ); - }); + expect(FirebaseAuth.instance.currentUser!.displayName, 'Mona Lisa'); + }, + ); - test( - 'can set the photoURL to null', - () async { - // First create a user with a photo - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); - await FirebaseAuth.instance.currentUser!.updatePhotoURL( - 'http://photo.url/test.jpg', - ); - await FirebaseAuth.instance.currentUser!.reload(); + test( + 'can set the photoURL to null', + () async { + // First create a user with a photo + await FirebaseAuth.instance.createUserWithEmailAndPassword( + email: email, + password: testPassword, + ); + await FirebaseAuth.instance.currentUser!.updatePhotoURL( + 'http://photo.url/test.jpg', + ); + await FirebaseAuth.instance.currentUser!.reload(); - // Just checking that the user indeed had a photo before we set it to null - expect( - FirebaseAuth.instance.currentUser!.photoURL, - isNotNull, - ); + // Just checking that the user indeed had a photo before we set it to null + expect(FirebaseAuth.instance.currentUser!.photoURL, isNotNull); - await FirebaseAuth.instance.currentUser!.updatePhotoURL(null); - await FirebaseAuth.instance.currentUser!.reload(); + await FirebaseAuth.instance.currentUser!.updatePhotoURL(null); + await FirebaseAuth.instance.currentUser!.reload(); - expect( - FirebaseAuth.instance.currentUser!.photoURL, - isNull, - ); - }, - // setting `photoURL` on web throws an error - // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 - skip: kIsWeb || - defaultTargetPlatform == TargetPlatform.macOS || - defaultTargetPlatform == TargetPlatform.windows, - ); - }, - ); + expect(FirebaseAuth.instance.currentUser!.photoURL, isNull); + }, + // setting `photoURL` on web throws an error + // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 + skip: + kIsWeb || + defaultTargetPlatform == TargetPlatform.macOS || + defaultTargetPlatform == TargetPlatform.windows, + ); + }); group('updatePhoneNumber()', () { test( @@ -979,7 +985,8 @@ void main() { fail('should have thrown an error'); }, - skip: kIsWeb || + skip: + kIsWeb || defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.windows, ); @@ -990,11 +997,11 @@ void main() { () { test('should delete a user', () async { // Setup - UserCredential userCredential = - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); + UserCredential userCredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( + email: email, + password: testPassword, + ); final user = userCredential.user; // Test @@ -1004,46 +1011,53 @@ void main() { expect(FirebaseAuth.instance.currentUser, equals(null)); await FirebaseAuth.instance .createUserWithEmailAndPassword( - email: email, - password: testPassword, - ) + email: email, + password: testPassword, + ) .then((UserCredential userCredential) { - expect(FirebaseAuth.instance.currentUser!.email, equals(email)); - return; - }).catchError((Object error) { - fail('Should have successfully created user after deletion'); - }); + expect( + FirebaseAuth.instance.currentUser!.email, + equals(email), + ); + return; + }) + .catchError((Object error) { + fail('Should have successfully created user after deletion'); + }); }); - test('should throw an error on delete when no user is signed in', - () async { - // Setup - UserCredential userCredential = - await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: email, - password: testPassword, - ); - final user = userCredential.user; + test( + 'should throw an error on delete when no user is signed in', + () async { + // Setup + UserCredential userCredential = await FirebaseAuth.instance + .createUserWithEmailAndPassword( + email: email, + password: testPassword, + ); + final user = userCredential.user; - await FirebaseAuth.instance.signOut(); + await FirebaseAuth.instance.signOut(); - try { - // Test - await user!.delete(); - } on FirebaseAuthException catch (e) { - // Assertions - expect(e.code, 'no-current-user'); - expect(e.message, 'No user currently signed in.'); + try { + // Test + await user!.delete(); + } on FirebaseAuthException catch (e) { + // Assertions + expect(e.code, 'no-current-user'); + expect(e.message, 'No user currently signed in.'); - return; - } catch (e) { - fail('Should have thrown an FirebaseAuthException error'); - } + return; + } catch (e) { + fail('Should have thrown an FirebaseAuthException error'); + } - fail('Should have thrown an error'); - }); + fail('Should have thrown an error'); + }, + ); }, - skip: !kIsWeb && + skip: + !kIsWeb && (defaultTargetPlatform == TargetPlatform.windows || defaultTargetPlatform == TargetPlatform.macOS), ); diff --git a/packages/firebase_auth/firebase_auth/example/integration_test/report_test_results.dart b/packages/firebase_auth/firebase_auth/example/integration_test/report_test_results.dart index 038d20c39931..416b8cd76dd0 100644 --- a/packages/firebase_auth/firebase_auth/example/integration_test/report_test_results.dart +++ b/packages/firebase_auth/firebase_auth/example/integration_test/report_test_results.dart @@ -26,8 +26,9 @@ void reportTestResultsToDriver(IntegrationTestWidgetsFlutterBinding binding) { for (final entry in binding.results.entries) if (entry.value is Failure) entry.key, ]; - bool didFail(String name) => failures - .any((failure) => name == failure || name.endsWith(' $failure')); + bool didFail(String name) => failures.any( + (failure) => name == failure || name.endsWith(' $failure'), + ); binding.reportData ??= {}; binding.reportData!['testResults'] = { diff --git a/packages/firebase_auth/firebase_auth/example/integration_test/test_utils.dart b/packages/firebase_auth/firebase_auth/example/integration_test/test_utils.dart index bf7d0773e15f..f71af7bfa26b 100644 --- a/packages/firebase_auth/firebase_auth/example/integration_test/test_utils.dart +++ b/packages/firebase_auth/firebase_auth/example/integration_test/test_utils.dart @@ -28,12 +28,7 @@ const int testEmulatorPort = 9099; class EmulatorOobCode { @protected - EmulatorOobCode({ - this.type, - this.email, - this.oobCode, - this.oobLink, - }); + EmulatorOobCode({this.type, this.email, this.oobCode, this.oobLink}); final EmulatorOobCodeType? type; final String? email; @@ -48,10 +43,7 @@ enum EmulatorOobCodeType { verifyEmail, } -String generateRandomEmail({ - String prefix = '', - String suffix = '@foo.bar', -}) { +String generateRandomEmail({String prefix = '', String suffix = '@foo.bar'}) { var uuid = createCryptoRandomString(); var testEmail = prefix + uuid + suffix; return testEmail; @@ -63,9 +55,7 @@ Future emulatorClearAllUsers() async { Uri.parse( 'http://$testEmulatorHost:$testEmulatorPort/emulator/v1/projects/$_testFirebaseProjectId/accounts', ), - headers: { - 'Authorization': 'Bearer owner', - }, + headers: {'Authorization': 'Bearer owner'}, ); } @@ -92,13 +82,12 @@ Future emulatorPhoneVerificationCode(String phoneNumber) async { Uri.parse( 'http://$testEmulatorHost:$testEmulatorPort/emulator/v1/projects/$_testFirebaseProjectId/verificationCodes', ), - headers: { - 'Authorization': 'Bearer owner', - }, + headers: {'Authorization': 'Bearer owner'}, ); final responseBody = Map.from(jsonDecode(response.body)); - final verificationCodes = - List>.from(responseBody['verificationCodes']); + final verificationCodes = List>.from( + responseBody['verificationCodes'], + ); return verificationCodes.reversed.firstWhere( (verificationCode) => verificationCode['phoneNumber'] == phoneNumber, orElse: () => {'code': 'NOT_FOUND'}, @@ -126,9 +115,7 @@ Future emulatorOutOfBandCode( Uri.parse( 'http://$testEmulatorHost:$testEmulatorPort/emulator/v1/projects/$_testFirebaseProjectId/oobCodes', ), - headers: { - 'Authorization': 'Bearer owner', - }, + headers: {'Authorization': 'Bearer owner'}, ); String? requestType; @@ -179,14 +166,7 @@ String emulatorCreateCustomToken( final int iat = (DateTime.now().millisecondsSinceEpoch / 1000).floor(); final String jwtHeaderEncoded = base64 - .encode( - utf8.encode( - jsonEncode({ - 'alg': 'none', - 'typ': 'JWT', - }), - ), - ) + .encode(utf8.encode(jsonEncode({'alg': 'none', 'typ': 'JWT'}))) // Note that base64 padding ("=") must be omitted as per JWT spec. .replaceAll(RegExp(r'=+$'), ''); diff --git a/packages/firebase_auth/firebase_auth/example/lib/auth.dart b/packages/firebase_auth/firebase_auth/example/lib/auth.dart index 7e273b89874d..f70a62cc4e3d 100644 --- a/packages/firebase_auth/firebase_auth/example/lib/auth.dart +++ b/packages/firebase_auth/firebase_auth/example/lib/auth.dart @@ -38,10 +38,7 @@ class ScaffoldSnackbar { ScaffoldMessenger.of(_context) ..hideCurrentSnackBar() ..showSnackBar( - SnackBar( - content: Text(message), - behavior: SnackBarBehavior.floating, - ), + SnackBar(content: Text(message), behavior: SnackBarBehavior.floating), ); } } @@ -54,8 +51,8 @@ extension on AuthMode { String get label => this == AuthMode.login ? 'Sign in' : this == AuthMode.phone - ? 'Sign in' - : 'Register'; + ? 'Sign in' + : 'Register'; } enum OAuthButton { @@ -113,33 +110,22 @@ class _AuthGateState extends State { if (!kIsWeb && Platform.isMacOS) { authButtons = { - OAuthButton.apple: () => _handleMultiFactorException( - _signInWithApple, - ), + OAuthButton.apple: () => _handleMultiFactorException(_signInWithApple), }; } else { authButtons = { - OAuthButton.apple: () => _handleMultiFactorException( - _signInWithApple, - ), - OAuthButton.google: () => _handleMultiFactorException( - _signInWithGoogle, - ), - OAuthButton.github: () => _handleMultiFactorException( - _signInWithGitHub, - ), - OAuthButton.microsoft: () => _handleMultiFactorException( - _signInWithMicrosoft, - ), - OAuthButton.twitter: () => _handleMultiFactorException( - _signInWithTwitter, - ), - OAuthButton.yahoo: () => _handleMultiFactorException( - _signInWithYahoo, - ), - OAuthButton.facebook: () => _handleMultiFactorException( - _signInWithFacebook, - ), + OAuthButton.apple: () => _handleMultiFactorException(_signInWithApple), + OAuthButton.google: () => + _handleMultiFactorException(_signInWithGoogle), + OAuthButton.github: () => + _handleMultiFactorException(_signInWithGitHub), + OAuthButton.microsoft: () => + _handleMultiFactorException(_signInWithMicrosoft), + OAuthButton.twitter: () => + _handleMultiFactorException(_signInWithTwitter), + OAuthButton.yahoo: () => _handleMultiFactorException(_signInWithYahoo), + OAuthButton.facebook: () => + _handleMultiFactorException(_signInWithFacebook), }; } } @@ -166,8 +152,9 @@ class _AuthGateState extends State { Visibility( visible: error.isNotEmpty, child: MaterialBanner( - backgroundColor: - Theme.of(context).colorScheme.error, + backgroundColor: Theme.of( + context, + ).colorScheme.error, content: SelectableText(error), actions: [ TextButton( @@ -182,8 +169,9 @@ class _AuthGateState extends State { ), ), ], - contentTextStyle: - const TextStyle(color: Colors.white), + contentTextStyle: const TextStyle( + color: Colors.white, + ), padding: const EdgeInsets.all(10), ), ), @@ -201,8 +189,8 @@ class _AuthGateState extends State { autofillHints: const [AutofillHints.email], validator: (value) => value != null && value.isNotEmpty - ? null - : 'Required', + ? null + : 'Required', ), const SizedBox(height: 20), TextFormField( @@ -214,8 +202,8 @@ class _AuthGateState extends State { ), validator: (value) => value != null && value.isNotEmpty - ? null - : 'Required', + ? null + : 'Required', ), ], ), @@ -229,8 +217,8 @@ class _AuthGateState extends State { ), validator: (value) => value != null && value.isNotEmpty - ? null - : 'Required', + ? null + : 'Required', ), const SizedBox(height: 20), SizedBox( @@ -240,8 +228,8 @@ class _AuthGateState extends State { onPressed: isLoading ? null : () => _handleMultiFactorException( - _emailAndPassword, - ), + _emailAndPassword, + ), child: isLoading ? const CircularProgressIndicator.adaptive() : Text(mode.label), @@ -254,8 +242,9 @@ class _AuthGateState extends State { ...authButtons.keys .map( (button) => Padding( - padding: - const EdgeInsets.symmetric(vertical: 5), + padding: const EdgeInsets.symmetric( + vertical: 5, + ), child: AnimatedSwitcher( duration: const Duration(milliseconds: 200), child: isLoading @@ -429,8 +418,9 @@ class _AuthGateState extends State { setState(() { error = '${e.message}'; }); - final firstTotpHint = e.resolver.hints - .firstWhereOrNull((element) => element is TotpMultiFactorInfo); + final firstTotpHint = e.resolver.hints.firstWhereOrNull( + (element) => element is TotpMultiFactorInfo, + ); if (firstTotpHint != null) { final code = await getSmsCodeFromUser(context); final assertion = await TotpMultiFactorGenerator.getAssertionForSignIn( @@ -441,8 +431,9 @@ class _AuthGateState extends State { return; } - final firstPhoneHint = e.resolver.hints - .firstWhereOrNull((element) => element is PhoneMultiFactorInfo); + final firstPhoneHint = e.resolver.hints.firstWhereOrNull( + (element) => element is PhoneMultiFactorInfo, + ); if (firstPhoneHint is! PhoneMultiFactorInfo) { return; @@ -464,9 +455,7 @@ class _AuthGateState extends State { try { await e.resolver.resolveSignIn( - PhoneMultiFactorGenerator.getAssertion( - credential, - ), + PhoneMultiFactorGenerator.getAssertion(credential), ); } on FirebaseAuthException catch (e) { print(e.message); @@ -512,8 +501,9 @@ class _AuthGateState extends State { }); } else { if (kIsWeb) { - final confirmationResult = - await auth.signInWithPhoneNumber(phoneController.text); + final confirmationResult = await auth.signInWithPhoneNumber( + phoneController.text, + ); final smsCode = await getSmsCodeFromUser(context); if (smsCode != null) { diff --git a/packages/firebase_auth/firebase_auth/example/lib/firebase_options.dart b/packages/firebase_auth/firebase_auth/example/lib/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/firebase_auth/firebase_auth/example/lib/firebase_options.dart +++ b/packages/firebase_auth/firebase_auth/example/lib/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/firebase_auth/firebase_auth/example/lib/profile.dart b/packages/firebase_auth/firebase_auth/example/lib/profile.dart index 3ccbf5dbbaa3..8dcf78e850e9 100644 --- a/packages/firebase_auth/firebase_auth/example/lib/profile.dart +++ b/packages/firebase_auth/firebase_auth/example/lib/profile.dart @@ -151,9 +151,7 @@ class _ProfilePageState extends State { floatingLabelBehavior: FloatingLabelBehavior.never, alignLabelWithHint: true, label: Center( - child: Text( - 'Click to add a display name', - ), + child: Text('Click to add a display name'), ), ), ), @@ -196,8 +194,8 @@ class _ProfilePageState extends State { // e.g. final authorizationCode = userCredential.additionalUserInfo?.authorizationCode; await FirebaseAuth.instance .revokeTokenWithAuthorizationCode( - AuthGate.appleAuthorizationCode!, - ); + AuthGate.appleAuthorizationCode!, + ); // You may wish to delete the user at this point AuthGate.appleAuthorizationCode = null; } else { @@ -225,30 +223,34 @@ class _ProfilePageState extends State { phoneNumber: phoneController.text, verificationCompleted: (_) {}, verificationFailed: print, - codeSent: ( - String verificationId, - int? resendToken, - ) async { - final smsCode = await getSmsCodeFromUser(context); + codeSent: + ( + String verificationId, + int? resendToken, + ) async { + final smsCode = await getSmsCodeFromUser( + context, + ); - if (smsCode != null) { - // Create a PhoneAuthCredential with the code - final credential = PhoneAuthProvider.credential( - verificationId: verificationId, - smsCode: smsCode, - ); + if (smsCode != null) { + // Create a PhoneAuthCredential with the code + final credential = + PhoneAuthProvider.credential( + verificationId: verificationId, + smsCode: smsCode, + ); - try { - await user.multiFactor.enroll( - PhoneMultiFactorGenerator.getAssertion( - credential, - ), - ); - } on FirebaseAuthException catch (e) { - print(e.message); - } - } - }, + try { + await user.multiFactor.enroll( + PhoneMultiFactorGenerator.getAssertion( + credential, + ), + ); + } on FirebaseAuthException catch (e) { + print(e.message); + } + } + }, codeAutoRetrievalTimeout: print, ); }, @@ -259,8 +261,8 @@ class _ProfilePageState extends State { final totp = (await user.multiFactor.getEnrolledFactors()) .firstWhereOrNull( - (element) => element.factorId == 'totp', - ); + (element) => element.factorId == 'totp', + ); if (totp != null) { await user.multiFactor.unenroll( factorUid: @@ -274,18 +276,19 @@ class _ProfilePageState extends State { final session = await user.multiFactor.getSession(); final totpSecret = await TotpMultiFactorGenerator.generateSecret( - session, - ); + session, + ); print(totpSecret); - final code = - await getTotpFromUser(context, totpSecret); + final code = await getTotpFromUser( + context, + totpSecret, + ); print('code: $code'); if (code == null) { return; } await user.multiFactor.enroll( - await TotpMultiFactorGenerator - .getAssertionForEnrollment( + await TotpMultiFactorGenerator.getAssertionForEnrollment( totpSecret, code, ), @@ -297,8 +300,8 @@ class _ProfilePageState extends State { TextButton( onPressed: () async { try { - final enrolledFactors = - await user.multiFactor.getEnrolledFactors(); + final enrolledFactors = await user.multiFactor + .getEnrolledFactors(); await user.multiFactor.unenroll( factorUid: enrolledFactors.first.uid, diff --git a/packages/firebase_auth/firebase_auth/example/pubspec.yaml b/packages/firebase_auth/firebase_auth/example/pubspec.yaml index e7d40b5b3b5f..2c630effa84e 100644 --- a/packages/firebase_auth/firebase_auth/example/pubspec.yaml +++ b/packages/firebase_auth/firebase_auth/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the firebase_auth plugin. resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: barcode_widget: ^2.0.4 diff --git a/packages/firebase_auth/firebase_auth/example/test_driver/integration_test.dart b/packages/firebase_auth/firebase_auth/example/test_driver/integration_test.dart index 691723cbbfe1..9ccbcc26ab97 100644 --- a/packages/firebase_auth/firebase_auth/example/test_driver/integration_test.dart +++ b/packages/firebase_auth/firebase_auth/example/test_driver/integration_test.dart @@ -7,28 +7,32 @@ import 'dart:io'; import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver( - writeResponseOnFailure: true, - responseDataCallback: (Map? data) async { - final results = - (data?['testResults'] as Map?)?.cast() ?? - const {}; - var passed = 0; - var failed = 0; - for (final entry in results.entries) { - final ok = entry.value == 'success'; - ok ? passed++ : failed++; - // ignore: avoid_print - print('${ok ? '✅' : '❌'} ${entry.key}'); - } - // ignore: avoid_print - print('Web e2e summary: $passed passed, $failed failed, ' - '${results.length} total'); - if (results.isEmpty) { - // ignore: avoid_print - print('[E] No tests reported by the app - treating as ' - 'infrastructure failure.'); - exit(1); - } - await writeResponseData(data); - }, + writeResponseOnFailure: true, + responseDataCallback: (Map? data) async { + final results = + (data?['testResults'] as Map?)?.cast() ?? + const {}; + var passed = 0; + var failed = 0; + for (final entry in results.entries) { + final ok = entry.value == 'success'; + ok ? passed++ : failed++; + // ignore: avoid_print + print('${ok ? '✅' : '❌'} ${entry.key}'); + } + // ignore: avoid_print + print( + 'Web e2e summary: $passed passed, $failed failed, ' + '${results.length} total', ); + if (results.isEmpty) { + // ignore: avoid_print + print( + '[E] No tests reported by the app - treating as ' + 'infrastructure failure.', + ); + exit(1); + } + await writeResponseData(data); + }, +); diff --git a/packages/firebase_auth/firebase_auth/lib/src/confirmation_result.dart b/packages/firebase_auth/firebase_auth/lib/src/confirmation_result.dart index c039cd7917d9..a8e339c602b1 100644 --- a/packages/firebase_auth/firebase_auth/lib/src/confirmation_result.dart +++ b/packages/firebase_auth/firebase_auth/lib/src/confirmation_result.dart @@ -28,9 +28,6 @@ class ConfirmationResult { /// Finishes a phone number sign-in, link, or reauthentication, given the code /// that was sent to the user's mobile device. Future confirm(String verificationCode) async { - return UserCredential._( - _auth, - await _delegate.confirm(verificationCode), - ); + return UserCredential._(_auth, await _delegate.confirm(verificationCode)); } } diff --git a/packages/firebase_auth/firebase_auth/lib/src/firebase_auth.dart b/packages/firebase_auth/firebase_auth/lib/src/firebase_auth.dart index a3e86b45cb8e..68591ac0244f 100644 --- a/packages/firebase_auth/firebase_auth/lib/src/firebase_auth.dart +++ b/packages/firebase_auth/firebase_auth/lib/src/firebase_auth.dart @@ -31,7 +31,7 @@ class FirebaseAuth extends FirebasePlugin implements FirebaseService { FirebaseApp app; FirebaseAuth._({required this.app}) - : super(app.name, 'plugins.flutter.io/firebase_auth'); + : super(app.name, 'plugins.flutter.io/firebase_auth'); /// Returns an instance using the default [FirebaseApp]. static FirebaseAuth get instance { @@ -41,9 +41,7 @@ class FirebaseAuth extends FirebasePlugin implements FirebaseService { } /// Returns an instance using a specified [FirebaseApp]. - factory FirebaseAuth.instanceFor({ - required FirebaseApp app, - }) { + factory FirebaseAuth.instanceFor({required FirebaseApp app}) { return _firebaseAuthInstances.putIfAbsent(app.name, () { final instance = FirebaseAuth._(app: app); app.registerService( @@ -89,8 +87,11 @@ class FirebaseAuth extends FirebasePlugin implements FirebaseService { /// /// Note: Must be called immediately, prior to accessing auth methods. /// Do not use with production credentials as emulator traffic is not encrypted. - Future useAuthEmulator(String host, int port, - {bool automaticHostMapping = true}) async { + Future useAuthEmulator( + String host, + int port, { + bool automaticHostMapping = true, + }) async { String mappedHost = automaticHostMapping ? getMappedHost(host) : host; await _delegate.useAuthEmulator(mappedHost, port); @@ -133,9 +134,7 @@ class FirebaseAuth extends FirebasePlugin implements FirebaseService { final message = defaultTargetPlatform == TargetPlatform.windows ? 'Cannot set custom auth domain on a FirebaseAuth instance for windows platform' : 'Cannot set custom auth domain on a FirebaseAuth instance. Set the custom auth domain on `FirebaseOptions.authDomain` instance and pass into `Firebase.initializeApp()` instead.'; - throw UnimplementedError( - message, - ); + throw UnimplementedError(message); } _delegate.customAuthDomain = customAuthDomain; } @@ -262,13 +261,15 @@ class FirebaseAuth extends FirebasePlugin implements FirebaseService { /// Internal helper which pipes internal [Stream] events onto /// a users own Stream. Stream _pipeStreamChanges(Stream stream) { - return stream.map((delegateUser) { - if (delegateUser == null) { - return null; - } + return stream + .map((delegateUser) { + if (delegateUser == null) { + return null; + } - return User._(this, delegateUser); - }).asBroadcastStream(onCancel: (sub) => sub.cancel()); + return User._(this, delegateUser); + }) + .asBroadcastStream(onCancel: (sub) => sub.cancel()); } /// Notifies about changes to the user's sign-in state (such as sign-in or @@ -535,7 +536,9 @@ class FirebaseAuth extends FirebasePlugin implements FirebaseService { Future signInWithCustomToken(String token) async { try { return UserCredential._( - this, await _delegate.signInWithCustomToken(token)); + this, + await _delegate.signInWithCustomToken(token), + ); } on FirebaseAuthMultiFactorExceptionPlatform catch (e) { throw FirebaseAuthMultiFactorException._(this, e); } catch (e) { @@ -646,9 +649,7 @@ class FirebaseAuth extends FirebasePlugin implements FirebaseService { /// A [FirebaseAuthException] maybe thrown with the following error code: /// - **user-disabled**: /// - Thrown if the user corresponding to the given email has been disabled. - Future signInWithProvider( - AuthProvider provider, - ) async { + Future signInWithProvider(AuthProvider provider) async { try { return UserCredential._( this, @@ -679,8 +680,10 @@ class FirebaseAuth extends FirebasePlugin implements FirebaseService { // also clear that instance before proceeding. bool mustClear = verifier == null; verifier ??= RecaptchaVerifier(auth: _delegate); - final result = - await _delegate.signInWithPhoneNumber(phoneNumber, verifier.delegate); + final result = await _delegate.signInWithPhoneNumber( + phoneNumber, + verifier.delegate, + ); if (mustClear) { verifier.clear(); } @@ -887,10 +890,11 @@ class FirebaseAuth extends FirebasePlugin implements FirebaseService { message: 'Password cannot be null or empty', ); } - PasswordPolicyApi passwordPolicyApi = - PasswordPolicyApi(auth.app.options.apiKey); - PasswordPolicy passwordPolicy = - await passwordPolicyApi.fetchPasswordPolicy(); + PasswordPolicyApi passwordPolicyApi = PasswordPolicyApi( + auth.app.options.apiKey, + ); + PasswordPolicy passwordPolicy = await passwordPolicyApi + .fetchPasswordPolicy(); PasswordPolicyImpl passwordPolicyImpl = PasswordPolicyImpl(passwordPolicy); return passwordPolicyImpl.isPasswordValid(password); } diff --git a/packages/firebase_auth/firebase_auth/lib/src/multi_factor.dart b/packages/firebase_auth/firebase_auth/lib/src/multi_factor.dart index 4610e284fba9..0c910499b0b5 100644 --- a/packages/firebase_auth/firebase_auth/lib/src/multi_factor.dart +++ b/packages/firebase_auth/firebase_auth/lib/src/multi_factor.dart @@ -57,11 +57,10 @@ class MultiFactor { class PhoneMultiFactorGenerator { /// Transforms a PhoneAuthCredential into a [MultiFactorAssertion] /// which can be used to confirm ownership of a phone second factor. - static MultiFactorAssertion getAssertion( - PhoneAuthCredential credential, - ) { - final assertion = - PhoneMultiFactorGeneratorPlatform.instance.getAssertion(credential); + static MultiFactorAssertion getAssertion(PhoneAuthCredential credential) { + final assertion = PhoneMultiFactorGeneratorPlatform.instance.getAssertion( + credential, + ); return MultiFactorAssertion._(assertion); } } @@ -70,11 +69,9 @@ class PhoneMultiFactorGenerator { class TotpMultiFactorGenerator { /// Transforms a PhoneAuthCredential into a [MultiFactorAssertion] /// which can be used to confirm ownership of a phone second factor. - static Future generateSecret( - MultiFactorSession session, - ) async { - final secret = - await TotpMultiFactorGeneratorPlatform.instance.generateSecret(session); + static Future generateSecret(MultiFactorSession session) async { + final secret = await TotpMultiFactorGeneratorPlatform.instance + .generateSecret(session); return TotpSecret._( secret.codeIntervalSeconds, secret.codeLength, @@ -92,10 +89,7 @@ class TotpMultiFactorGenerator { String oneTimePassword, ) async { final assertion = await TotpMultiFactorGeneratorPlatform.instance - .getAssertionForEnrollment( - secret._instance, - oneTimePassword, - ); + .getAssertionForEnrollment(secret._instance, oneTimePassword); return MultiFactorAssertion._(assertion); } @@ -106,11 +100,8 @@ class TotpMultiFactorGenerator { String enrollmentId, String oneTimePassword, ) async { - final assertion = - await TotpMultiFactorGeneratorPlatform.instance.getAssertionForSignIn( - enrollmentId, - oneTimePassword, - ); + final assertion = await TotpMultiFactorGeneratorPlatform.instance + .getAssertionForSignIn(enrollmentId, oneTimePassword); return MultiFactorAssertion._(assertion); } @@ -135,10 +126,7 @@ class TotpSecret { ); /// Generate a TOTP secret for the authenticated user. - Future generateQrCodeUrl({ - String? accountName, - String? issuer, - }) { + Future generateQrCodeUrl({String? accountName, String? issuer}) { return _instance.generateQrCodeUrl( accountName: accountName, issuer: issuer, @@ -146,12 +134,8 @@ class TotpSecret { } /// Opens the specified QR Code URL in a password manager like iCloud Keychain. - Future openInOtpApp( - String qrCodeUrl, - ) async { - await _instance.openInOtpApp( - qrCodeUrl, - ); + Future openInOtpApp(String qrCodeUrl) async { + await _instance.openInOtpApp(qrCodeUrl); } } @@ -184,9 +168,7 @@ class MultiFactorResolver { /// Completes sign in with a second factor using an MultiFactorAssertion which /// confirms that the user has successfully completed the second factor challenge. - Future resolveSignIn( - MultiFactorAssertion assertion, - ) async { + Future resolveSignIn(MultiFactorAssertion assertion) async { final credential = await _delegate.resolveSignIn(assertion._delegate); return UserCredential._(_auth, credential); } @@ -199,14 +181,14 @@ class FirebaseAuthMultiFactorException extends FirebaseAuthException { final FirebaseAuthMultiFactorExceptionPlatform _delegate; FirebaseAuthMultiFactorException._(this._auth, this._delegate) - : super( - code: _delegate.code, - message: _delegate.message, - email: _delegate.email, - credential: _delegate.credential, - phoneNumber: _delegate.phoneNumber, - tenantId: _delegate.tenantId, - ); + : super( + code: _delegate.code, + message: _delegate.message, + email: _delegate.email, + credential: _delegate.credential, + phoneNumber: _delegate.phoneNumber, + tenantId: _delegate.tenantId, + ); MultiFactorResolver get resolver => MultiFactorResolver._(_auth, _delegate.resolver); diff --git a/packages/firebase_auth/firebase_auth/lib/src/user.dart b/packages/firebase_auth/firebase_auth/lib/src/user.dart index 4e40dd0ab661..069a9bab1024 100644 --- a/packages/firebase_auth/firebase_auth/lib/src/user.dart +++ b/packages/firebase_auth/firebase_auth/lib/src/user.dart @@ -236,9 +236,7 @@ class User { /// - Thrown if you have not enabled the provider in the Firebase Console. Go /// to the Firebase Console for your project, in the Auth section and the /// Sign in Method tab and configure the provider. - Future linkWithProvider( - AuthProvider provider, - ) async { + Future linkWithProvider(AuthProvider provider) async { try { return UserCredential._( _auth, @@ -328,9 +326,7 @@ class User { /// - **invalid-verification-id**: /// - Thrown if the credential is a [PhoneAuthProvider.credential] and the /// verification ID of the credential is not valid. - Future reauthenticateWithPopup( - AuthProvider provider, - ) async { + Future reauthenticateWithPopup(AuthProvider provider) async { return UserCredential._( _auth, await _delegate.reauthenticateWithPopup(provider), @@ -366,9 +362,7 @@ class User { /// - **invalid-verification-id**: /// - Thrown if the credential is a [PhoneAuthProvider.credential] and the /// verification ID of the credential is not valid. - Future reauthenticateWithRedirect( - AuthProvider provider, - ) async { + Future reauthenticateWithRedirect(AuthProvider provider) async { await _delegate.reauthenticateWithRedirect(provider); } @@ -409,10 +403,7 @@ class User { /// Sign in Method tab and configure the provider. Future linkWithPopup(AuthProvider provider) async { try { - return UserCredential._( - _auth, - await _delegate.linkWithPopup(provider), - ); + return UserCredential._(_auth, await _delegate.linkWithPopup(provider)); } on FirebaseAuthMultiFactorExceptionPlatform catch (e) { throw FirebaseAuthMultiFactorException._(_auth, e); } catch (e) { @@ -501,8 +492,10 @@ class User { bool mustClear = verifier == null; verifier ??= RecaptchaVerifier(auth: _delegate.auth); try { - final result = - await _delegate.linkWithPhoneNumber(phoneNumber, verifier.delegate); + final result = await _delegate.linkWithPhoneNumber( + phoneNumber, + verifier.delegate, + ); if (mustClear) { verifier.clear(); } @@ -625,8 +618,9 @@ class User { /// Update the user name. Future updateDisplayName(String? displayName) { - return _delegate - .updateProfile({'displayName': displayName}); + return _delegate.updateProfile({ + 'displayName': displayName, + }); } /// Update the user's profile picture. diff --git a/packages/firebase_auth/firebase_auth/pubspec.yaml b/packages/firebase_auth/firebase_auth/pubspec.yaml index 8332fdd2b039..07850e8bfbf5 100755 --- a/packages/firebase_auth/firebase_auth/pubspec.yaml +++ b/packages/firebase_auth/firebase_auth/pubspec.yaml @@ -17,8 +17,8 @@ false_secrets: - example/** environment: - sdk: '^3.6.0' - flutter: '>=3.16.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_auth_platform_interface: ^9.0.7 diff --git a/packages/firebase_auth/firebase_auth/test/firebase_auth_test.dart b/packages/firebase_auth/firebase_auth/test/firebase_auth_test.dart index 865fc1b112d7..4ca86241e7fd 100644 --- a/packages/firebase_auth/firebase_auth/test/firebase_auth_test.dart +++ b/packages/firebase_auth/firebase_auth/test/firebase_auth_test.dart @@ -58,15 +58,18 @@ void main() { 'schemaVersion': 1, 'enforcement': 'OFF', }; - final PasswordPolicy kMockPasswordPolicyObject = - PasswordPolicy(kMockPasswordPolicy); + final PasswordPolicy kMockPasswordPolicyObject = PasswordPolicy( + kMockPasswordPolicy, + ); const int kMockPort = 31337; final TestAuthProvider testAuthProvider = TestAuthProvider(); - final int kMockCreationTimestamp = - DateTime.now().subtract(const Duration(days: 2)).millisecondsSinceEpoch; - final int kMockLastSignInTimestamp = - DateTime.now().subtract(const Duration(days: 1)).millisecondsSinceEpoch; + final int kMockCreationTimestamp = DateTime.now() + .subtract(const Duration(days: 2)) + .millisecondsSinceEpoch; + final int kMockLastSignInTimestamp = DateTime.now() + .subtract(const Duration(days: 1)) + .millisecondsSinceEpoch; final kMockUser = InternalUserDetails( userInfo: InternalUserInfo( @@ -84,7 +87,7 @@ void main() { 'displayName': 'Flutter Test User', 'photoUrl': 'http://www.example.com/', 'email': 'test@example.com', - } + }, ], ); @@ -120,7 +123,10 @@ void main() { user = kMockUser; mockUserPlatform = MockUserPlatform( - mockAuthPlatform, TestMultiFactorPlatform(mockAuthPlatform), user); + mockAuthPlatform, + TestMultiFactorPlatform(mockAuthPlatform), + user, + ); mockConfirmationResultPlatform = MockConfirmationResultPlatform(); mockAdditionalUserInfo = AdditionalUserInfo( isNewUser: false, @@ -128,10 +134,9 @@ void main() { providerId: 'testProvider', profile: {'foo': 'bar'}, ); - mockCredential = EmailAuthProvider.credential( - email: 'test', - password: 'test', - ) as EmailAuthCredential; + mockCredential = + EmailAuthProvider.credential(email: 'test', password: 'test') + as EmailAuthCredential; mockUserCredPlatform = MockUserCredentialPlatform( FirebaseAuthPlatform.instance, mockAdditionalUserInfo, @@ -140,68 +145,89 @@ void main() { ); mockVerifier = MockRecaptchaVerifier(); - when(mockAuthPlatform.signInAnonymously()) - .thenAnswer((_) async => mockUserCredPlatform); + when( + mockAuthPlatform.signInAnonymously(), + ).thenAnswer((_) async => mockUserCredPlatform); when(mockAuthPlatform.signInWithCredential(any)).thenAnswer( - (_) => Future.value(mockUserCredPlatform)); + (_) => Future.value(mockUserCredPlatform), + ); when(mockAuthPlatform.currentUser).thenReturn(mockUserPlatform); - when(mockAuthPlatform.instanceFor( - app: anyNamed('app'), - pluginConstants: anyNamed('pluginConstants'), - )).thenAnswer((_) => mockUserPlatform); + when( + mockAuthPlatform.instanceFor( + app: anyNamed('app'), + pluginConstants: anyNamed('pluginConstants'), + ), + ).thenAnswer((_) => mockUserPlatform); - when(mockAuthPlatform.delegateFor( - app: anyNamed('app'), - )).thenAnswer((_) => mockAuthPlatform); + when( + mockAuthPlatform.delegateFor(app: anyNamed('app')), + ).thenAnswer((_) => mockAuthPlatform); - when(mockAuthPlatform.setInitialValues( - currentUser: anyNamed('currentUser'), - languageCode: anyNamed('languageCode'), - )).thenAnswer((_) => mockAuthPlatform); + when( + mockAuthPlatform.setInitialValues( + currentUser: anyNamed('currentUser'), + languageCode: anyNamed('languageCode'), + ), + ).thenAnswer((_) => mockAuthPlatform); - when(mockAuthPlatform.createUserWithEmailAndPassword(any, any)) - .thenAnswer((_) async => mockUserCredPlatform); + when( + mockAuthPlatform.createUserWithEmailAndPassword(any, any), + ).thenAnswer((_) async => mockUserCredPlatform); - when(mockAuthPlatform.getRedirectResult()) - .thenAnswer((_) async => mockUserCredPlatform); + when( + mockAuthPlatform.getRedirectResult(), + ).thenAnswer((_) async => mockUserCredPlatform); - when(mockAuthPlatform.signInWithCustomToken(any)) - .thenAnswer((_) async => mockUserCredPlatform); + when( + mockAuthPlatform.signInWithCustomToken(any), + ).thenAnswer((_) async => mockUserCredPlatform); - when(mockAuthPlatform.signInWithEmailAndPassword(any, any)) - .thenAnswer((_) async => mockUserCredPlatform); + when( + mockAuthPlatform.signInWithEmailAndPassword(any, any), + ).thenAnswer((_) async => mockUserCredPlatform); - when(mockAuthPlatform.signInWithEmailLink(any, any)) - .thenAnswer((_) async => mockUserCredPlatform); + when( + mockAuthPlatform.signInWithEmailLink(any, any), + ).thenAnswer((_) async => mockUserCredPlatform); - when(mockAuthPlatform.signInWithPhoneNumber(any, any)) - .thenAnswer((_) async => mockConfirmationResultPlatform); + when( + mockAuthPlatform.signInWithPhoneNumber(any, any), + ).thenAnswer((_) async => mockConfirmationResultPlatform); when(mockVerifier.delegate).thenReturn(mockVerifier.mockDelegate); - when(mockAuthPlatform.signInWithPopup(any)) - .thenAnswer((_) async => mockUserCredPlatform); + when( + mockAuthPlatform.signInWithPopup(any), + ).thenAnswer((_) async => mockUserCredPlatform); - when(mockAuthPlatform.signInWithRedirect(any)) - .thenAnswer((_) async => mockUserCredPlatform); + when( + mockAuthPlatform.signInWithRedirect(any), + ).thenAnswer((_) async => mockUserCredPlatform); - when(mockAuthPlatform.authStateChanges()).thenAnswer((_) => - Stream.fromIterable([mockUserPlatform])); + when(mockAuthPlatform.authStateChanges()).thenAnswer( + (_) => + Stream.fromIterable([mockUserPlatform]), + ); - when(mockAuthPlatform.idTokenChanges()).thenAnswer((_) => - Stream.fromIterable([mockUserPlatform])); + when(mockAuthPlatform.idTokenChanges()).thenAnswer( + (_) => + Stream.fromIterable([mockUserPlatform]), + ); - when(mockAuthPlatform.userChanges()).thenAnswer((_) => - Stream.fromIterable([mockUserPlatform])); + when(mockAuthPlatform.userChanges()).thenAnswer( + (_) => + Stream.fromIterable([mockUserPlatform]), + ); TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(MethodChannelFirebaseAuth.channel, - (call) async { - return {'user': user}; - }); + .setMockMethodCallHandler(MethodChannelFirebaseAuth.channel, ( + call, + ) async { + return {'user': user}; + }); }); // incremented after tests completed, in case a test may want to use this @@ -216,8 +242,9 @@ void main() { group('emulator', () { test('useAuthEmulator() should call delegate method', () async { // Necessary as we otherwise get a "null is not a Future" error - when(mockAuthPlatform.useAuthEmulator(kMockHost, kMockPort)) - .thenAnswer((i) async {}); + when( + mockAuthPlatform.useAuthEmulator(kMockHost, kMockPort), + ).thenAnswer((i) async {}); await auth.useAuthEmulator(kMockHost, kMockPort); verify(mockAuthPlatform.useAuthEmulator(kMockHost, kMockPort)); }); @@ -231,51 +258,56 @@ void main() { }); }); - test('creates a fresh instance after app delete and reinitialize', - () async { - final appName = 'delete-reinit-$testCount'; - const options = FirebaseOptions( - apiKey: 'apiKey', - appId: 'appId', - messagingSenderId: 'messagingSenderId', - projectId: 'projectId', - ); - final app = await Firebase.initializeApp( - name: appName, - options: options, - ); - final auth1 = FirebaseAuth.instanceFor(app: app); + test( + 'creates a fresh instance after app delete and reinitialize', + () async { + final appName = 'delete-reinit-$testCount'; + const options = FirebaseOptions( + apiKey: 'apiKey', + appId: 'appId', + messagingSenderId: 'messagingSenderId', + projectId: 'projectId', + ); + final app = await Firebase.initializeApp( + name: appName, + options: options, + ); + final auth1 = FirebaseAuth.instanceFor(app: app); - expect(app.getService(), same(auth1)); + expect(app.getService(), same(auth1)); - await app.delete(); + await app.delete(); - final app2 = await Firebase.initializeApp( - name: appName, - options: options, - ); - addTearDown(app2.delete); + final app2 = await Firebase.initializeApp( + name: appName, + options: options, + ); + addTearDown(app2.delete); - final auth2 = FirebaseAuth.instanceFor(app: app2); + final auth2 = FirebaseAuth.instanceFor(app: app2); - expect(auth2, isNot(same(auth1))); - expect(auth2.app, app2); - expect(app2.getService(), same(auth2)); - }); + expect(auth2, isNot(same(auth1))); + expect(auth2.app, app2); + expect(app2.getService(), same(auth2)); + }, + ); group('tenantId', () { test('set tenantId should call delegate method', () async { // Each test uses a unique FirebaseApp instance to avoid sharing state final app = await Firebase.initializeApp( - name: 'tenantIdTest', - options: const FirebaseOptions( - apiKey: 'apiKey', - appId: 'appId', - messagingSenderId: 'messagingSenderId', - projectId: 'projectId')); - - FirebaseAuthPlatform.instance = - FakeFirebaseAuthPlatform(tenantId: 'foo'); + name: 'tenantIdTest', + options: const FirebaseOptions( + apiKey: 'apiKey', + appId: 'appId', + messagingSenderId: 'messagingSenderId', + projectId: 'projectId', + ), + ); + + FirebaseAuthPlatform.instance = FakeFirebaseAuthPlatform( + tenantId: 'foo', + ); auth = FirebaseAuth.instanceFor(app: app); expect(auth.tenantId, 'foo'); @@ -291,15 +323,18 @@ void main() { test('set customAuthDomain should call delegate method', () async { // Each test uses a unique FirebaseApp instance to avoid sharing state final app = await Firebase.initializeApp( - name: 'customAuthDomainTest', - options: const FirebaseOptions( - apiKey: 'apiKey', - appId: 'appId', - messagingSenderId: 'messagingSenderId', - projectId: 'projectId')); - - FirebaseAuthPlatform.instance = - FakeFirebaseAuthPlatform(customAuthDomain: 'foo'); + name: 'customAuthDomainTest', + options: const FirebaseOptions( + apiKey: 'apiKey', + appId: 'appId', + messagingSenderId: 'messagingSenderId', + projectId: 'projectId', + ), + ); + + FirebaseAuthPlatform.instance = FakeFirebaseAuthPlatform( + customAuthDomain: 'foo', + ); auth = FirebaseAuth.instanceFor(app: app); expect(auth.customAuthDomain, 'foo'); @@ -351,41 +386,47 @@ void main() { group('confirmPasswordReset()', () { test('should call delegate method', () async { // Necessary as we otherwise get a "null is not a Future" error - when(mockAuthPlatform.confirmPasswordReset(any, any)) - .thenAnswer((i) async {}); + when( + mockAuthPlatform.confirmPasswordReset(any, any), + ).thenAnswer((i) async {}); await auth.confirmPasswordReset( code: kMockActionCode, newPassword: kMockPassword, ); - verify(mockAuthPlatform.confirmPasswordReset( - kMockActionCode, kMockPassword)); + verify( + mockAuthPlatform.confirmPasswordReset(kMockActionCode, kMockPassword), + ); }); }); group('createUserWithEmailAndPassword()', () { test('should call delegate method', () async { // Necessary as we otherwise get a "null is not a Future" error - when(mockAuthPlatform.createUserWithEmailAndPassword(any, any)) - .thenAnswer((i) async => EmptyUserCredentialPlatform()); + when( + mockAuthPlatform.createUserWithEmailAndPassword(any, any), + ).thenAnswer((i) async => EmptyUserCredentialPlatform()); await auth.createUserWithEmailAndPassword( email: kMockEmail, password: kMockPassword, ); - verify(mockAuthPlatform.createUserWithEmailAndPassword( - kMockEmail, - kMockPassword, - )); + verify( + mockAuthPlatform.createUserWithEmailAndPassword( + kMockEmail, + kMockPassword, + ), + ); }); }); group('getRedirectResult()', () { test('should call delegate method', () async { // Necessary as we otherwise get a "null is not a Future" error - when(mockAuthPlatform.getRedirectResult()) - .thenAnswer((i) async => EmptyUserCredentialPlatform()); + when( + mockAuthPlatform.getRedirectResult(), + ).thenAnswer((i) async => EmptyUserCredentialPlatform()); await auth.getRedirectResult(); verify(mockAuthPlatform.getRedirectResult()); @@ -395,8 +436,9 @@ void main() { group('isSignInWithEmailLink()', () { test('should call delegate method', () async { // Necessary as we otherwise get a "null is not a Future" error - when(mockAuthPlatform.isSignInWithEmailLink(any)) - .thenAnswer((i) => false); + when( + mockAuthPlatform.isSignInWithEmailLink(any), + ).thenAnswer((i) => false); auth.isSignInWithEmailLink(kMockURL); verify(mockAuthPlatform.isSignInWithEmailLink(kMockURL)); @@ -405,24 +447,27 @@ void main() { group('authStateChanges()', () { test('should stream changes', () async { - final StreamQueue changes = - StreamQueue(auth.authStateChanges()); + final StreamQueue changes = StreamQueue( + auth.authStateChanges(), + ); expect(await changes.next, isA()); }); }); group('idTokenChanges()', () { test('should stream changes', () async { - final StreamQueue changes = - StreamQueue(auth.idTokenChanges()); + final StreamQueue changes = StreamQueue( + auth.idTokenChanges(), + ); expect(await changes.next, isA()); }); }); group('userChanges()', () { test('should stream changes', () async { - final StreamQueue changes = - StreamQueue(auth.userChanges()); + final StreamQueue changes = StreamQueue( + auth.userChanges(), + ); expect(await changes.next, isA()); }); }); @@ -430,8 +475,9 @@ void main() { group('sendPasswordResetEmail()', () { test('should call delegate method', () async { // Necessary as we otherwise get a "null is not a Future" error - when(mockAuthPlatform.sendPasswordResetEmail(any)) - .thenAnswer((i) async {}); + when( + mockAuthPlatform.sendPasswordResetEmail(any), + ).thenAnswer((i) async {}); await auth.sendPasswordResetEmail(email: kMockEmail); verify(mockAuthPlatform.sendPasswordResetEmail(kMockEmail)); @@ -441,8 +487,9 @@ void main() { group('sendPasswordResetEmail()', () { test('should call delegate method', () async { // Necessary as we otherwise get a "null is not a Future" error - when(mockAuthPlatform.sendPasswordResetEmail(any)) - .thenAnswer((i) async {}); + when( + mockAuthPlatform.sendPasswordResetEmail(any), + ).thenAnswer((i) async {}); await auth.sendPasswordResetEmail(email: kMockEmail); verify(mockAuthPlatform.sendPasswordResetEmail(kMockEmail)); @@ -450,37 +497,43 @@ void main() { }); group('sendSignInLinkToEmail()', () { - test('should throw if actionCodeSettings.handleCodeInApp is not true', - () async { - // Necessary as we otherwise get a "null is not a Future" error - when(mockAuthPlatform.sendSignInLinkToEmail(any, any)) - .thenAnswer((i) async {}); - - final ActionCodeSettings kMockActionCodeSettingsNull = - ActionCodeSettings(url: kMockURL); - final ActionCodeSettings kMockActionCodeSettingsFalse = - ActionCodeSettings(url: kMockURL); - - // when handleCodeInApp is null - expect( - () => auth.sendSignInLinkToEmail( + test( + 'should throw if actionCodeSettings.handleCodeInApp is not true', + () async { + // Necessary as we otherwise get a "null is not a Future" error + when( + mockAuthPlatform.sendSignInLinkToEmail(any, any), + ).thenAnswer((i) async {}); + + final ActionCodeSettings kMockActionCodeSettingsNull = + ActionCodeSettings(url: kMockURL); + final ActionCodeSettings kMockActionCodeSettingsFalse = + ActionCodeSettings(url: kMockURL); + + // when handleCodeInApp is null + expect( + () => auth.sendSignInLinkToEmail( email: kMockEmail, - actionCodeSettings: kMockActionCodeSettingsNull), - throwsArgumentError, - ); - // when handleCodeInApp is false - expect( - () => auth.sendSignInLinkToEmail( + actionCodeSettings: kMockActionCodeSettingsNull, + ), + throwsArgumentError, + ); + // when handleCodeInApp is false + expect( + () => auth.sendSignInLinkToEmail( email: kMockEmail, - actionCodeSettings: kMockActionCodeSettingsFalse), - throwsArgumentError, - ); - }); + actionCodeSettings: kMockActionCodeSettingsFalse, + ), + throwsArgumentError, + ); + }, + ); test('should call delegate method', () async { // Necessary as we otherwise get a "null is not a Future" error - when(mockAuthPlatform.sendSignInLinkToEmail(any, any)) - .thenAnswer((i) async {}); + when( + mockAuthPlatform.sendSignInLinkToEmail(any, any), + ).thenAnswer((i) async {}); final ActionCodeSettings kMockActionCodeSettingsValid = ActionCodeSettings(url: kMockURL, handleCodeInApp: true); @@ -490,24 +543,28 @@ void main() { actionCodeSettings: kMockActionCodeSettingsValid, ); - verify(mockAuthPlatform.sendSignInLinkToEmail( - kMockEmail, - kMockActionCodeSettingsValid, - )); + verify( + mockAuthPlatform.sendSignInLinkToEmail( + kMockEmail, + kMockActionCodeSettingsValid, + ), + ); }); }); group('setSettings()', () { test('should call delegate method', () async { // Necessary as we otherwise get a "null is not a Future" error - when(mockAuthPlatform.setSettings( - appVerificationDisabledForTesting: any, - phoneNumber: any, - smsCode: any, - forceRecaptchaFlow: any, - userAccessGroup: any, - migrateCurrentUser: true, - )).thenAnswer((i) async {}); + when( + mockAuthPlatform.setSettings( + appVerificationDisabledForTesting: any, + phoneNumber: any, + smsCode: any, + forceRecaptchaFlow: any, + userAccessGroup: any, + migrateCurrentUser: true, + ), + ).thenAnswer((i) async {}); String phoneNumber = '123456'; String smsCode = '1234'; @@ -552,8 +609,9 @@ void main() { group('signInAnonymously()', () { test('should call delegate method', () async { // Necessary as we otherwise get a "null is not a Future" error - when(mockAuthPlatform.signInAnonymously()) - .thenAnswer((i) async => EmptyUserCredentialPlatform()); + when( + mockAuthPlatform.signInAnonymously(), + ).thenAnswer((i) async => EmptyUserCredentialPlatform()); await auth.signInAnonymously(); verify(mockAuthPlatform.signInAnonymously()); @@ -562,13 +620,13 @@ void main() { group('signInWithCredential()', () { test('GithubAuthProvider signInWithCredential', () async { - final AuthCredential credential = - GithubAuthProvider.credential(kMockGithubToken); + final AuthCredential credential = GithubAuthProvider.credential( + kMockGithubToken, + ); await auth.signInWithCredential(credential); - final captured = - verify(mockAuthPlatform.signInWithCredential(captureAny)) - .captured - .single; + final captured = verify( + mockAuthPlatform.signInWithCredential(captureAny), + ).captured.single; expect(captured, isA()); expect(captured.providerId, equals('github.com')); expect(captured.accessToken, equals(kMockGithubToken)); @@ -580,14 +638,15 @@ void main() { emailLink: '', ); await auth.signInWithCredential(credential); - final EmailAuthCredential captured = - verify(mockAuthPlatform.signInWithCredential(captureAny)) - .captured - .single; + final EmailAuthCredential captured = verify( + mockAuthPlatform.signInWithCredential(captureAny), + ).captured.single; expect(captured.providerId, equals('password')); expect(captured.email, equals('test@example.com')); - expect(captured.emailLink, - equals('')); + expect( + captured.emailLink, + equals(''), + ); }); test('TwitterAuthProvider signInWithCredential', () async { @@ -596,10 +655,9 @@ void main() { secret: kMockAccessToken, ); await auth.signInWithCredential(credential); - final captured = - verify(mockAuthPlatform.signInWithCredential(captureAny)) - .captured - .single; + final captured = verify( + mockAuthPlatform.signInWithCredential(captureAny), + ).captured.single; expect(captured, isA()); expect(captured.providerId, equals('twitter.com')); expect(captured.accessToken, equals(kMockIdToken)); @@ -612,10 +670,9 @@ void main() { accessToken: kMockAccessToken, ); await auth.signInWithCredential(credential); - final captured = - verify(mockAuthPlatform.signInWithCredential(captureAny)) - .captured - .single; + final captured = verify( + mockAuthPlatform.signInWithCredential(captureAny), + ).captured.single; expect(captured, isA()); expect(captured.providerId, equals('google.com')); expect(captured.idToken, equals(kMockIdToken)); @@ -629,53 +686,53 @@ void main() { accessToken: kMockAccessToken, ); await auth.signInWithCredential(credential); - final captured = - verify(mockAuthPlatform.signInWithCredential(captureAny)) - .captured - .single; + final captured = verify( + mockAuthPlatform.signInWithCredential(captureAny), + ).captured.single; expect(captured.providerId, equals('apple.com')); expect(captured.idToken, equals(kMockIdToken)); expect(captured.accessToken, equals(kMockAccessToken)); expect(captured.rawNonce, equals(null)); }); - test('OAuthProvider signInWithCredential for Apple with rawNonce', - () async { - OAuthProvider oAuthProvider = OAuthProvider('apple.com'); - final AuthCredential credential = oAuthProvider.credential( - idToken: kMockIdToken, - rawNonce: kMockRawNonce, - accessToken: kMockAccessToken, - ); - await auth.signInWithCredential(credential); - final captured = - verify(mockAuthPlatform.signInWithCredential(captureAny)) - .captured - .single; - expect(captured.providerId, equals('apple.com')); - expect(captured.idToken, equals(kMockIdToken)); - expect(captured.rawNonce, equals(kMockRawNonce)); - expect(captured.accessToken, equals(kMockAccessToken)); - }); + test( + 'OAuthProvider signInWithCredential for Apple with rawNonce', + () async { + OAuthProvider oAuthProvider = OAuthProvider('apple.com'); + final AuthCredential credential = oAuthProvider.credential( + idToken: kMockIdToken, + rawNonce: kMockRawNonce, + accessToken: kMockAccessToken, + ); + await auth.signInWithCredential(credential); + final captured = verify( + mockAuthPlatform.signInWithCredential(captureAny), + ).captured.single; + expect(captured.providerId, equals('apple.com')); + expect(captured.idToken, equals(kMockIdToken)); + expect(captured.rawNonce, equals(kMockRawNonce)); + expect(captured.accessToken, equals(kMockAccessToken)); + }, + ); test( - 'OAuthProvider signInWithCredential for Apple with rawNonce (empty accessToken)', - () async { - OAuthProvider oAuthProvider = OAuthProvider('apple.com'); - final AuthCredential credential = oAuthProvider.credential( - idToken: kMockIdToken, - rawNonce: kMockRawNonce, - ); - await auth.signInWithCredential(credential); - final captured = - verify(mockAuthPlatform.signInWithCredential(captureAny)) - .captured - .single; - expect(captured.providerId, equals('apple.com')); - expect(captured.idToken, equals(kMockIdToken)); - expect(captured.rawNonce, equals(kMockRawNonce)); - expect(captured.accessToken, equals(null)); - }); + 'OAuthProvider signInWithCredential for Apple with rawNonce (empty accessToken)', + () async { + OAuthProvider oAuthProvider = OAuthProvider('apple.com'); + final AuthCredential credential = oAuthProvider.credential( + idToken: kMockIdToken, + rawNonce: kMockRawNonce, + ); + await auth.signInWithCredential(credential); + final captured = verify( + mockAuthPlatform.signInWithCredential(captureAny), + ).captured.single; + expect(captured.providerId, equals('apple.com')); + expect(captured.idToken, equals(kMockIdToken)); + expect(captured.rawNonce, equals(kMockRawNonce)); + expect(captured.accessToken, equals(null)); + }, + ); test('PhoneAuthProvider signInWithCredential', () async { final PhoneAuthCredential credential = PhoneAuthProvider.credential( @@ -683,23 +740,22 @@ void main() { smsCode: kMockSmsCode, ); await auth.signInWithCredential(credential); - final PhoneAuthCredential captured = - verify(mockAuthPlatform.signInWithCredential(captureAny)) - .captured - .single; + final PhoneAuthCredential captured = verify( + mockAuthPlatform.signInWithCredential(captureAny), + ).captured.single; expect(captured.providerId, equals('phone')); expect(captured.verificationId, equals(kMockVerificationId)); expect(captured.smsCode, equals(kMockSmsCode)); }); test('FacebookAuthProvider signInWithCredential', () async { - final AuthCredential credential = - FacebookAuthProvider.credential(kMockAccessToken); + final AuthCredential credential = FacebookAuthProvider.credential( + kMockAccessToken, + ); await auth.signInWithCredential(credential); - final captured = - verify(mockAuthPlatform.signInWithCredential(captureAny)) - .captured - .single; + final captured = verify( + mockAuthPlatform.signInWithCredential(captureAny), + ).captured.single; expect(captured, isA()); expect(captured.providerId, equals('facebook.com')); expect(captured.accessToken, equals(kMockAccessToken)); @@ -716,9 +772,15 @@ void main() { group('signInWithEmailAndPassword()', () { test('should call delegate method', () async { await auth.signInWithEmailAndPassword( - email: kMockEmail, password: kMockPassword); - verify(mockAuthPlatform.signInWithEmailAndPassword( - kMockEmail, kMockPassword)); + email: kMockEmail, + password: kMockPassword, + ); + verify( + mockAuthPlatform.signInWithEmailAndPassword( + kMockEmail, + kMockPassword, + ), + ); }); }); @@ -763,8 +825,9 @@ void main() { group('verifyPasswordResetCode()', () { test('should call delegate method', () async { // Necessary as we otherwise get a "null is not a Future" error - when(mockAuthPlatform.verifyPasswordResetCode(any)) - .thenAnswer((i) async => ''); + when( + mockAuthPlatform.verifyPasswordResetCode(any), + ).thenAnswer((i) async => ''); await auth.verifyPasswordResetCode(kMockOobCode); verify(mockAuthPlatform.verifyPasswordResetCode(kMockOobCode)); @@ -774,17 +837,20 @@ void main() { group('verifyPhoneNumber()', () { test('should call delegate method', () async { // Necessary as we otherwise get a "null is not a Future" error - when(mockAuthPlatform.verifyPhoneNumber( - autoRetrievedSmsCodeForTesting: - anyNamed('autoRetrievedSmsCodeForTesting'), - codeAutoRetrievalTimeout: anyNamed('codeAutoRetrievalTimeout'), - codeSent: anyNamed('codeSent'), - forceResendingToken: anyNamed('forceResendingToken'), - phoneNumber: anyNamed('phoneNumber'), - timeout: anyNamed('timeout'), - verificationCompleted: anyNamed('verificationCompleted'), - verificationFailed: anyNamed('verificationFailed'), - )).thenAnswer((i) async {}); + when( + mockAuthPlatform.verifyPhoneNumber( + autoRetrievedSmsCodeForTesting: anyNamed( + 'autoRetrievedSmsCodeForTesting', + ), + codeAutoRetrievalTimeout: anyNamed('codeAutoRetrievalTimeout'), + codeSent: anyNamed('codeSent'), + forceResendingToken: anyNamed('forceResendingToken'), + phoneNumber: anyNamed('phoneNumber'), + timeout: anyNamed('timeout'), + verificationCompleted: anyNamed('verificationCompleted'), + verificationFailed: anyNamed('verificationFailed'), + ), + ).thenAnswer((i) async {}); final PhoneVerificationCompleted verificationCompleted = (PhoneAuthCredential phoneAuthCredential) {}; @@ -818,8 +884,9 @@ void main() { group('revokeAccessToken()', () { test('should call delegate method', () async { // Necessary as we otherwise get a "null is not a Future" error - when(mockAuthPlatform.revokeAccessToken(kMockAuthToken)) - .thenAnswer((i) async {}); + when( + mockAuthPlatform.revokeAccessToken(kMockAuthToken), + ).thenAnswer((i) async {}); await auth.revokeAccessToken(kMockAuthToken); verify(mockAuthPlatform.revokeAccessToken(kMockAuthToken)); @@ -827,65 +894,75 @@ void main() { }); group('passwordPolicy', () { - test('passwordPolicy should be initialized with correct parameters', - () async { - PasswordPolicyImpl passwordPolicy = - PasswordPolicyImpl(kMockPasswordPolicyObject); - expect(passwordPolicy.policy, equals(kMockPasswordPolicyObject)); - }); + test( + 'passwordPolicy should be initialized with correct parameters', + () async { + PasswordPolicyImpl passwordPolicy = PasswordPolicyImpl( + kMockPasswordPolicyObject, + ); + expect(passwordPolicy.policy, equals(kMockPasswordPolicyObject)); + }, + ); - PasswordPolicyImpl passwordPolicy = - PasswordPolicyImpl(kMockPasswordPolicyObject); + PasswordPolicyImpl passwordPolicy = PasswordPolicyImpl( + kMockPasswordPolicyObject, + ); test('should return true for valid password', () async { - final PasswordValidationStatus status = - passwordPolicy.isPasswordValid(kMockValidPassword); + final PasswordValidationStatus status = passwordPolicy.isPasswordValid( + kMockValidPassword, + ); expect(status.isValid, isTrue); }); - test('should return false for invalid password that is too short', - () async { - final PasswordValidationStatus status = - passwordPolicy.isPasswordValid(kMockInvalidPassword); - expect(status.isValid, isFalse); - }); + test( + 'should return false for invalid password that is too short', + () async { + final PasswordValidationStatus status = passwordPolicy + .isPasswordValid(kMockInvalidPassword); + expect(status.isValid, isFalse); + }, + ); test( - 'should return false for invalid password with no capital characters', - () async { - final PasswordValidationStatus status = - passwordPolicy.isPasswordValid(kMockInvalidPassword2); - expect(status.isValid, isFalse); - }); + 'should return false for invalid password with no capital characters', + () async { + final PasswordValidationStatus status = passwordPolicy + .isPasswordValid(kMockInvalidPassword2); + expect(status.isValid, isFalse); + }, + ); test( - 'should return false for invalid password with no lowercase characters', - () async { - final PasswordValidationStatus status = - passwordPolicy.isPasswordValid(kMockInvalidPassword3); - expect(status.isValid, isFalse); - }); + 'should return false for invalid password with no lowercase characters', + () async { + final PasswordValidationStatus status = passwordPolicy + .isPasswordValid(kMockInvalidPassword3); + expect(status.isValid, isFalse); + }, + ); - test('should return false for invalid password with no numbers', - () async { - final PasswordValidationStatus status = - passwordPolicy.isPasswordValid(kMockInvalidPassword4); - expect(status.isValid, isFalse); - }); + test( + 'should return false for invalid password with no numbers', + () async { + final PasswordValidationStatus status = passwordPolicy + .isPasswordValid(kMockInvalidPassword4); + expect(status.isValid, isFalse); + }, + ); - test('should return false for invalid password with no symbols', - () async { - final PasswordValidationStatus status = - passwordPolicy.isPasswordValid(kMockInvalidPassword5); - expect(status.isValid, isFalse); - }); + test( + 'should return false for invalid password with no symbols', + () async { + final PasswordValidationStatus status = passwordPolicy + .isPasswordValid(kMockInvalidPassword5); + expect(status.isValid, isFalse); + }, + ); }); test('toString()', () async { - expect( - auth.toString(), - equals('FirebaseAuth(app: $testCount)'), - ); + expect(auth.toString(), equals('FirebaseAuth(app: $testCount)')); }); }); } @@ -921,8 +998,10 @@ class MockFirebaseAuth extends Mock } @override - FirebaseAuthPlatform delegateFor( - {FirebaseApp? app, Persistence? persistence}) { + FirebaseAuthPlatform delegateFor({ + FirebaseApp? app, + Persistence? persistence, + }) { return super.noSuchMethod( Invocation.method(#delegateFor, [], {#app: app}), returnValue: TestFirebaseAuthPlatform(), @@ -948,10 +1027,10 @@ class MockFirebaseAuth extends Mock RecaptchaVerifierFactoryPlatform? applicationVerifier, ) { return super.noSuchMethod( - Invocation.method( - #signInWithPhoneNumber, - [phoneNumber, applicationVerifier], - ), + Invocation.method(#signInWithPhoneNumber, [ + phoneNumber, + applicationVerifier, + ]), returnValue: neverEndingFuture(), returnValueForMissingStub: neverEndingFuture(), @@ -1223,8 +1302,10 @@ class FakeFirebaseAuthPlatform extends Fake String? customAuthDomain; @override - FirebaseAuthPlatform delegateFor( - {required FirebaseApp app, Persistence? persistence}) { + FirebaseAuthPlatform delegateFor({ + required FirebaseApp app, + Persistence? persistence, + }) { return this; } @@ -1240,8 +1321,11 @@ class FakeFirebaseAuthPlatform extends Fake class MockUserPlatform extends Mock with MockPlatformInterfaceMixin implements TestUserPlatform { - MockUserPlatform(FirebaseAuthPlatform auth, MultiFactorPlatform multiFactor, - InternalUserDetails _user) { + MockUserPlatform( + FirebaseAuthPlatform auth, + MultiFactorPlatform multiFactor, + InternalUserDetails _user, + ) { TestUserPlatform(auth, multiFactor, _user); } } @@ -1285,8 +1369,10 @@ class TestFirebaseAuthPlatform extends FirebaseAuthPlatform { }) {} @override - FirebaseAuthPlatform delegateFor( - {FirebaseApp? app, Persistence? persistence}) { + FirebaseAuthPlatform delegateFor({ + FirebaseApp? app, + Persistence? persistence, + }) { return this; } @@ -1360,9 +1446,11 @@ class TestAuthProvider extends AuthProvider { } class TestUserPlatform extends UserPlatform { - TestUserPlatform(FirebaseAuthPlatform auth, MultiFactorPlatform multiFactor, - InternalUserDetails data) - : super(auth, multiFactor, data); + TestUserPlatform( + FirebaseAuthPlatform auth, + MultiFactorPlatform multiFactor, + InternalUserDetails data, + ) : super(auth, multiFactor, data); } class TestMultiFactorPlatform extends MultiFactorPlatform { @@ -1376,11 +1464,11 @@ class TestUserCredentialPlatform extends UserCredentialPlatform { AuthCredential credential, UserPlatform userPlatform, ) : super( - auth: auth, - additionalUserInfo: additionalUserInfo, - credential: credential, - user: userPlatform, - ); + auth: auth, + additionalUserInfo: additionalUserInfo, + credential: credential, + user: userPlatform, + ); } class EmptyUserCredentialPlatform extends UserCredentialPlatform { diff --git a/packages/firebase_auth/firebase_auth/test/user_test.dart b/packages/firebase_auth/firebase_auth/test/user_test.dart index 967be866fee2..2b85f13a7f0e 100644 --- a/packages/firebase_auth/firebase_auth/test/user_test.dart +++ b/packages/firebase_auth/firebase_auth/test/user_test.dart @@ -37,15 +37,15 @@ void main() { authTimestamp: 1234567, issuedAtTimestamp: 12345678, signInProvider: 'password', - claims: { - 'claim1': 'value1', - }, + claims: {'claim1': 'value1'}, ); - final int kMockCreationTimestamp = - DateTime.now().subtract(const Duration(days: 2)).millisecondsSinceEpoch; - final int kMockLastSignInTimestamp = - DateTime.now().subtract(const Duration(days: 1)).millisecondsSinceEpoch; + final int kMockCreationTimestamp = DateTime.now() + .subtract(const Duration(days: 2)) + .millisecondsSinceEpoch; + final int kMockLastSignInTimestamp = DateTime.now() + .subtract(const Duration(days: 1)) + .millisecondsSinceEpoch; final kMockUser = InternalUserDetails( userInfo: InternalUserInfo( @@ -65,7 +65,7 @@ void main() { 'email': 'test@example.com', 'isAnonymous': true, 'isEmailVerified': false, - } + }, ], ); late MockUserPlatform mockUserPlatform; @@ -118,27 +118,31 @@ void main() { ); when(mockAuthPlatform.signInAnonymously()).thenAnswer( - (_) => Future.value(mockUserCredPlatform)); + (_) => Future.value(mockUserCredPlatform), + ); when(mockAuthPlatform.currentUser).thenReturn(mockUserPlatform); - when(mockAuthPlatform.delegateFor( - app: anyNamed('app'), - )).thenAnswer((_) => mockAuthPlatform); + when( + mockAuthPlatform.delegateFor(app: anyNamed('app')), + ).thenAnswer((_) => mockAuthPlatform); - when(mockAuthPlatform.setInitialValues( - currentUser: anyNamed('currentUser'), - languageCode: anyNamed('languageCode'), - )).thenAnswer((_) => mockAuthPlatform); + when( + mockAuthPlatform.setInitialValues( + currentUser: anyNamed('currentUser'), + languageCode: anyNamed('languageCode'), + ), + ).thenAnswer((_) => mockAuthPlatform); TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(MethodChannelFirebaseAuth.channel, - (call) async { - switch (call.method) { - default: - return {'user': user}; - } - }); + .setMockMethodCallHandler(MethodChannelFirebaseAuth.channel, ( + call, + ) async { + switch (call.method) { + default: + return {'user': user}; + } + }); }); tearDown(() => testCount++); @@ -168,8 +172,9 @@ void main() { }); test('getIdTokenResult()', () async { - when(mockUserPlatform.getIdTokenResult(any)) - .thenAnswer((_) async => IdTokenResult(kMockIdTokenResult)); + when( + mockUserPlatform.getIdTokenResult(any), + ).thenAnswer((_) async => IdTokenResult(kMockIdTokenResult)); final idTokenResult = await auth.currentUser!.getIdTokenResult(true); @@ -179,8 +184,9 @@ void main() { group('linkWithCredential()', () { setUp(() { - when(mockUserPlatform.linkWithCredential(any)) - .thenAnswer((_) async => mockUserCredPlatform); + when( + mockUserPlatform.linkWithCredential(any), + ).thenAnswer((_) async => mockUserCredPlatform); }); test('should call linkWithCredential()', () async { @@ -197,8 +203,9 @@ void main() { group('reauthenticateWithCredential()', () { setUp(() { - when(mockUserPlatform.reauthenticateWithCredential(any)) - .thenAnswer((_) => Future.value(mockUserCredPlatform)); + when( + mockUserPlatform.reauthenticateWithCredential(any), + ).thenAnswer((_) => Future.value(mockUserCredPlatform)); }); test('should call reauthenticateWithCredential()', () async { String newEmail = 'new@email.com'; @@ -223,11 +230,13 @@ void main() { test('sendEmailVerification()', () async { // Necessary as we otherwise get a "null is not a Future" error - when(mockUserPlatform.sendEmailVerification(any)) - .thenAnswer((i) async {}); + when( + mockUserPlatform.sendEmailVerification(any), + ).thenAnswer((i) async {}); - final ActionCodeSettings actionCodeSettings = - ActionCodeSettings(url: 'test'); + final ActionCodeSettings actionCodeSettings = ActionCodeSettings( + url: 'test', + ); await auth.currentUser!.sendEmailVerification(actionCodeSettings); @@ -236,8 +245,9 @@ void main() { group('unlink()', () { setUp(() { - when(mockUserPlatform.unlink(any)) - .thenAnswer((_) => Future.value(mockUserPlatform)); + when( + mockUserPlatform.unlink(any), + ).thenAnswer((_) => Future.value(mockUserPlatform)); }); test('should call unlink()', () async { const String providerId = 'providerId'; @@ -284,12 +294,12 @@ void main() { const String photoURL = 'testUrl'; Map data = { 'displayName': displayName, - 'photoURL': photoURL + 'photoURL': photoURL, }; await auth.currentUser! - // ignore: deprecated_member_use_from_same_package - .updateProfile(displayName: displayName, photoURL: photoURL); + // ignore: deprecated_member_use_from_same_package + .updateProfile(displayName: displayName, photoURL: photoURL); verify(mockUserPlatform.updateProfile(data)); }); @@ -297,25 +307,38 @@ void main() { group('verifyBeforeUpdateEmail()', () { test('should call verifyBeforeUpdateEmail()', () async { // Necessary as we otherwise get a "null is not a Future" error - when(mockUserPlatform.verifyBeforeUpdateEmail(any, any)) - .thenAnswer((i) async {}); + when( + mockUserPlatform.verifyBeforeUpdateEmail(any, any), + ).thenAnswer((i) async {}); const newEmail = 'new@email.com'; ActionCodeSettings actionCodeSettings = ActionCodeSettings(url: 'test'); - await auth.currentUser! - .verifyBeforeUpdateEmail(newEmail, actionCodeSettings); + await auth.currentUser!.verifyBeforeUpdateEmail( + newEmail, + actionCodeSettings, + ); - verify(mockUserPlatform.verifyBeforeUpdateEmail( - newEmail, actionCodeSettings)); + verify( + mockUserPlatform.verifyBeforeUpdateEmail( + newEmail, + actionCodeSettings, + ), + ); }); }); test('toString()', () async { - when(mockAuthPlatform.currentUser).thenReturn(TestUserPlatform( - mockAuthPlatform, TestMultiFactorPlatform(mockAuthPlatform), user)); + when(mockAuthPlatform.currentUser).thenReturn( + TestUserPlatform( + mockAuthPlatform, + TestMultiFactorPlatform(mockAuthPlatform), + user, + ), + ); - const userInfo = 'UserInfo(' + const userInfo = + 'UserInfo(' 'displayName: Flutter Test User, ' 'email: test@example.com, ' 'phoneNumber: null, ' @@ -323,7 +346,8 @@ void main() { 'providerId: firebase, ' 'uid: 12345)'; - final userMetadata = 'UserMetadata(' + final userMetadata = + 'UserMetadata(' 'creationTime: ${DateTime.fromMillisecondsSinceEpoch(kMockCreationTimestamp, isUtc: true)}, ' 'lastSignInTime: ${DateTime.fromMillisecondsSinceEpoch(kMockLastSignInTimestamp, isUtc: true)})'; @@ -365,8 +389,10 @@ class MockFirebaseAuth extends Mock } @override - FirebaseAuthPlatform delegateFor( - {FirebaseApp? app, Persistence? persistence}) { + FirebaseAuthPlatform delegateFor({ + FirebaseApp? app, + Persistence? persistence, + }) { return super.noSuchMethod( Invocation.method(#delegateFor, const [], {#app: app}), returnValue: TestFirebaseAuthPlatform(), @@ -538,9 +564,10 @@ class TestFirebaseAuthPlatform extends FirebaseAuthPlatform { TestFirebaseAuthPlatform() : super(); @override - FirebaseAuthPlatform delegateFor( - {FirebaseApp? app, Persistence? persistence}) => - this; + FirebaseAuthPlatform delegateFor({ + FirebaseApp? app, + Persistence? persistence, + }) => this; @override FirebaseAuthPlatform setInitialValues({ @@ -552,9 +579,11 @@ class TestFirebaseAuthPlatform extends FirebaseAuthPlatform { } class TestUserPlatform extends UserPlatform { - TestUserPlatform(FirebaseAuthPlatform auth, MultiFactorPlatform multiFactor, - InternalUserDetails data) - : super(auth, multiFactor, data); + TestUserPlatform( + FirebaseAuthPlatform auth, + MultiFactorPlatform multiFactor, + InternalUserDetails data, + ) : super(auth, multiFactor, data); } class TestUserCredentialPlatform extends UserCredentialPlatform { @@ -564,8 +593,9 @@ class TestUserCredentialPlatform extends UserCredentialPlatform { AuthCredential credential, UserPlatform userPlatform, ) : super( - auth: auth, - additionalUserInfo: additionalUserInfo, - credential: credential, - user: userPlatform); + auth: auth, + additionalUserInfo: additionalUserInfo, + credential: credential, + user: userPlatform, + ); } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/action_code_info.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/action_code_info.dart index 64aeb5aa48ad..2f79ed7a652f 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/action_code_info.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/action_code_info.dart @@ -10,10 +10,8 @@ import 'package:meta/meta.dart'; class ActionCodeInfo { // ignore: public_member_api_docs @protected - ActionCodeInfo({ - required this.operation, - required ActionCodeInfoData data, - }) : _data = data; + ActionCodeInfo({required this.operation, required ActionCodeInfoData data}) + : _data = data; ActionCodeInfoOperation operation; @@ -29,10 +27,7 @@ class ActionCodeInfo { class ActionCodeInfoData { // ignore: public_member_api_docs @protected - ActionCodeInfoData({ - required this.email, - required this.previousEmail, - }); + ActionCodeInfoData({required this.email, required this.previousEmail}); /// The email associated with the action code. final String? email; @@ -42,9 +37,6 @@ class ActionCodeInfoData { /// Converts the [ActionCodeInfoData] instance to a [Map]. Map toMap() { - return { - 'email': email, - 'previousEmail': previousEmail, - }; + return {'email': email, 'previousEmail': previousEmail}; } } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/action_code_settings.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/action_code_settings.dart index b4ab3e8e4378..96b9096a3f8b 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/action_code_settings.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/action_code_settings.dart @@ -55,16 +55,13 @@ class ActionCodeSettings { 'url': url, 'linkDomain': linkDomain, 'handleCodeInApp': handleCodeInApp, - if (iOSBundleId != null) - 'iOS': { - 'bundleId': iOSBundleId, - }, + if (iOSBundleId != null) 'iOS': {'bundleId': iOSBundleId}, if (androidPackageName != null) 'android': { 'packageName': androidPackageName, 'minimumVersion': androidMinimumVersion, 'installApp': androidInstallApp, - } + }, }; } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/firebase_auth_multi_factor_exception.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/firebase_auth_multi_factor_exception.dart index 1b5663452b76..f386c299d514 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/firebase_auth_multi_factor_exception.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/firebase_auth_multi_factor_exception.dart @@ -21,13 +21,13 @@ class FirebaseAuthMultiFactorExceptionPlatform extends FirebaseAuthException String? tenantId, required this.resolver, }) : super( - message: message, - code: code, - email: email, - credential: credential, - phoneNumber: phoneNumber, - tenantId: tenantId, - ); + message: message, + code: code, + email: email, + credential: credential, + phoneNumber: phoneNumber, + tenantId: tenantId, + ); final MultiFactorResolverPlatform resolver; } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_firebase_auth.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_firebase_auth.dart index c172b2dce8e8..9d92f06adb89 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_firebase_auth.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_firebase_auth.dart @@ -29,22 +29,21 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { /// Map of [MethodChannelFirebaseAuth] that can be get with Firebase App Name. static Map - methodChannelFirebaseAuthInstances = - {}; + methodChannelFirebaseAuthInstances = {}; static Map _multiFactorInstances = {}; static final Map>> - _authStateChangesListeners = + _authStateChangesListeners = >>{}; static final Map>> - _idTokenChangesListeners = + _idTokenChangesListeners = >>{}; static final Map>> - _userChangesListeners = + _userChangesListeners = >>{}; final List> _listenerRegistrations = >[]; @@ -78,7 +77,7 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { /// Creates a new instance with a given [FirebaseApp]. MethodChannelFirebaseAuth({required FirebaseApp app}) - : super(appInstance: app) { + : super(appInstance: app) { // Create a app instance broadcast stream for native listener events _authStateChangesListeners[app.name] = _createBroadcastStream<_ValueWrapper>(); @@ -103,10 +102,10 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { events .receiveGuardedBroadcastStream(onError: convertPlatformException) .listen((arguments) { - if (!_isDisposed) { - _handleIdTokenChangesListener(app.name, arguments); - } - }), + if (!_isDisposed) { + _handleIdTokenChangesListener(app.name, arguments); + } + }), ); // ignore: avoid_catches_without_on_clauses } catch (_) { @@ -127,10 +126,10 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { events .receiveGuardedBroadcastStream(onError: convertPlatformException) .listen((arguments) { - if (!_isDisposed) { - _handleAuthStateChangesListener(app.name, arguments); - } - }), + if (!_isDisposed) { + _handleAuthStateChangesListener(app.name, arguments); + } + }), ); // ignore: avoid_catches_without_on_clauses } catch (_) { @@ -156,7 +155,9 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { // Duplicate setting of [currentUser] in [_handleAuthStateChangesListener] & [_handleIdTokenChangesListener] // as iOS & Android do not guarantee correct ordering Future _handleAuthStateChangesListener( - String appName, Map arguments) async { + String appName, + Map arguments, + ) async { // ignore: close_sinks final streamController = _authStateChangesListeners[appName]; MethodChannelFirebaseAuth? instance = @@ -181,9 +182,10 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { final MethodChannelUser user = MethodChannelUser( instance, multiFactorInstance, - InternalUserDetails.decode( - [InternalUserInfo.decode(userList[0]!), userList[1]], - ), + InternalUserDetails.decode([ + InternalUserInfo.decode(userList[0]!), + userList[1], + ]), ); instance.currentUser = user; @@ -196,7 +198,9 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { /// This handler also manages the [currentUser] along with sending events /// to any [userChanges] stream subscribers. Future _handleIdTokenChangesListener( - String appName, Map arguments) async { + String appName, + Map arguments, + ) async { // ignore: close_sinks final idTokenStreamController = _idTokenChangesListeners[appName]; // ignore: close_sinks @@ -225,9 +229,10 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { final MethodChannelUser user = MethodChannelUser( instance, multiFactorInstance, - InternalUserDetails.decode( - [InternalUserInfo.decode(userList[0]!), userList[1]], - ), + InternalUserDetails.decode([ + InternalUserInfo.decode(userList[0]!), + userList[1], + ]), ); instance.currentUser = user; @@ -330,15 +335,19 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { @override Future createUserWithEmailAndPassword( - String email, String password) async { + String email, + String password, + ) async { try { final result = await _api.createUserWithEmailAndPassword( pigeonDefault, email, password, ); - MethodChannelUserCredential userCredential = - MethodChannelUserCredential(this, result); + MethodChannelUserCredential userCredential = MethodChannelUserCredential( + this, + result, + ); currentUser = userCredential.user; return userCredential; @@ -352,8 +361,10 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { try { final result = await _api.signInAnonymously(pigeonDefault); - MethodChannelUserCredential userCredential = - MethodChannelUserCredential(this, result); + MethodChannelUserCredential userCredential = MethodChannelUserCredential( + this, + result, + ); currentUser = userCredential.user; return userCredential; @@ -372,8 +383,10 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { credential.asMap(), ); - MethodChannelUserCredential userCredential = - MethodChannelUserCredential(this, result); + MethodChannelUserCredential userCredential = MethodChannelUserCredential( + this, + result, + ); currentUser = userCredential.user; return userCredential; @@ -385,13 +398,12 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { @override Future signInWithCustomToken(String token) async { try { - final result = await _api.signInWithCustomToken( - pigeonDefault, - token, - ); + final result = await _api.signInWithCustomToken(pigeonDefault, token); - MethodChannelUserCredential userCredential = - MethodChannelUserCredential(this, result); + MethodChannelUserCredential userCredential = MethodChannelUserCredential( + this, + result, + ); currentUser = userCredential.user; return userCredential; @@ -402,7 +414,9 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { @override Future signInWithEmailAndPassword( - String email, String password) async { + String email, + String password, + ) async { try { final result = await _api.signInWithEmailAndPassword( pigeonDefault, @@ -410,8 +424,10 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { password, ); - MethodChannelUserCredential userCredential = - MethodChannelUserCredential(this, result); + MethodChannelUserCredential userCredential = MethodChannelUserCredential( + this, + result, + ); currentUser = userCredential.user; return userCredential; @@ -422,7 +438,9 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { @override Future signInWithEmailLink( - String email, String emailLink) async { + String email, + String emailLink, + ) async { try { final result = await _api.signInWithEmailLink( pigeonDefault, @@ -430,8 +448,10 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { emailLink, ); - MethodChannelUserCredential userCredential = - MethodChannelUserCredential(this, result); + MethodChannelUserCredential userCredential = MethodChannelUserCredential( + this, + result, + ); currentUser = userCredential.user; return userCredential; @@ -461,8 +481,10 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { ), ); - MethodChannelUserCredential userCredential = - MethodChannelUserCredential(this, result); + MethodChannelUserCredential userCredential = MethodChannelUserCredential( + this, + result, + ); currentUser = userCredential.user; return userCredential; @@ -510,17 +532,17 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { @override Stream authStateChanges() async* { yield currentUser; - yield* _authStateChangesListeners[app.name]! - .stream - .map((event) => event.value); + yield* _authStateChangesListeners[app.name]!.stream.map( + (event) => event.value, + ); } @override Stream idTokenChanges() async* { yield currentUser; - yield* _idTokenChangesListeners[app.name]! - .stream - .map((event) => event.value); + yield* _idTokenChangesListeners[app.name]!.stream.map( + (event) => event.value, + ); } @override @@ -582,8 +604,10 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { @override Future setLanguageCode(String? languageCode) async { try { - final newLanguageCode = - await _api.setLanguageCode(pigeonDefault, languageCode); + final newLanguageCode = await _api.setLanguageCode( + pigeonDefault, + languageCode, + ); this.languageCode = newLanguageCode; } catch (e, stack) { @@ -615,16 +639,16 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { try { final InternalUserDetails? migratedUser = await _api.setSettings( - pigeonDefault, - InternalFirebaseAuthSettings( - appVerificationDisabledForTesting: - appVerificationDisabledForTesting, - userAccessGroup: userAccessGroup, - migrateCurrentUser: migrateCurrentUser, - phoneNumber: phoneNumber, - smsCode: smsCode, - forceRecaptchaFlow: forceRecaptchaFlow, - )); + pigeonDefault, + InternalFirebaseAuthSettings( + appVerificationDisabledForTesting: appVerificationDisabledForTesting, + userAccessGroup: userAccessGroup, + migrateCurrentUser: migrateCurrentUser, + phoneNumber: phoneNumber, + smsCode: smsCode, + forceRecaptchaFlow: forceRecaptchaFlow, + ), + ); // Native migration completes before this Future resolves, but auth-state // events are delivered asynchronously. Assign [currentUser] from the @@ -638,8 +662,11 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { multiFactorInstance = MethodChannelMultiFactor(this); _multiFactorInstances[app.name] = multiFactorInstance; } - currentUser = - MethodChannelUser(this, multiFactorInstance, migratedUser); + currentUser = MethodChannelUser( + this, + multiFactorInstance, + migratedUser, + ); } } catch (e, stack) { convertPlatformException(e, stack); @@ -696,38 +723,40 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { ), ); - EventChannel(eventChannelName) - .receiveGuardedBroadcastStream(onError: convertPlatformException) - .listen((arguments) { - final name = arguments['name']; - if (name == 'Auth#phoneVerificationCompleted') { - final int token = arguments['token']; - final String? smsCode = arguments['smsCode']; - - PhoneAuthCredential phoneAuthCredential = - PhoneAuthProvider.credentialFromToken(token, smsCode: smsCode); - verificationCompleted(phoneAuthCredential); - } else if (name == 'Auth#phoneVerificationFailed') { - final Map? error = arguments['error']; - final Map? details = error?['details']; - - FirebaseAuthException exception = FirebaseAuthException( - message: details?['message'] ?? error?['message'], - code: details?['code'] ?? error?['code'] ?? 'unknown', - ); - - verificationFailed(exception); - } else if (name == 'Auth#phoneCodeSent') { - final String verificationId = arguments['verificationId']; - final int? forceResendingToken = arguments['forceResendingToken']; - - codeSent(verificationId, forceResendingToken); - } else if (name == 'Auth#phoneCodeAutoRetrievalTimeout') { - final String verificationId = arguments['verificationId']; - - codeAutoRetrievalTimeout(verificationId); - } - }); + EventChannel( + eventChannelName, + ).receiveGuardedBroadcastStream(onError: convertPlatformException).listen( + (arguments) { + final name = arguments['name']; + if (name == 'Auth#phoneVerificationCompleted') { + final int token = arguments['token']; + final String? smsCode = arguments['smsCode']; + + PhoneAuthCredential phoneAuthCredential = + PhoneAuthProvider.credentialFromToken(token, smsCode: smsCode); + verificationCompleted(phoneAuthCredential); + } else if (name == 'Auth#phoneVerificationFailed') { + final Map? error = arguments['error']; + final Map? details = error?['details']; + + FirebaseAuthException exception = FirebaseAuthException( + message: details?['message'] ?? error?['message'], + code: details?['code'] ?? error?['code'] ?? 'unknown', + ); + + verificationFailed(exception); + } else if (name == 'Auth#phoneCodeSent') { + final String verificationId = arguments['verificationId']; + final int? forceResendingToken = arguments['forceResendingToken']; + + codeSent(verificationId, forceResendingToken); + } else if (name == 'Auth#phoneCodeAutoRetrievalTimeout') { + final String verificationId = arguments['verificationId']; + + codeAutoRetrievalTimeout(verificationId); + } + }, + ); } catch (e, stack) { convertPlatformException(e, stack); } @@ -735,7 +764,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { @override Future revokeTokenWithAuthorizationCode( - String authorizationCode) async { + String authorizationCode, + ) async { if (defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.iOS) { try { @@ -757,7 +787,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { Future revokeAccessToken(String accessToken) async { if (defaultTargetPlatform != TargetPlatform.android) { throw UnimplementedError( - 'revokeAccessToken() is only available on the Android platform.'); + 'revokeAccessToken() is only available on the Android platform.', + ); } try { diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_multi_factor.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_multi_factor.dart index f0a438aeb0b7..263df2fda0db 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_multi_factor.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_multi_factor.dart @@ -94,10 +94,7 @@ class MethodChannelMultiFactor extends MultiFactorPlatform { } try { - await _api.unenroll( - pigeonDefault, - uidToUnenroll, - ); + await _api.unenroll(pigeonDefault, uidToUnenroll); } catch (e, stack) { convertPlatformException(e, stack); } @@ -120,9 +117,9 @@ class MethodChannelMultiFactorResolver extends MultiFactorResolverPlatform { MultiFactorSession session, String resolverId, MethodChannelFirebaseAuth auth, - ) : _resolverId = resolverId, - _auth = auth, - super(hints, session); + ) : _resolverId = resolverId, + _auth = auth, + super(hints, session); final String _resolverId; @@ -197,9 +194,7 @@ class MultiFactorAssertion extends MultiFactorAssertionPlatform { } class PhoneMultiFactorAssertion extends MultiFactorAssertion { - PhoneMultiFactorAssertion( - PhoneAuthCredential credential, - ) : super(credential); + PhoneMultiFactorAssertion(PhoneAuthCredential credential) : super(credential); } /// Helper class used to generate PhoneMultiFactorAssertions. @@ -208,17 +203,13 @@ class MethodChannelPhoneMultiFactorGenerator /// Transforms a PhoneAuthCredential into a [MultiFactorAssertion] /// which can be used to confirm ownership of a phone second factor. @override - MultiFactorAssertionPlatform getAssertion( - PhoneAuthCredential credential, - ) { + MultiFactorAssertionPlatform getAssertion(PhoneAuthCredential credential) { return PhoneMultiFactorAssertion(credential); } } class TotpMultiFactorAssertion extends MultiFactorAssertion { - TotpMultiFactorAssertion( - this.assertionId, - ) : super(null); + TotpMultiFactorAssertion(this.assertionId) : super(null); final String assertionId; } @@ -231,9 +222,7 @@ class MethodChannelTotpMultiFactorGenerator /// Transforms a PhoneAuthCredential into a [MultiFactorAssertion] /// which can be used to confirm ownership of a phone second factor. @override - Future generateSecret( - MultiFactorSession session, - ) async { + Future generateSecret(MultiFactorSession session) async { final pigeonSecret = await _api.generateSecret(session.id); return MethodChannelTotpSecret( pigeonSecret.codeIntervalSeconds, @@ -255,8 +244,10 @@ class MethodChannelTotpMultiFactorGenerator TotpSecretPlatform secret, String oneTimePassword, ) async { - final totpAssertionId = - await _api.getAssertionForEnrollment(secret.secretKey, oneTimePassword); + final totpAssertionId = await _api.getAssertionForEnrollment( + secret.secretKey, + oneTimePassword, + ); return TotpMultiFactorAssertion(totpAssertionId); } @@ -267,8 +258,10 @@ class MethodChannelTotpMultiFactorGenerator String enrollmentId, String oneTimePassword, ) async { - final totpAssertionId = - await _api.getAssertionForSignIn(enrollmentId, oneTimePassword); + final totpAssertionId = await _api.getAssertionForSignIn( + enrollmentId, + oneTimePassword, + ); return TotpMultiFactorAssertion(totpAssertionId); } } @@ -303,12 +296,7 @@ class MethodChannelTotpSecret extends TotpSecretPlatform { /// Opens the specified QR Code URL in a password manager like iCloud Keychain. @override - Future openInOtpApp( - String qrCodeUrl, - ) async { - await _api.openInOtpApp( - secretKey, - qrCodeUrl, - ); + Future openInOtpApp(String qrCodeUrl) async { + await _api.openInOtpApp(secretKey, qrCodeUrl); } } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_user.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_user.dart index e6a627f8017b..e8b6fc36866e 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_user.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_user.dart @@ -15,9 +15,11 @@ import 'utils/exception.dart'; /// Method Channel delegate for [UserPlatform] instances. class MethodChannelUser extends UserPlatform { /// Constructs a new [MethodChannelUser] instance. - MethodChannelUser(FirebaseAuthPlatform auth, MultiFactorPlatform multiFactor, - InternalUserDetails data) - : super(auth, multiFactor, data); + MethodChannelUser( + FirebaseAuthPlatform auth, + MultiFactorPlatform multiFactor, + InternalUserDetails data, + ) : super(auth, multiFactor, data); final _api = FirebaseAuthUserHostApi(); @@ -41,10 +43,7 @@ class MethodChannelUser extends UserPlatform { @override Future getIdToken(bool forceRefresh) async { try { - final data = await _api.getIdToken( - pigeonDefault, - forceRefresh, - ); + final data = await _api.getIdToken(pigeonDefault, forceRefresh); return data.token; } catch (e, stack) { @@ -55,10 +54,7 @@ class MethodChannelUser extends UserPlatform { @override Future getIdTokenResult(bool forceRefresh) async { try { - final data = await _api.getIdToken( - pigeonDefault, - forceRefresh, - ); + final data = await _api.getIdToken(pigeonDefault, forceRefresh); return IdTokenResult(data); } catch (e, stack) { @@ -76,8 +72,10 @@ class MethodChannelUser extends UserPlatform { credential.asMap(), ); - MethodChannelUserCredential userCredential = - MethodChannelUserCredential(auth, result); + MethodChannelUserCredential userCredential = MethodChannelUserCredential( + auth, + result, + ); auth.currentUser = userCredential.user; return userCredential; @@ -87,9 +85,7 @@ class MethodChannelUser extends UserPlatform { } @override - Future linkWithProvider( - AuthProvider provider, - ) async { + Future linkWithProvider(AuthProvider provider) async { try { // To extract scopes and custom parameters from the provider final convertedProvider = convertToOAuthProvider(provider); @@ -107,8 +103,10 @@ class MethodChannelUser extends UserPlatform { ), ); - MethodChannelUserCredential userCredential = - MethodChannelUserCredential(auth, result); + MethodChannelUserCredential userCredential = MethodChannelUserCredential( + auth, + result, + ); auth.currentUser = userCredential.user; return userCredential; @@ -127,8 +125,10 @@ class MethodChannelUser extends UserPlatform { credential.asMap(), ); - MethodChannelUserCredential userCredential = - MethodChannelUserCredential(auth, result); + MethodChannelUserCredential userCredential = MethodChannelUserCredential( + auth, + result, + ); auth.currentUser = userCredential.user; return userCredential; @@ -158,8 +158,10 @@ class MethodChannelUser extends UserPlatform { ), ); - MethodChannelUserCredential userCredential = - MethodChannelUserCredential(auth, result); + MethodChannelUserCredential userCredential = MethodChannelUserCredential( + auth, + result, + ); auth.currentUser = userCredential.user; return userCredential; @@ -173,8 +175,11 @@ class MethodChannelUser extends UserPlatform { try { final result = await _api.reload(pigeonDefault); - MethodChannelUser user = - MethodChannelUser(auth, super.multiFactor, result); + MethodChannelUser user = MethodChannelUser( + auth, + super.multiFactor, + result, + ); auth.currentUser = user; auth.sendAuthChangesEvent(auth.app.name, user); } catch (e, stack) { @@ -212,8 +217,10 @@ class MethodChannelUser extends UserPlatform { final result = await _api.unlink(pigeonDefault, providerId); // Native returns a UserCredential, whereas Dart should expect a User - MethodChannelUserCredential userCredential = - MethodChannelUserCredential(auth, result); + MethodChannelUserCredential userCredential = MethodChannelUserCredential( + auth, + result, + ); MethodChannelUser? user = userCredential.user as MethodChannelUser?; auth.currentUser = user; @@ -229,8 +236,11 @@ class MethodChannelUser extends UserPlatform { try { final result = await _api.updateEmail(pigeonDefault, newEmail); - MethodChannelUser user = - MethodChannelUser(auth, super.multiFactor, result); + MethodChannelUser user = MethodChannelUser( + auth, + super.multiFactor, + result, + ); auth.currentUser = user; auth.sendAuthChangesEvent(auth.app.name, user); } catch (e, stack) { @@ -243,8 +253,11 @@ class MethodChannelUser extends UserPlatform { try { final result = await _api.updatePassword(pigeonDefault, newPassword); - MethodChannelUser user = - MethodChannelUser(auth, super.multiFactor, result); + MethodChannelUser user = MethodChannelUser( + auth, + super.multiFactor, + result, + ); auth.currentUser = user; auth.sendAuthChangesEvent(auth.app.name, user); } catch (e, stack) { @@ -260,8 +273,11 @@ class MethodChannelUser extends UserPlatform { phoneCredential.asMap(), ); - MethodChannelUser user = - MethodChannelUser(auth, super.multiFactor, result); + MethodChannelUser user = MethodChannelUser( + auth, + super.multiFactor, + result, + ); auth.currentUser = user; auth.sendAuthChangesEvent(auth.app.name, user); } catch (e, stack) { @@ -281,8 +297,11 @@ class MethodChannelUser extends UserPlatform { photoUrlChanged: profile.containsKey('photoURL'), ), ); - MethodChannelUser user = - MethodChannelUser(auth, super.multiFactor, result); + MethodChannelUser user = MethodChannelUser( + auth, + super.multiFactor, + result, + ); auth.currentUser = user; auth.sendAuthChangesEvent(auth.app.name, user); } catch (e, stack) { diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_user_credential.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_user_credential.dart index 7b65930754a9..3cba6912874c 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_user_credential.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_user_credential.dart @@ -12,33 +12,35 @@ import 'package:firebase_auth_platform_interface/src/pigeon/messages.pigeon.dart class MethodChannelUserCredential extends UserCredentialPlatform { // ignore: public_member_api_docs MethodChannelUserCredential( - FirebaseAuthPlatform auth, InternalUserCredential data) - : super( - auth: auth, - additionalUserInfo: data.additionalUserInfo == null - ? null - : AdditionalUserInfo( - isNewUser: data.additionalUserInfo!.isNewUser, - profile: Map.from( - data.additionalUserInfo!.profile ?? {}), - providerId: data.additionalUserInfo!.providerId, - username: data.additionalUserInfo!.username, - authorizationCode: data.additionalUserInfo?.authorizationCode, + FirebaseAuthPlatform auth, + InternalUserCredential data, + ) : super( + auth: auth, + additionalUserInfo: data.additionalUserInfo == null + ? null + : AdditionalUserInfo( + isNewUser: data.additionalUserInfo!.isNewUser, + profile: Map.from( + data.additionalUserInfo!.profile ?? {}, ), - credential: data.credential == null - ? null - : AuthCredential( - providerId: data.credential!.providerId, - signInMethod: data.credential!.signInMethod, - token: data.credential!.nativeId, - accessToken: data.credential!.accessToken, - ), - user: data.user == null - ? null - : MethodChannelUser( - auth, - MethodChannelMultiFactor(auth), - data.user!, - ), - ); + providerId: data.additionalUserInfo!.providerId, + username: data.additionalUserInfo!.username, + authorizationCode: data.additionalUserInfo?.authorizationCode, + ), + credential: data.credential == null + ? null + : AuthCredential( + providerId: data.credential!.providerId, + signInMethod: data.credential!.signInMethod, + token: data.credential!.nativeId, + accessToken: data.credential!.accessToken, + ), + user: data.user == null + ? null + : MethodChannelUser( + auth, + MethodChannelMultiFactor(auth), + data.user!, + ), + ); } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/utils/convert_auth_provider.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/utils/convert_auth_provider.dart index 48f63a8ec32a..8f062b8c3a2c 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/utils/convert_auth_provider.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/utils/convert_auth_provider.dart @@ -37,8 +37,9 @@ AuthProvider convertToOAuthProvider(AuthProvider authProvider) { if (authProvider is GoogleAuthProvider) { final oAuthProvider = OAuthProvider(authProvider.providerId); oAuthProvider.setScopes(authProvider.scopes); - oAuthProvider - .setCustomParameters(authProvider.parameters.cast()); + oAuthProvider.setCustomParameters( + authProvider.parameters.cast(), + ); return oAuthProvider; } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/utils/exception.dart index d01fedccb150..6daa60da6f31 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/utils/exception.dart @@ -46,10 +46,7 @@ FirebaseException platformExceptionToFirebaseAuthException( ? platformException.details as Map : null; - final customCode = _getCustomCode( - details, - platformException.message, - ); + final customCode = _getCustomCode(details, platformException.message); if (customCode != null) { code = customCode; } @@ -166,7 +163,8 @@ String? _getCustomCode(Map? additionalData, String? message) { const kMultiFactorError = 'second-factor-required'; FirebaseAuthMultiFactorExceptionPlatform parseMultiFactorError( - PlatformException exception) { + PlatformException exception, +) { const code = kMultiFactorError; final message = exception.message; final additionalData = exception.details as Map?; @@ -179,25 +177,17 @@ FirebaseAuthMultiFactorExceptionPlatform parseMultiFactorError( } final pigeonMultiFactorInfo = - (additionalData['multiFactorHints'] as List? ?? []) - .nonNulls - .map( - InternalMultiFactorInfo.decode, - ) + (additionalData['multiFactorHints'] as List? ?? []).nonNulls + .map(InternalMultiFactorInfo.decode) .toList(); - final multiFactorInfo = multiFactorInfoPigeonToObject( - pigeonMultiFactorInfo, - ); + final multiFactorInfo = multiFactorInfoPigeonToObject(pigeonMultiFactorInfo); final auth = MethodChannelFirebaseAuth .methodChannelFirebaseAuthInstances[additionalData['appName']]; if (auth == null) { - throw FirebaseAuthException( - code: code, - message: message, - ); + throw FirebaseAuthException(code: code, message: message); } final sessionId = additionalData['multiFactorSessionId'] as String?; diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/pigeon/messages.pigeon.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/pigeon/messages.pigeon.dart index 751c8650e0ef..f6e6b8209afc 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/pigeon/messages.pigeon.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/pigeon/messages.pigeon.dart @@ -37,8 +37,11 @@ Object? _extractReplyValueOrThrow( return replyList.firstOrNull; } -List wrapResponse( - {Object? result, PlatformException? error, bool empty = false}) { +List wrapResponse({ + Object? result, + PlatformException? error, + bool empty = false, +}) { if (empty) { return []; } @@ -60,8 +63,9 @@ bool _deepEquals(Object? a, Object? b) { } if (a is List && b is List) { return a.length == b.length && - a.indexed - .every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1])); + a.indexed.every( + ((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]), + ); } if (a is Map && b is Map) { if (a.length != b.length) { @@ -136,16 +140,12 @@ enum ActionCodeInfoOperation { } class InternalMultiFactorSession { - InternalMultiFactorSession({ - required this.id, - }); + InternalMultiFactorSession({required this.id}); String id; List _toList() { - return [ - id, - ]; + return [id]; } Object encode() { @@ -154,9 +154,7 @@ class InternalMultiFactorSession { static InternalMultiFactorSession decode(Object result) { result as List; - return InternalMultiFactorSession( - id: result[0]! as String, - ); + return InternalMultiFactorSession(id: result[0]! as String); } @override @@ -188,10 +186,7 @@ class InternalPhoneMultiFactorAssertion { String verificationCode; List _toList() { - return [ - verificationId, - verificationCode, - ]; + return [verificationId, verificationCode]; } Object encode() { @@ -304,11 +299,7 @@ class AuthPigeonFirebaseApp { String? customAuthDomain; List _toList() { - return [ - appName, - tenantId, - customAuthDomain, - ]; + return [appName, tenantId, customAuthDomain]; } Object encode() { @@ -344,20 +335,14 @@ class AuthPigeonFirebaseApp { } class InternalActionCodeInfoData { - InternalActionCodeInfoData({ - this.email, - this.previousEmail, - }); + InternalActionCodeInfoData({this.email, this.previousEmail}); String? email; String? previousEmail; List _toList() { - return [ - email, - previousEmail, - ]; + return [email, previousEmail]; } Object encode() { @@ -392,20 +377,14 @@ class InternalActionCodeInfoData { } class InternalActionCodeInfo { - InternalActionCodeInfo({ - required this.operation, - required this.data, - }); + InternalActionCodeInfo({required this.operation, required this.data}); ActionCodeInfoOperation operation; InternalActionCodeInfoData data; List _toList() { - return [ - operation, - data, - ]; + return [operation, data]; } Object encode() { @@ -521,12 +500,7 @@ class InternalAuthCredential { String? accessToken; List _toList() { - return [ - providerId, - signInMethod, - nativeId, - accessToken, - ]; + return [providerId, signInMethod, nativeId, accessToken]; } Object encode() { @@ -671,20 +645,14 @@ class InternalUserInfo { } class InternalUserDetails { - InternalUserDetails({ - required this.userInfo, - required this.providerData, - }); + InternalUserDetails({required this.userInfo, required this.providerData}); InternalUserInfo userInfo; List?> providerData; List _toList() { - return [ - userInfo, - providerData, - ]; + return [userInfo, providerData]; } Object encode() { @@ -695,8 +663,8 @@ class InternalUserDetails { result as List; return InternalUserDetails( userInfo: result[0]! as InternalUserInfo, - providerData: - (result[1]! as List).cast?>(), + providerData: (result[1]! as List) + .cast?>(), ); } @@ -719,11 +687,7 @@ class InternalUserDetails { } class InternalUserCredential { - InternalUserCredential({ - this.user, - this.additionalUserInfo, - this.credential, - }); + InternalUserCredential({this.user, this.additionalUserInfo, this.credential}); InternalUserDetails? user; @@ -732,11 +696,7 @@ class InternalUserCredential { InternalAuthCredential? credential; List _toList() { - return [ - user, - additionalUserInfo, - credential, - ]; + return [user, additionalUserInfo, credential]; } Object encode() { @@ -788,12 +748,7 @@ class InternalAuthCredentialInput { String? accessToken; List _toList() { - return [ - providerId, - signInMethod, - token, - accessToken, - ]; + return [providerId, signInMethod, token, accessToken]; } Object encode() { @@ -974,8 +929,10 @@ class InternalFirebaseAuthSettings { if (identical(this, other)) { return true; } - return _deepEquals(appVerificationDisabledForTesting, - other.appVerificationDisabledForTesting) && + return _deepEquals( + appVerificationDisabledForTesting, + other.appVerificationDisabledForTesting, + ) && _deepEquals(userAccessGroup, other.userAccessGroup) && _deepEquals(migrateCurrentUser, other.migrateCurrentUser) && _deepEquals(phoneNumber, other.phoneNumber) && @@ -1002,11 +959,7 @@ class InternalSignInProvider { Map? customParameters; List _toList() { - return [ - providerId, - scopes, - customParameters, - ]; + return [providerId, scopes, customParameters]; } Object encode() { @@ -1018,8 +971,8 @@ class InternalSignInProvider { return InternalSignInProvider( providerId: result[0]! as String, scopes: (result[1] as List?)?.cast(), - customParameters: - (result[2] as Map?)?.cast(), + customParameters: (result[2] as Map?) + ?.cast(), ); } @@ -1104,8 +1057,10 @@ class InternalVerifyPhoneNumberRequest { return _deepEquals(phoneNumber, other.phoneNumber) && _deepEquals(timeout, other.timeout) && _deepEquals(forceResendingToken, other.forceResendingToken) && - _deepEquals(autoRetrievedSmsCodeForTesting, - other.autoRetrievedSmsCodeForTesting) && + _deepEquals( + autoRetrievedSmsCodeForTesting, + other.autoRetrievedSmsCodeForTesting, + ) && _deepEquals(multiFactorInfoId, other.multiFactorInfoId) && _deepEquals(multiFactorSessionId, other.multiFactorSessionId); } @@ -1307,7 +1262,9 @@ class InternalTotpSecret { return _deepEquals(codeIntervalSeconds, other.codeIntervalSeconds) && _deepEquals(codeLength, other.codeLength) && _deepEquals( - enrollmentCompletionDeadline, other.enrollmentCompletionDeadline) && + enrollmentCompletionDeadline, + other.enrollmentCompletionDeadline, + ) && _deepEquals(hashingAlgorithm, other.hashingAlgorithm) && _deepEquals(secretKey, other.secretKey); } @@ -1443,11 +1400,13 @@ class FirebaseAuthHostApi { /// Constructor for [FirebaseAuthHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - FirebaseAuthHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + FirebaseAuthHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -1462,8 +1421,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1482,8 +1442,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1495,7 +1456,10 @@ class FirebaseAuthHostApi { } Future useEmulator( - AuthPigeonFirebaseApp app, String host, int port) async { + AuthPigeonFirebaseApp app, + String host, + int port, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.useEmulator$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1503,8 +1467,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, host, port]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, host, port], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1522,8 +1487,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, code]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, code], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1534,7 +1500,9 @@ class FirebaseAuthHostApi { } Future checkActionCode( - AuthPigeonFirebaseApp app, String code) async { + AuthPigeonFirebaseApp app, + String code, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.checkActionCode$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1542,8 +1510,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, code]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, code], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1555,7 +1524,10 @@ class FirebaseAuthHostApi { } Future confirmPasswordReset( - AuthPigeonFirebaseApp app, String code, String newPassword) async { + AuthPigeonFirebaseApp app, + String code, + String newPassword, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.confirmPasswordReset$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1563,8 +1535,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, code, newPassword]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, code, newPassword], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1575,7 +1548,10 @@ class FirebaseAuthHostApi { } Future createUserWithEmailAndPassword( - AuthPigeonFirebaseApp app, String email, String password) async { + AuthPigeonFirebaseApp app, + String email, + String password, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.createUserWithEmailAndPassword$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1583,8 +1559,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, email, password]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, email, password], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1596,7 +1573,8 @@ class FirebaseAuthHostApi { } Future signInAnonymously( - AuthPigeonFirebaseApp app) async { + AuthPigeonFirebaseApp app, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInAnonymously$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1604,8 +1582,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1617,7 +1596,9 @@ class FirebaseAuthHostApi { } Future signInWithCredential( - AuthPigeonFirebaseApp app, Map input) async { + AuthPigeonFirebaseApp app, + Map input, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInWithCredential$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1625,8 +1606,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, input]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, input], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1638,7 +1620,9 @@ class FirebaseAuthHostApi { } Future signInWithCustomToken( - AuthPigeonFirebaseApp app, String token) async { + AuthPigeonFirebaseApp app, + String token, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInWithCustomToken$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1646,8 +1630,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, token]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, token], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1659,7 +1644,10 @@ class FirebaseAuthHostApi { } Future signInWithEmailAndPassword( - AuthPigeonFirebaseApp app, String email, String password) async { + AuthPigeonFirebaseApp app, + String email, + String password, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInWithEmailAndPassword$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1667,8 +1655,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, email, password]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, email, password], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1680,7 +1669,10 @@ class FirebaseAuthHostApi { } Future signInWithEmailLink( - AuthPigeonFirebaseApp app, String email, String emailLink) async { + AuthPigeonFirebaseApp app, + String email, + String emailLink, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInWithEmailLink$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1688,8 +1680,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, email, emailLink]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, email, emailLink], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1701,7 +1694,9 @@ class FirebaseAuthHostApi { } Future signInWithProvider( - AuthPigeonFirebaseApp app, InternalSignInProvider signInProvider) async { + AuthPigeonFirebaseApp app, + InternalSignInProvider signInProvider, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInWithProvider$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1709,8 +1704,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, signInProvider]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, signInProvider], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1729,8 +1725,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1741,7 +1738,9 @@ class FirebaseAuthHostApi { } Future> fetchSignInMethodsForEmail( - AuthPigeonFirebaseApp app, String email) async { + AuthPigeonFirebaseApp app, + String email, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.fetchSignInMethodsForEmail$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1749,8 +1748,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, email]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, email], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1761,8 +1761,11 @@ class FirebaseAuthHostApi { return (pigeonVar_replyValue! as List).cast(); } - Future sendPasswordResetEmail(AuthPigeonFirebaseApp app, String email, - InternalActionCodeSettings? actionCodeSettings) async { + Future sendPasswordResetEmail( + AuthPigeonFirebaseApp app, + String email, + InternalActionCodeSettings? actionCodeSettings, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.sendPasswordResetEmail$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1770,8 +1773,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, email, actionCodeSettings]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, email, actionCodeSettings], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1781,8 +1785,11 @@ class FirebaseAuthHostApi { ); } - Future sendSignInLinkToEmail(AuthPigeonFirebaseApp app, String email, - InternalActionCodeSettings actionCodeSettings) async { + Future sendSignInLinkToEmail( + AuthPigeonFirebaseApp app, + String email, + InternalActionCodeSettings actionCodeSettings, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.sendSignInLinkToEmail$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1790,8 +1797,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, email, actionCodeSettings]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, email, actionCodeSettings], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1802,7 +1810,9 @@ class FirebaseAuthHostApi { } Future setLanguageCode( - AuthPigeonFirebaseApp app, String? languageCode) async { + AuthPigeonFirebaseApp app, + String? languageCode, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.setLanguageCode$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1810,8 +1820,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, languageCode]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, languageCode], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1826,7 +1837,9 @@ class FirebaseAuthHostApi { /// is true and a user was migrated, returns that user so Dart can reconcile /// [currentUser] before auth-state events arrive. Otherwise returns null. Future setSettings( - AuthPigeonFirebaseApp app, InternalFirebaseAuthSettings settings) async { + AuthPigeonFirebaseApp app, + InternalFirebaseAuthSettings settings, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.setSettings$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1834,8 +1847,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, settings]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, settings], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1847,7 +1861,9 @@ class FirebaseAuthHostApi { } Future verifyPasswordResetCode( - AuthPigeonFirebaseApp app, String code) async { + AuthPigeonFirebaseApp app, + String code, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.verifyPasswordResetCode$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1855,8 +1871,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, code]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, code], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1867,8 +1884,10 @@ class FirebaseAuthHostApi { return pigeonVar_replyValue! as String; } - Future verifyPhoneNumber(AuthPigeonFirebaseApp app, - InternalVerifyPhoneNumberRequest request) async { + Future verifyPhoneNumber( + AuthPigeonFirebaseApp app, + InternalVerifyPhoneNumberRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.verifyPhoneNumber$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1876,8 +1895,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1889,7 +1909,9 @@ class FirebaseAuthHostApi { } Future revokeTokenWithAuthorizationCode( - AuthPigeonFirebaseApp app, String authorizationCode) async { + AuthPigeonFirebaseApp app, + String authorizationCode, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.revokeTokenWithAuthorizationCode$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1897,8 +1919,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, authorizationCode]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, authorizationCode], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1909,7 +1932,9 @@ class FirebaseAuthHostApi { } Future revokeAccessToken( - AuthPigeonFirebaseApp app, String accessToken) async { + AuthPigeonFirebaseApp app, + String accessToken, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.revokeAccessToken$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1917,8 +1942,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, accessToken]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, accessToken], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1936,8 +1962,9 @@ class FirebaseAuthHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1952,11 +1979,13 @@ class FirebaseAuthUserHostApi { /// Constructor for [FirebaseAuthUserHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - FirebaseAuthUserHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + FirebaseAuthUserHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -1971,8 +2000,9 @@ class FirebaseAuthUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1983,7 +2013,9 @@ class FirebaseAuthUserHostApi { } Future getIdToken( - AuthPigeonFirebaseApp app, bool forceRefresh) async { + AuthPigeonFirebaseApp app, + bool forceRefresh, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.getIdToken$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1991,8 +2023,9 @@ class FirebaseAuthUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, forceRefresh]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, forceRefresh], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2004,7 +2037,9 @@ class FirebaseAuthUserHostApi { } Future linkWithCredential( - AuthPigeonFirebaseApp app, Map input) async { + AuthPigeonFirebaseApp app, + Map input, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.linkWithCredential$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2012,8 +2047,9 @@ class FirebaseAuthUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, input]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, input], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2025,7 +2061,9 @@ class FirebaseAuthUserHostApi { } Future linkWithProvider( - AuthPigeonFirebaseApp app, InternalSignInProvider signInProvider) async { + AuthPigeonFirebaseApp app, + InternalSignInProvider signInProvider, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.linkWithProvider$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2033,8 +2071,9 @@ class FirebaseAuthUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, signInProvider]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, signInProvider], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2046,7 +2085,9 @@ class FirebaseAuthUserHostApi { } Future reauthenticateWithCredential( - AuthPigeonFirebaseApp app, Map input) async { + AuthPigeonFirebaseApp app, + Map input, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.reauthenticateWithCredential$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2054,8 +2095,9 @@ class FirebaseAuthUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, input]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, input], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2067,7 +2109,9 @@ class FirebaseAuthUserHostApi { } Future reauthenticateWithProvider( - AuthPigeonFirebaseApp app, InternalSignInProvider signInProvider) async { + AuthPigeonFirebaseApp app, + InternalSignInProvider signInProvider, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.reauthenticateWithProvider$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2075,8 +2119,9 @@ class FirebaseAuthUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, signInProvider]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, signInProvider], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2095,8 +2140,9 @@ class FirebaseAuthUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2107,8 +2153,10 @@ class FirebaseAuthUserHostApi { return pigeonVar_replyValue! as InternalUserDetails; } - Future sendEmailVerification(AuthPigeonFirebaseApp app, - InternalActionCodeSettings? actionCodeSettings) async { + Future sendEmailVerification( + AuthPigeonFirebaseApp app, + InternalActionCodeSettings? actionCodeSettings, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.sendEmailVerification$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2116,8 +2164,9 @@ class FirebaseAuthUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, actionCodeSettings]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, actionCodeSettings], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -2128,7 +2177,9 @@ class FirebaseAuthUserHostApi { } Future unlink( - AuthPigeonFirebaseApp app, String providerId) async { + AuthPigeonFirebaseApp app, + String providerId, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.unlink$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2136,8 +2187,9 @@ class FirebaseAuthUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, providerId]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, providerId], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2149,7 +2201,9 @@ class FirebaseAuthUserHostApi { } Future updateEmail( - AuthPigeonFirebaseApp app, String newEmail) async { + AuthPigeonFirebaseApp app, + String newEmail, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.updateEmail$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2157,8 +2211,9 @@ class FirebaseAuthUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, newEmail]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, newEmail], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2170,7 +2225,9 @@ class FirebaseAuthUserHostApi { } Future updatePassword( - AuthPigeonFirebaseApp app, String newPassword) async { + AuthPigeonFirebaseApp app, + String newPassword, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.updatePassword$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2178,8 +2235,9 @@ class FirebaseAuthUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, newPassword]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, newPassword], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2191,7 +2249,9 @@ class FirebaseAuthUserHostApi { } Future updatePhoneNumber( - AuthPigeonFirebaseApp app, Map input) async { + AuthPigeonFirebaseApp app, + Map input, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.updatePhoneNumber$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2199,8 +2259,9 @@ class FirebaseAuthUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, input]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, input], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2212,7 +2273,9 @@ class FirebaseAuthUserHostApi { } Future updateProfile( - AuthPigeonFirebaseApp app, InternalUserProfile profile) async { + AuthPigeonFirebaseApp app, + InternalUserProfile profile, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.updateProfile$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2220,8 +2283,9 @@ class FirebaseAuthUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, profile]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, profile], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2232,8 +2296,11 @@ class FirebaseAuthUserHostApi { return pigeonVar_replyValue! as InternalUserDetails; } - Future verifyBeforeUpdateEmail(AuthPigeonFirebaseApp app, - String newEmail, InternalActionCodeSettings? actionCodeSettings) async { + Future verifyBeforeUpdateEmail( + AuthPigeonFirebaseApp app, + String newEmail, + InternalActionCodeSettings? actionCodeSettings, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.verifyBeforeUpdateEmail$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2241,8 +2308,9 @@ class FirebaseAuthUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, newEmail, actionCodeSettings]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, newEmail, actionCodeSettings], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -2257,19 +2325,24 @@ class MultiFactorUserHostApi { /// Constructor for [MultiFactorUserHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - MultiFactorUserHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + MultiFactorUserHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); final String pigeonVar_messageChannelSuffix; - Future enrollPhone(AuthPigeonFirebaseApp app, - InternalPhoneMultiFactorAssertion assertion, String? displayName) async { + Future enrollPhone( + AuthPigeonFirebaseApp app, + InternalPhoneMultiFactorAssertion assertion, + String? displayName, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorUserHostApi.enrollPhone$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2277,8 +2350,9 @@ class MultiFactorUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, assertion, displayName]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, assertion, displayName], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -2288,8 +2362,11 @@ class MultiFactorUserHostApi { ); } - Future enrollTotp(AuthPigeonFirebaseApp app, String assertionId, - String? displayName) async { + Future enrollTotp( + AuthPigeonFirebaseApp app, + String assertionId, + String? displayName, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorUserHostApi.enrollTotp$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2297,8 +2374,9 @@ class MultiFactorUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, assertionId, displayName]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, assertionId, displayName], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -2309,7 +2387,8 @@ class MultiFactorUserHostApi { } Future getSession( - AuthPigeonFirebaseApp app) async { + AuthPigeonFirebaseApp app, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorUserHostApi.getSession$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2317,8 +2396,9 @@ class MultiFactorUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2337,8 +2417,9 @@ class MultiFactorUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, factorUid]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, factorUid], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -2349,7 +2430,8 @@ class MultiFactorUserHostApi { } Future> getEnrolledFactors( - AuthPigeonFirebaseApp app) async { + AuthPigeonFirebaseApp app, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorUserHostApi.getEnrolledFactors$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2357,8 +2439,9 @@ class MultiFactorUserHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2375,11 +2458,13 @@ class MultiFactoResolverHostApi { /// Constructor for [MultiFactoResolverHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - MultiFactoResolverHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + MultiFactoResolverHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -2387,9 +2472,10 @@ class MultiFactoResolverHostApi { final String pigeonVar_messageChannelSuffix; Future resolveSignIn( - String resolverId, - InternalPhoneMultiFactorAssertion? assertion, - String? totpAssertionId) async { + String resolverId, + InternalPhoneMultiFactorAssertion? assertion, + String? totpAssertionId, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactoResolverHostApi.resolveSignIn$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2397,8 +2483,9 @@ class MultiFactoResolverHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel - .send([resolverId, assertion, totpAssertionId]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [resolverId, assertion, totpAssertionId], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2414,11 +2501,13 @@ class MultiFactorTotpHostApi { /// Constructor for [MultiFactorTotpHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - MultiFactorTotpHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + MultiFactorTotpHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -2433,8 +2522,9 @@ class MultiFactorTotpHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([sessionId]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [sessionId], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2446,7 +2536,9 @@ class MultiFactorTotpHostApi { } Future getAssertionForEnrollment( - String secretKey, String oneTimePassword) async { + String secretKey, + String oneTimePassword, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorTotpHostApi.getAssertionForEnrollment$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2454,8 +2546,9 @@ class MultiFactorTotpHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([secretKey, oneTimePassword]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [secretKey, oneTimePassword], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2467,7 +2560,9 @@ class MultiFactorTotpHostApi { } Future getAssertionForSignIn( - String enrollmentId, String oneTimePassword) async { + String enrollmentId, + String oneTimePassword, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorTotpHostApi.getAssertionForSignIn$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2475,8 +2570,9 @@ class MultiFactorTotpHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([enrollmentId, oneTimePassword]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [enrollmentId, oneTimePassword], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2492,11 +2588,13 @@ class MultiFactorTotpSecretHostApi { /// Constructor for [MultiFactorTotpSecretHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - MultiFactorTotpSecretHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + MultiFactorTotpSecretHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -2504,7 +2602,10 @@ class MultiFactorTotpSecretHostApi { final String pigeonVar_messageChannelSuffix; Future generateQrCodeUrl( - String secretKey, String? accountName, String? issuer) async { + String secretKey, + String? accountName, + String? issuer, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorTotpSecretHostApi.generateQrCodeUrl$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -2512,8 +2613,9 @@ class MultiFactorTotpSecretHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([secretKey, accountName, issuer]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [secretKey, accountName, issuer], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -2532,8 +2634,9 @@ class MultiFactorTotpSecretHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([secretKey, qrCodeUrl]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [secretKey, qrCodeUrl], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -2549,11 +2652,13 @@ class GenerateInterfaces { /// Constructor for [GenerateInterfaces]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - GenerateInterfaces( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + GenerateInterfaces({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -2568,8 +2673,9 @@ class GenerateInterfaces { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([info]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [info], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/platform_interface/platform_interface_firebase_auth.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/platform_interface/platform_interface_firebase_auth.dart index b6013e880db0..101425fdefdb 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/platform_interface/platform_interface_firebase_auth.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/platform_interface/platform_interface_firebase_auth.dart @@ -68,7 +68,9 @@ abstract class FirebaseAuthPlatform extends PlatformInterface { final secondElement = currentUser[1]!; currentUser = InternalUserDetails.decode([firstElement, secondElement]); } - return FirebaseAuthPlatform.instance.delegateFor(app: app).setInitialValues( + return FirebaseAuthPlatform.instance + .delegateFor(app: app) + .setInitialValues( languageCode: pluginConstants['APP_LANGUAGE_CODE'], currentUser: currentUser, ); @@ -727,7 +729,8 @@ abstract class FirebaseAuthPlatform extends PlatformInterface { /// Authorization code can be retrieved on the user credential i.e. userCredential.additionalUserInfo.authorizationCode Future revokeTokenWithAuthorizationCode(String authorizationCode) { throw UnimplementedError( - 'revokeTokenWithAuthorizationCode() is not implemented'); + 'revokeTokenWithAuthorizationCode() is not implemented', + ); } /// Android only. Revokes the provided accessToken. Currently supports revoking Apple-issued accessToken only. diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/platform_interface/platform_interface_multi_factor.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/platform_interface/platform_interface_multi_factor.dart index ac21ecaf4d1c..3ead798f287a 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/platform_interface/platform_interface_multi_factor.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/platform_interface/platform_interface_multi_factor.dart @@ -12,9 +12,7 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; /// {@endtemplate} abstract class MultiFactorPlatform extends PlatformInterface { /// {@macro .platformInterfaceMultiFactor} - MultiFactorPlatform( - this.auth, - ) : super(token: _token); + MultiFactorPlatform(this.auth) : super(token: _token); /// The [FirebaseAuthPlatform] instance. final FirebaseAuthPlatform auth; @@ -82,10 +80,7 @@ class MultiFactorAssertionPlatform extends PlatformInterface { /// {@endtemplate} class MultiFactorResolverPlatform extends PlatformInterface { /// {@macro .platformInterfaceMultiFactorResolverPlatform} - MultiFactorResolverPlatform( - this.hints, - this.session, - ) : super(token: _token); + MultiFactorResolverPlatform(this.hints, this.session) : super(token: _token); static final Object _token = Object(); @@ -148,11 +143,11 @@ class PhoneMultiFactorInfo extends MultiFactorInfo { required String uid, required this.phoneNumber, }) : super( - displayName: displayName, - enrollmentTimestamp: enrollmentTimestamp, - factorId: factorId, - uid: uid, - ); + displayName: displayName, + enrollmentTimestamp: enrollmentTimestamp, + factorId: factorId, + uid: uid, + ); /// The phone number associated with this second factor verification method. final String phoneNumber; @@ -193,9 +188,7 @@ class PhoneMultiFactorGeneratorPlatform extends PlatformInterface { /// Transforms a PhoneAuthCredential into a [MultiFactorAssertion] /// which can be used to confirm ownership of a phone second factor. - MultiFactorAssertionPlatform getAssertion( - PhoneAuthCredential credential, - ) { + MultiFactorAssertionPlatform getAssertion(PhoneAuthCredential credential) { throw UnimplementedError('getAssertion() is not implemented'); } } @@ -224,9 +217,7 @@ class TotpMultiFactorGeneratorPlatform extends PlatformInterface { } /// Generate a TOTP secret for the authenticated user. - Future generateSecret( - MultiFactorSession session, - ) { + Future generateSecret(MultiFactorSession session) { throw UnimplementedError('generateSecret() is not implemented'); } @@ -268,17 +259,12 @@ class TotpSecretPlatform extends PlatformInterface { ) : super(token: _token); /// Generate a TOTP secret for the authenticated user. - Future generateQrCodeUrl({ - String? accountName, - String? issuer, - }) { + Future generateQrCodeUrl({String? accountName, String? issuer}) { throw UnimplementedError('generateQrCodeUrl() is not implemented'); } /// Opens the specified QR Code URL in a password manager like iCloud Keychain. - Future openInOtpApp( - String qrCodeUrl, - ) async { + Future openInOtpApp(String qrCodeUrl) async { throw UnimplementedError('openInOtpApp() is not implemented'); } } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/platform_interface/platform_interface_recaptcha_verifier_factory.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/platform_interface/platform_interface_recaptcha_verifier_factory.dart index 7a3befbc7ff2..d672b252a1fe 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/platform_interface/platform_interface_recaptcha_verifier_factory.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/platform_interface/platform_interface_recaptcha_verifier_factory.dart @@ -30,9 +30,8 @@ enum RecaptchaVerifierTheme { typedef RecaptchaVerifierOnSuccess = void Function(); /// Called when the reCAPTCHA widget errors (such as a network error). -typedef RecaptchaVerifierOnError = void Function( - FirebaseAuthException exception, -); +typedef RecaptchaVerifierOnError = + void Function(FirebaseAuthException exception); /// Called when the time to complete the reCAPTCHA widget expires. typedef RecaptchaVerifierOnExpired = void Function(); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/platform_interface/platform_interface_user.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/platform_interface/platform_interface_user.dart index bc8060fd7c0b..8c80df6c78ea 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/platform_interface/platform_interface_user.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/platform_interface/platform_interface_user.dart @@ -12,8 +12,8 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; abstract class UserPlatform extends PlatformInterface { // ignore: public_member_api_docs UserPlatform(this.auth, this.multiFactor, InternalUserDetails user) - : _user = user, - super(token: _token); + : _user = user, + super(token: _token); static final Object _token = Object(); @@ -295,9 +295,7 @@ abstract class UserPlatform extends PlatformInterface { /// - Thrown if you have not enabled the provider in the Firebase Console. Go /// to the Firebase Console for your project, in the Auth section and the /// Sign in Method tab and configure the provider. - Future reauthenticateWithRedirect( - AuthProvider provider, - ) { + Future reauthenticateWithRedirect(AuthProvider provider) { throw UnimplementedError('reauthenticateWithRedirect() is not implemented'); } @@ -439,9 +437,11 @@ abstract class UserPlatform extends PlatformInterface { /// - Thrown if the credential is a [PhoneAuthProvider.credential] and the /// verification ID of the credential is not valid. Future reauthenticateWithCredential( - AuthCredential credential) { + AuthCredential credential, + ) { throw UnimplementedError( - 'reauthenticateWithCredential() is not implemented'); + 'reauthenticateWithCredential() is not implemented', + ); } /// Refreshes the current user, if signed in. diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/apple_auth.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/apple_auth.dart index 678c7835f791..ebb5464bd4e3 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/apple_auth.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/apple_auth.dart @@ -41,9 +41,7 @@ class AppleAuthProvider extends AuthProvider { /// Create a new [AppleAuthCredential] from a provided [accessToken]; static OAuthCredential credential(String accessToken) { - return AppleAuthCredential._credential( - accessToken, - ); + return AppleAuthCredential._credential(accessToken); } /// Create a new [AppleAuthCredential] from a provided [idToken], [rawNonce] and [appleFullPersonName]; @@ -107,18 +105,16 @@ class AppleAuthCredential extends OAuthCredential { String? idToken, AppleFullPersonName? appleFullPersonName, }) : super( - providerId: _kProviderId, - signInMethod: _kProviderId, - accessToken: accessToken, - appleFullPersonName: appleFullPersonName, - rawNonce: rawNonce, - idToken: idToken, - ); + providerId: _kProviderId, + signInMethod: _kProviderId, + accessToken: accessToken, + appleFullPersonName: appleFullPersonName, + rawNonce: rawNonce, + idToken: idToken, + ); factory AppleAuthCredential._credential(String accessToken) { - return AppleAuthCredential._( - accessToken: accessToken, - ); + return AppleAuthCredential._(accessToken: accessToken); } factory AppleAuthCredential._credentialWithIDToken( diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/email_auth.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/email_auth.dart index 98fa9b3124df..2b7f2d0ae760 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/email_auth.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/email_auth.dart @@ -61,14 +61,22 @@ class EmailAuthCredential extends AuthCredential { }) : super(providerId: _kProviderId, signInMethod: _signInMethod); factory EmailAuthCredential._credential(String email, String password) { - return EmailAuthCredential._(_kProviderId, - email: email, password: password); + return EmailAuthCredential._( + _kProviderId, + email: email, + password: password, + ); } factory EmailAuthCredential._credentialWithLink( - String email, String emailLink) { - return EmailAuthCredential._(_kLinkProviderId, - email: email, emailLink: emailLink); + String email, + String emailLink, + ) { + return EmailAuthCredential._( + _kLinkProviderId, + email: email, + emailLink: emailLink, + ); } /// The user's email address. diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/facebook_auth.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/facebook_auth.dart index 13b333e657bb..567967aa2d43 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/facebook_auth.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/facebook_auth.dart @@ -41,9 +41,7 @@ class FacebookAuthProvider extends AuthProvider { /// Create a new [FacebookAuthCredential] from a provided [accessToken]; static OAuthCredential credential(String accessToken) { - return FacebookAuthCredential._credential( - accessToken, - ); + return FacebookAuthCredential._credential(accessToken); } /// This corresponds to the sign-in method identifier. @@ -88,12 +86,12 @@ class FacebookAuthProvider extends AuthProvider { /// The auth credential returned from calling /// [FacebookAuthProvider.credential]. class FacebookAuthCredential extends OAuthCredential { - FacebookAuthCredential._({ - required String accessToken, - }) : super( - providerId: _kProviderId, - signInMethod: _kProviderId, - accessToken: accessToken); + FacebookAuthCredential._({required String accessToken}) + : super( + providerId: _kProviderId, + signInMethod: _kProviderId, + accessToken: accessToken, + ); factory FacebookAuthCredential._credential(String accessToken) { return FacebookAuthCredential._(accessToken: accessToken); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/game_center_auth.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/game_center_auth.dart index 0d7d4171f18b..3486fae3f09e 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/game_center_auth.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/game_center_auth.dart @@ -57,10 +57,7 @@ class GameCenterAuthProvider extends AuthProvider { /// [GameCenterAuthProvider.credential]. class GameCenterAuthCredential extends OAuthCredential { GameCenterAuthCredential._() - : super( - providerId: _kProviderId, - signInMethod: _kProviderId, - ); + : super(providerId: _kProviderId, signInMethod: _kProviderId); factory GameCenterAuthCredential._credential() { return GameCenterAuthCredential._(); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/github_auth.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/github_auth.dart index a420ee2169c2..44cf51e2cafa 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/github_auth.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/github_auth.dart @@ -41,9 +41,7 @@ class GithubAuthProvider extends AuthProvider { /// Create a new [GithubAuthCredential] from a provided [accessToken]; static OAuthCredential credential(String accessToken) { - return GithubAuthCredential._credential( - accessToken, - ); + return GithubAuthCredential._credential(accessToken); } /// This corresponds to the sign-in method identifier. @@ -88,12 +86,12 @@ class GithubAuthProvider extends AuthProvider { /// The auth credential returned from calling /// [GithubAuthProvider.credential]. class GithubAuthCredential extends OAuthCredential { - GithubAuthCredential._({ - required String accessToken, - }) : super( - providerId: _kProviderId, - signInMethod: _kProviderId, - accessToken: accessToken); + GithubAuthCredential._({required String accessToken}) + : super( + providerId: _kProviderId, + signInMethod: _kProviderId, + accessToken: accessToken, + ); factory GithubAuthCredential._credential(String accessToken) { return GithubAuthCredential._(accessToken: accessToken); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/google_auth.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/google_auth.dart index e52dbd013ada..1802dadb13f8 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/google_auth.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/google_auth.dart @@ -40,8 +40,10 @@ class GoogleAuthProvider extends AuthProvider { /// Create a new [GoogleAuthCredential] from a provided [accessToken]. static OAuthCredential credential({String? idToken, String? accessToken}) { - assert(accessToken != null || idToken != null, - 'At least one of ID token and access token is required'); + assert( + accessToken != null || idToken != null, + 'At least one of ID token and access token is required', + ); return GoogleAuthCredential._credential( idToken: idToken, accessToken: accessToken, @@ -90,14 +92,13 @@ class GoogleAuthProvider extends AuthProvider { /// The auth credential returned from calling /// [GoogleAuthProvider.credential]. class GoogleAuthCredential extends OAuthCredential { - GoogleAuthCredential._({ - String? accessToken, - String? idToken, - }) : super( - providerId: _kProviderId, - signInMethod: _kProviderId, - accessToken: accessToken, - idToken: idToken); + GoogleAuthCredential._({String? accessToken, String? idToken}) + : super( + providerId: _kProviderId, + signInMethod: _kProviderId, + accessToken: accessToken, + idToken: idToken, + ); factory GoogleAuthCredential._credential({ String? idToken, diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/oauth.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/oauth.dart index f51328c04b2e..a66e904e22c4 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/oauth.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/oauth.dart @@ -41,9 +41,7 @@ class OAuthProvider extends AuthProvider { /// Sets the OAuth custom parameters to pass in a OAuth request for popup and /// redirect sign-in operations. - OAuthProvider setCustomParameters( - Map customOAuthParameters, - ) { + OAuthProvider setCustomParameters(Map customOAuthParameters) { _parameters = customOAuthParameters; return this; } @@ -84,10 +82,10 @@ class OAuthCredential extends AuthCredential { this.serverAuthCode, this.appleFullPersonName, }) : super( - providerId: providerId, - signInMethod: signInMethod, - accessToken: accessToken, - ); + providerId: providerId, + signInMethod: signInMethod, + accessToken: accessToken, + ); /// The OAuth ID token associated with the credential if it belongs to an /// OIDC provider, such as `google.com`. diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/phone_auth.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/phone_auth.dart index 411e2fc193d2..d8e64631e7ea 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/phone_auth.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/phone_auth.dart @@ -45,20 +45,17 @@ class PhoneAuthProvider extends AuthProvider { /// The auth credential returned from calling /// [PhoneAuthProvider.credential]. class PhoneAuthCredential extends AuthCredential { - PhoneAuthCredential._({ - this.verificationId, - this.smsCode, - int? token, - }) : super( - providerId: _kProviderId, - signInMethod: _kProviderId, - token: token, - ); + PhoneAuthCredential._({this.verificationId, this.smsCode, int? token}) + : super(providerId: _kProviderId, signInMethod: _kProviderId, token: token); factory PhoneAuthCredential._credential( - String verificationId, String smsCode) { + String verificationId, + String smsCode, + ) { return PhoneAuthCredential._( - verificationId: verificationId, smsCode: smsCode); + verificationId: verificationId, + smsCode: smsCode, + ); } factory PhoneAuthCredential._credentialFromToken( diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/play_games_auth.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/play_games_auth.dart index 987aae935453..f2c045c3a78b 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/play_games_auth.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/play_games_auth.dart @@ -25,12 +25,8 @@ class PlayGamesAuthProvider extends AuthProvider { PlayGamesAuthProvider() : super(_kProviderId); /// Create a new [PlayGamesAuthCredential] from a provided [serverAuthCode] - static OAuthCredential credential({ - required String serverAuthCode, - }) { - return PlayGamesAuthCredential._credential( - serverAuthCode: serverAuthCode, - ); + static OAuthCredential credential({required String serverAuthCode}) { + return PlayGamesAuthCredential._credential(serverAuthCode: serverAuthCode); } /// This corresponds to the sign-in method identifier. @@ -63,13 +59,12 @@ class PlayGamesAuthProvider extends AuthProvider { /// The auth credential returned from calling /// [PlayGamesAuthProvider.credential]. class PlayGamesAuthCredential extends OAuthCredential { - PlayGamesAuthCredential._({ - required String serverAuthCode, - }) : super( - providerId: _kProviderId, - signInMethod: _kProviderId, - serverAuthCode: serverAuthCode, - ); + PlayGamesAuthCredential._({required String serverAuthCode}) + : super( + providerId: _kProviderId, + signInMethod: _kProviderId, + serverAuthCode: serverAuthCode, + ); factory PlayGamesAuthCredential._credential({ required String serverAuthCode, diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/twitter_auth.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/twitter_auth.dart index 7408db0a1fe6..06d0fd1ae336 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/twitter_auth.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/twitter_auth.dart @@ -81,14 +81,13 @@ class TwitterAuthProvider extends AuthProvider { /// The auth credential returned from calling /// [TwitterAuthProvider.credential]. class TwitterAuthCredential extends OAuthCredential { - TwitterAuthCredential._({ - required String accessToken, - required String secret, - }) : super( - providerId: _kProviderId, - signInMethod: _kProviderId, - accessToken: accessToken, - secret: secret); + TwitterAuthCredential._({required String accessToken, required String secret}) + : super( + providerId: _kProviderId, + signInMethod: _kProviderId, + accessToken: accessToken, + secret: secret, + ); factory TwitterAuthCredential._credential({ required String accessToken, diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/yahoo_auth.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/yahoo_auth.dart index aa6181591c7a..0d949b5b0821 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/yahoo_auth.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/providers/yahoo_auth.dart @@ -41,9 +41,7 @@ class YahooAuthProvider extends AuthProvider { /// Create a new [YahooAuthCredential] from a provided [accessToken]; static OAuthCredential credential(String accessToken) { - return YahooAuthCredential._credential( - accessToken, - ); + return YahooAuthCredential._credential(accessToken); } /// This corresponds to the sign-in method identifier. @@ -88,12 +86,12 @@ class YahooAuthProvider extends AuthProvider { /// The auth credential returned from calling /// [YahooAuthProvider.credential]. class YahooAuthCredential extends OAuthCredential { - YahooAuthCredential._({ - required String accessToken, - }) : super( - providerId: _kProviderId, - signInMethod: _kProviderId, - accessToken: accessToken); + YahooAuthCredential._({required String accessToken}) + : super( + providerId: _kProviderId, + signInMethod: _kProviderId, + accessToken: accessToken, + ); factory YahooAuthCredential._credential(String accessToken) { return YahooAuthCredential._(accessToken: accessToken); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/types.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/types.dart index 8e4ebd77d467..83cb670ac8f0 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/types.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/types.dart @@ -10,19 +10,16 @@ import 'firebase_auth_exception.dart'; /// Typedef for an automatic phone number resolution. /// /// This handler can only be called on supported Android devices. -typedef PhoneVerificationCompleted = void Function( - PhoneAuthCredential phoneAuthCredential, -); +typedef PhoneVerificationCompleted = + void Function(PhoneAuthCredential phoneAuthCredential); /// Typedef for handling errors via phone number verification. typedef PhoneVerificationFailed = void Function(FirebaseAuthException error); /// Typedef for handling when Firebase sends a SMS code to the provided phone /// number. -typedef PhoneCodeSent = void Function( - String verificationId, - int? forceResendingToken, -); +typedef PhoneCodeSent = + void Function(String verificationId, int? forceResendingToken); /// Typedef for handling automatic phone number timeout resolution. typedef PhoneCodeAutoRetrievalTimeout = void Function(String verificationId); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/user_info.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/user_info.dart index b4936290a156..a491d4f60a18 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/user_info.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/user_info.dart @@ -14,20 +14,20 @@ class UserInfo { @protected UserInfo.fromJson(Map data) - : _data = InternalUserInfo( - uid: data['uid'] as String, - email: data['email'] as String?, - displayName: data['displayName'] as String?, - photoUrl: data['photoUrl'] as String?, - phoneNumber: data['phoneNumber'] as String?, - isAnonymous: data['isAnonymous'] as bool, - isEmailVerified: data['isEmailVerified'] as bool, - providerId: data['providerId'] as String?, - tenantId: data['tenantId'] as String?, - refreshToken: data['refreshToken'] as String?, - creationTimestamp: data['creationTimestamp'] as int?, - lastSignInTimestamp: data['lastSignInTimestamp'] as int?, - ); + : _data = InternalUserInfo( + uid: data['uid'] as String, + email: data['email'] as String?, + displayName: data['displayName'] as String?, + photoUrl: data['photoUrl'] as String?, + phoneNumber: data['phoneNumber'] as String?, + isAnonymous: data['isAnonymous'] as bool, + isEmailVerified: data['isEmailVerified'] as bool, + providerId: data['providerId'] as String?, + tenantId: data['tenantId'] as String?, + refreshToken: data['refreshToken'] as String?, + creationTimestamp: data['creationTimestamp'] as int?, + lastSignInTimestamp: data['lastSignInTimestamp'] as int?, + ); final InternalUserInfo _data; diff --git a/packages/firebase_auth/firebase_auth_platform_interface/pigeons/messages.dart b/packages/firebase_auth/firebase_auth_platform_interface/pigeons/messages.dart index 51398a81f9b1..28a44205ca0c 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/pigeons/messages.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/pigeons/messages.dart @@ -13,9 +13,7 @@ import 'package:pigeon/pigeon.dart'; dartTestOut: 'test/pigeon/test_api.dart', kotlinOut: '../firebase_auth/android/src/main/kotlin/io/flutter/plugins/firebase/auth/GeneratedAndroidFirebaseAuth.g.kt', - kotlinOptions: KotlinOptions( - package: 'io.flutter.plugins.firebase.auth', - ), + kotlinOptions: KotlinOptions(package: 'io.flutter.plugins.firebase.auth'), swiftOut: '../firebase_auth/ios/firebase_auth/Sources/firebase_auth/FirebaseAuthMessages.g.swift', cppHeaderOut: '../firebase_auth/windows/messages.g.h', @@ -25,9 +23,7 @@ import 'package:pigeon/pigeon.dart'; ), ) class InternalMultiFactorSession { - const InternalMultiFactorSession({ - required this.id, - }); + const InternalMultiFactorSession({required this.id}); final String id; } @@ -98,20 +94,14 @@ enum ActionCodeInfoOperation { } class InternalActionCodeInfoData { - const InternalActionCodeInfoData({ - this.email, - this.previousEmail, - }); + const InternalActionCodeInfoData({this.email, this.previousEmail}); final String? email; final String? previousEmail; } class InternalActionCodeInfo { - const InternalActionCodeInfo({ - required this.operation, - required this.data, - }); + const InternalActionCodeInfo({required this.operation, required this.data}); final ActionCodeInfoOperation operation; final InternalActionCodeInfoData data; @@ -286,27 +276,16 @@ class InternalVerifyPhoneNumberRequest { @HostApi(dartHostTestHandler: 'TestFirebaseAuthHostApi') abstract class FirebaseAuthHostApi { @async - String registerIdTokenListener( - AuthPigeonFirebaseApp app, - ); + String registerIdTokenListener(AuthPigeonFirebaseApp app); @async - String registerAuthStateListener( - AuthPigeonFirebaseApp app, - ); + String registerAuthStateListener(AuthPigeonFirebaseApp app); @async - void useEmulator( - AuthPigeonFirebaseApp app, - String host, - int port, - ); + void useEmulator(AuthPigeonFirebaseApp app, String host, int port); @async - void applyActionCode( - AuthPigeonFirebaseApp app, - String code, - ); + void applyActionCode(AuthPigeonFirebaseApp app, String code); @async InternalActionCodeInfo checkActionCode( @@ -329,9 +308,7 @@ abstract class FirebaseAuthHostApi { ); @async - InternalUserCredential signInAnonymously( - AuthPigeonFirebaseApp app, - ); + InternalUserCredential signInAnonymously(AuthPigeonFirebaseApp app); @async InternalUserCredential signInWithCredential( @@ -366,9 +343,7 @@ abstract class FirebaseAuthHostApi { ); @async - void signOut( - AuthPigeonFirebaseApp app, - ); + void signOut(AuthPigeonFirebaseApp app); @async List fetchSignInMethodsForEmail( @@ -391,10 +366,7 @@ abstract class FirebaseAuthHostApi { ); @async - String setLanguageCode( - AuthPigeonFirebaseApp app, - String? languageCode, - ); + String setLanguageCode(AuthPigeonFirebaseApp app, String? languageCode); /// Applies auth settings. When [InternalFirebaseAuthSettings.migrateCurrentUser] /// is true and a user was migrated, returns that user so Dart can reconcile @@ -406,10 +378,7 @@ abstract class FirebaseAuthHostApi { ); @async - String verifyPasswordResetCode( - AuthPigeonFirebaseApp app, - String code, - ); + String verifyPasswordResetCode(AuthPigeonFirebaseApp app, String code); @async String verifyPhoneNumber( @@ -423,15 +392,10 @@ abstract class FirebaseAuthHostApi { ); @async - void revokeAccessToken( - AuthPigeonFirebaseApp app, - String accessToken, - ); + void revokeAccessToken(AuthPigeonFirebaseApp app, String accessToken); @async - void initializeRecaptchaConfig( - AuthPigeonFirebaseApp app, - ); + void initializeRecaptchaConfig(AuthPigeonFirebaseApp app); } class InternalIdTokenResult { @@ -471,9 +435,7 @@ class InternalUserProfile { @HostApi(dartHostTestHandler: 'TestFirebaseAuthUserHostApi') abstract class FirebaseAuthUserHostApi { @async - void delete( - AuthPigeonFirebaseApp app, - ); + void delete(AuthPigeonFirebaseApp app); @async InternalIdTokenResult getIdToken( @@ -506,9 +468,7 @@ abstract class FirebaseAuthUserHostApi { ); @async - InternalUserDetails reload( - AuthPigeonFirebaseApp app, - ); + InternalUserDetails reload(AuthPigeonFirebaseApp app); @async void sendEmailVerification( @@ -517,16 +477,10 @@ abstract class FirebaseAuthUserHostApi { ); @async - InternalUserCredential unlink( - AuthPigeonFirebaseApp app, - String providerId, - ); + InternalUserCredential unlink(AuthPigeonFirebaseApp app, String providerId); @async - InternalUserDetails updateEmail( - AuthPigeonFirebaseApp app, - String newEmail, - ); + InternalUserDetails updateEmail(AuthPigeonFirebaseApp app, String newEmail); @async InternalUserDetails updatePassword( @@ -571,20 +525,13 @@ abstract class MultiFactorUserHostApi { ); @async - InternalMultiFactorSession getSession( - AuthPigeonFirebaseApp app, - ); + InternalMultiFactorSession getSession(AuthPigeonFirebaseApp app); @async - void unenroll( - AuthPigeonFirebaseApp app, - String factorUid, - ); + void unenroll(AuthPigeonFirebaseApp app, String factorUid); @async - List getEnrolledFactors( - AuthPigeonFirebaseApp app, - ); + List getEnrolledFactors(AuthPigeonFirebaseApp app); } @HostApi(dartHostTestHandler: 'TestMultiFactoResolverHostApi') @@ -616,21 +563,13 @@ class InternalTotpSecret { @HostApi(dartHostTestHandler: 'TestMultiFactoResolverHostApi') abstract class MultiFactorTotpHostApi { @async - InternalTotpSecret generateSecret( - String sessionId, - ); + InternalTotpSecret generateSecret(String sessionId); @async - String getAssertionForEnrollment( - String secretKey, - String oneTimePassword, - ); + String getAssertionForEnrollment(String secretKey, String oneTimePassword); @async - String getAssertionForSignIn( - String enrollmentId, - String oneTimePassword, - ); + String getAssertionForSignIn(String enrollmentId, String oneTimePassword); } @HostApi(dartHostTestHandler: 'TestMultiFactoResolverHostApi') @@ -643,10 +582,7 @@ abstract class MultiFactorTotpSecretHostApi { ); @async - void openInOtpApp( - String secretKey, - String qrCodeUrl, - ); + void openInOtpApp(String secretKey, String qrCodeUrl); } /// Only used to generate the object interface that are use outside of the Pigeon interface diff --git a/packages/firebase_auth/firebase_auth_platform_interface/pubspec.yaml b/packages/firebase_auth/firebase_auth_platform_interface/pubspec.yaml index d528978f4846..680bce022f87 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/pubspec.yaml +++ b/packages/firebase_auth/firebase_auth_platform_interface/pubspec.yaml @@ -8,8 +8,8 @@ version: 9.0.7 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.16.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/action_code_info_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/action_code_info_test.dart index 424a27515b21..3531e82df70b 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/action_code_info_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/action_code_info_test.dart @@ -10,12 +10,16 @@ void main() { const kMockOperation = ActionCodeInfoOperation.verifyEmail; const String kMockEmail = 'test@test.com'; const String kMockPreviousEmail = 'previous@test.com'; - final kMockData = - ActionCodeInfoData(email: kMockEmail, previousEmail: kMockPreviousEmail); + final kMockData = ActionCodeInfoData( + email: kMockEmail, + previousEmail: kMockPreviousEmail, + ); group('$ActionCodeInfo', () { - ActionCodeInfo actionCodeInfo = - ActionCodeInfo(operation: kMockOperation, data: kMockData); + ActionCodeInfo actionCodeInfo = ActionCodeInfo( + operation: kMockOperation, + data: kMockData, + ); group('Constructor', () { test('returns an instance of [ActionCodeInfo]', () { expect(actionCodeInfo, isA()); @@ -27,29 +31,32 @@ void main() { expect(actionCodeInfo.data, isA>()); expect(actionCodeInfo.data['email'], equals(kMockEmail)); expect( - actionCodeInfo.data['previousEmail'], equals(kMockPreviousEmail)); + actionCodeInfo.data['previousEmail'], + equals(kMockPreviousEmail), + ); }); test('handles email is null', () { ActionCodeInfo testActionCodeInfo = ActionCodeInfo( - operation: kMockOperation, - data: ActionCodeInfoData( - email: null, - previousEmail: kMockPreviousEmail, - )); + operation: kMockOperation, + data: ActionCodeInfoData( + email: null, + previousEmail: kMockPreviousEmail, + ), + ); expect(testActionCodeInfo.data, isA>()); expect(testActionCodeInfo.data['email'], isNull); - expect(testActionCodeInfo.data['previousEmail'], - equals(kMockPreviousEmail)); + expect( + testActionCodeInfo.data['previousEmail'], + equals(kMockPreviousEmail), + ); }); test('handles previousEmail is null', () { ActionCodeInfo testActionCodeInfo = ActionCodeInfo( - operation: kMockOperation, - data: ActionCodeInfoData( - email: kMockEmail, - previousEmail: null, - )); + operation: kMockOperation, + data: ActionCodeInfoData(email: kMockEmail, previousEmail: null), + ); expect(testActionCodeInfo.data, isA>()); expect(testActionCodeInfo.data['email'], equals(kMockEmail)); expect(testActionCodeInfo.data['previousEmail'], isNull); @@ -59,54 +66,75 @@ void main() { group('operation', () { test('returns an instance of [ActionCodeInfoOperation]', () { expect(actionCodeInfo.operation, isA()); - expect(actionCodeInfo.operation, - equals(ActionCodeInfoOperation.verifyEmail)); + expect( + actionCodeInfo.operation, + equals(ActionCodeInfoOperation.verifyEmail), + ); }); test('returns operation type `emailSignIn`', () { ActionCodeInfo testActionCodeInfo = ActionCodeInfo( - operation: ActionCodeInfoOperation.emailSignIn, data: kMockData); + operation: ActionCodeInfoOperation.emailSignIn, + data: kMockData, + ); expect(testActionCodeInfo.operation, isA()); - expect(testActionCodeInfo.operation, - equals(ActionCodeInfoOperation.emailSignIn)); + expect( + testActionCodeInfo.operation, + equals(ActionCodeInfoOperation.emailSignIn), + ); }); test('returns operation type `passwordReset`', () { ActionCodeInfo testActionCodeInfo = ActionCodeInfo( - operation: ActionCodeInfoOperation.passwordReset, data: kMockData); + operation: ActionCodeInfoOperation.passwordReset, + data: kMockData, + ); expect(testActionCodeInfo.operation, isA()); - expect(testActionCodeInfo.operation, - equals(ActionCodeInfoOperation.passwordReset)); + expect( + testActionCodeInfo.operation, + equals(ActionCodeInfoOperation.passwordReset), + ); }); test('returns operation type `recoverEmail`', () { ActionCodeInfo testActionCodeInfo = ActionCodeInfo( - operation: ActionCodeInfoOperation.recoverEmail, data: kMockData); + operation: ActionCodeInfoOperation.recoverEmail, + data: kMockData, + ); expect(testActionCodeInfo.operation, isA()); - expect(testActionCodeInfo.operation, - equals(ActionCodeInfoOperation.recoverEmail)); + expect( + testActionCodeInfo.operation, + equals(ActionCodeInfoOperation.recoverEmail), + ); }); test('returns operation type `verifyAndChangeEmail`', () { ActionCodeInfo testActionCodeInfo = ActionCodeInfo( - operation: ActionCodeInfoOperation.verifyAndChangeEmail, - data: kMockData); + operation: ActionCodeInfoOperation.verifyAndChangeEmail, + data: kMockData, + ); expect(testActionCodeInfo.operation, isA()); - expect(testActionCodeInfo.operation, - equals(ActionCodeInfoOperation.verifyAndChangeEmail)); + expect( + testActionCodeInfo.operation, + equals(ActionCodeInfoOperation.verifyAndChangeEmail), + ); }); test('returns operation type `verifyEmail`', () { ActionCodeInfo testActionCodeInfo = ActionCodeInfo( - operation: ActionCodeInfoOperation.verifyEmail, data: kMockData); + operation: ActionCodeInfoOperation.verifyEmail, + data: kMockData, + ); expect(testActionCodeInfo.operation, isA()); - expect(testActionCodeInfo.operation, - equals(ActionCodeInfoOperation.verifyEmail)); + expect( + testActionCodeInfo.operation, + equals(ActionCodeInfoOperation.verifyEmail), + ); }); }); }); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/action_code_settings_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/action_code_settings_test.dart index d243a4f7b355..4209a44b0327 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/action_code_settings_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/action_code_settings_test.dart @@ -18,13 +18,14 @@ void main() { group('$ActionCodeSettings', () { ActionCodeSettings actionCodeSettings = ActionCodeSettings( - androidPackageName: kMockPackageName, - androidMinimumVersion: kMockMinimumVersion, - androidInstallApp: kMockInstallApp, - linkDomain: kMockLinkDomain, - handleCodeInApp: kMockHandleCodeInApp, - iOSBundleId: kMockBundleId, - url: kMockUrl); + androidPackageName: kMockPackageName, + androidMinimumVersion: kMockMinimumVersion, + androidInstallApp: kMockInstallApp, + linkDomain: kMockLinkDomain, + handleCodeInApp: kMockHandleCodeInApp, + iOSBundleId: kMockBundleId, + url: kMockUrl, + ); group('Constructor', () { test('returns an instance of [ActionCodeInfo]', () { @@ -32,10 +33,14 @@ void main() { expect(actionCodeSettings.url, equals(kMockUrl)); expect(actionCodeSettings.linkDomain, equals(kMockLinkDomain)); expect( - actionCodeSettings.handleCodeInApp, equals(kMockHandleCodeInApp)); + actionCodeSettings.handleCodeInApp, + equals(kMockHandleCodeInApp), + ); expect(actionCodeSettings.androidPackageName, equals(kMockPackageName)); - expect(actionCodeSettings.androidMinimumVersion, - equals(kMockMinimumVersion)); + expect( + actionCodeSettings.androidMinimumVersion, + equals(kMockMinimumVersion), + ); expect(actionCodeSettings.androidInstallApp, equals(kMockInstallApp)); expect(actionCodeSettings.iOSBundleId, equals(kMockBundleId)); }); @@ -52,14 +57,18 @@ void main() { expect(result['android']['packageName'], equals(kMockPackageName)); expect(result['android']['installApp'], equals(kMockInstallApp)); expect( - result['android']['minimumVersion'], equals(kMockMinimumVersion)); + result['android']['minimumVersion'], + equals(kMockMinimumVersion), + ); expect(result['iOS']['bundleId'], equals(kMockBundleId)); }); }); test('toString', () { - expect(actionCodeSettings.toString(), - equals('$ActionCodeSettings(${actionCodeSettings.asMap})')); + expect( + actionCodeSettings.toString(), + equals('$ActionCodeSettings(${actionCodeSettings.asMap})'), + ); }); }); }); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/additional_user_info_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/additional_user_info_test.dart index 52e5a3bbbcff..8869c3a5a892 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/additional_user_info_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/additional_user_info_test.dart @@ -10,7 +10,7 @@ void main() { const bool kMockIsNewUser = true; const String kMockDisplayName = 'test-name'; final Map kMockProfile = { - 'displayName': kMockDisplayName + 'displayName': kMockDisplayName, }; const String kMockProviderId = 'password'; const String kMockUsername = 'username'; @@ -32,8 +32,10 @@ void main() { expect(additionalUserInfo.isNewUser, equals(kMockIsNewUser)); expect(additionalUserInfo.username, equals(kMockUsername)); expect(additionalUserInfo.profile, equals(kMockProfile)); - expect(additionalUserInfo.authorizationCode, - equals(kMockAuthorizationCode)); + expect( + additionalUserInfo.authorizationCode, + equals(kMockAuthorizationCode), + ); }); }); @@ -42,9 +44,11 @@ void main() { final result = additionalUserInfo.toString(); expect(result, isA()); expect( - result, - equals( - '$AdditionalUserInfo(isNewUser: $kMockIsNewUser, profile: $kMockProfile, providerId: $kMockProviderId, username: $kMockUsername, authorizationCode: $kMockAuthorizationCode)')); + result, + equals( + '$AdditionalUserInfo(isNewUser: $kMockIsNewUser, profile: $kMockProfile, providerId: $kMockProviderId, username: $kMockUsername, authorizationCode: $kMockAuthorizationCode)', + ), + ); }); }); }); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/auth_credential_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/auth_credential_test.dart index c05ca224cb77..d6adb458dde1 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/auth_credential_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/auth_credential_test.dart @@ -15,9 +15,10 @@ void main() { setUpAll(() { authCredential = const AuthCredential( - providerId: kMockProviderId, - signInMethod: kMockSignInMethod, - token: kMockToken); + providerId: kMockProviderId, + signInMethod: kMockSignInMethod, + token: kMockToken, + ); }); group('Constructor', () { diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/auth_provider_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/auth_provider_test.dart index 9bbb5a6b98ab..b751c490da35 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/auth_provider_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/auth_provider_test.dart @@ -19,8 +19,10 @@ void main() { group('toString', () { test('returns correct string when providerId is set', () { TestAuthProvider authProvider = TestAuthProvider(kMockProviderId); - expect(authProvider.toString(), - equals('AuthProvider(providerId: $kMockProviderId)')); + expect( + authProvider.toString(), + equals('AuthProvider(providerId: $kMockProviderId)'), + ); }); }); }); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/auth_settings_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/auth_settings_test.dart index 236d7c566f4f..8551f90afe27 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/auth_settings_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/auth_settings_test.dart @@ -17,13 +17,15 @@ void main() { test('sets appVerificationDisabledForTesting with given value', () { // set appVerificationDisabledForTesting to true - AuthSettings authSettings = - const AuthSettings(appVerificationDisabledForTesting: true); + AuthSettings authSettings = const AuthSettings( + appVerificationDisabledForTesting: true, + ); expect(authSettings.appVerificationDisabledForTesting, isTrue); // set appVerificationDisabledForTesting to false - authSettings = - const AuthSettings(appVerificationDisabledForTesting: false); + authSettings = const AuthSettings( + appVerificationDisabledForTesting: false, + ); expect(authSettings.appVerificationDisabledForTesting, isFalse); }); }); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/id_token_result_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/id_token_result_test.dart index 9a13f6b58be6..b9151eb539ca 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/id_token_result_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/id_token_result_test.dart @@ -14,34 +14,41 @@ void main() { const int kMockExpirationTimestamp = 1234566; const int kMockAuthTimestamp = 1234567; const int kMockIssuedAtTimestamp = 12345678; - final Map kMockClaims = { - 'claim1': 'value1', - }; + final Map kMockClaims = {'claim1': 'value1'}; final kMockData = InternalIdTokenResult( - claims: kMockClaims, - issuedAtTimestamp: kMockIssuedAtTimestamp, - authTimestamp: kMockAuthTimestamp, - expirationTimestamp: kMockExpirationTimestamp, - signInProvider: kMockSignInProvider, - signInSecondFactor: kMockSignInSecondFactor, - token: kMockToken); + claims: kMockClaims, + issuedAtTimestamp: kMockIssuedAtTimestamp, + authTimestamp: kMockAuthTimestamp, + expirationTimestamp: kMockExpirationTimestamp, + signInProvider: kMockSignInProvider, + signInSecondFactor: kMockSignInSecondFactor, + token: kMockToken, + ); group('$IdTokenResult', () { final idTokenResult = IdTokenResult(kMockData); group('Constructor', () { test('returns an instance of [IdTokenResult]', () { expect(idTokenResult, isA()); - expect(idTokenResult.authTime!.millisecondsSinceEpoch, - equals(kMockAuthTimestamp)); + expect( + idTokenResult.authTime!.millisecondsSinceEpoch, + equals(kMockAuthTimestamp), + ); expect(idTokenResult.claims, equals(kMockClaims)); - expect(idTokenResult.expirationTime!.millisecondsSinceEpoch, - equals(kMockExpirationTimestamp)); - expect(idTokenResult.issuedAtTime!.millisecondsSinceEpoch, - equals(kMockIssuedAtTimestamp)); + expect( + idTokenResult.expirationTime!.millisecondsSinceEpoch, + equals(kMockExpirationTimestamp), + ); + expect( + idTokenResult.issuedAtTime!.millisecondsSinceEpoch, + equals(kMockIssuedAtTimestamp), + ); expect(idTokenResult.signInProvider, equals(kMockSignInProvider)); expect( - idTokenResult.signInSecondFactor, equals(kMockSignInSecondFactor)); + idTokenResult.signInSecondFactor, + equals(kMockSignInSecondFactor), + ); expect(idTokenResult.token, equals(kMockToken)); }); }); @@ -53,12 +60,13 @@ void main() { test('returns null when data[claims] is null', () { final kMockData = InternalIdTokenResult( - issuedAtTimestamp: kMockIssuedAtTimestamp, - authTimestamp: kMockAuthTimestamp, - expirationTimestamp: kMockExpirationTimestamp, - signInProvider: kMockSignInProvider, - signInSecondFactor: kMockSignInSecondFactor, - token: kMockToken); + issuedAtTimestamp: kMockIssuedAtTimestamp, + authTimestamp: kMockAuthTimestamp, + expirationTimestamp: kMockExpirationTimestamp, + signInProvider: kMockSignInProvider, + signInSecondFactor: kMockSignInSecondFactor, + token: kMockToken, + ); final testIdTokenResult = IdTokenResult(kMockData); expect(testIdTokenResult.claims, isNull); @@ -66,8 +74,10 @@ void main() { }); test('toString()', () { - expect(idTokenResult.toString(), - '$IdTokenResult(authTime: ${idTokenResult.authTime}, claims: $kMockClaims, expirationTime: ${idTokenResult.expirationTime}, issuedAtTime: ${idTokenResult.issuedAtTime}, signInProvider: $kMockSignInProvider, signInSecondFactor: $kMockSignInSecondFactor, token: $kMockToken)'); + expect( + idTokenResult.toString(), + '$IdTokenResult(authTime: ${idTokenResult.authTime}, claims: $kMockClaims, expirationTime: ${idTokenResult.expirationTime}, issuedAtTime: ${idTokenResult.issuedAtTime}, signInProvider: $kMockSignInProvider, signInSecondFactor: $kMockSignInSecondFactor, token: $kMockToken)', + ); }); }); } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/method_channel_firebase_auth_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/method_channel_firebase_auth_test.dart index 36a48ac12ed4..11b0d2b95461 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/method_channel_firebase_auth_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/method_channel_firebase_auth_test.dart @@ -20,19 +20,21 @@ void main() { }); group('setSettings()', () { - test('throws if migrateCurrentUser is set without a userAccessGroup', - () async { - await expectLater( - () => auth.setSettings(migrateCurrentUser: true), - throwsA( - isA().having( - (e) => e.message, - 'message', - contains('userAccessGroup'), + test( + 'throws if migrateCurrentUser is set without a userAccessGroup', + () async { + await expectLater( + () => auth.setSettings(migrateCurrentUser: true), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('userAccessGroup'), + ), ), - ), - ); - }); + ); + }, + ); test('throws if only one of phoneNumber & smsCode is set', () async { await expectLater( diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/method_channel_user_credential_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/method_channel_user_credential_test.dart index 47fcbbd849d5..043111552c87 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/method_channel_user_credential_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/method_channel_user_credential_test.dart @@ -113,35 +113,45 @@ void main() { test('set additionalUserInfo to null', () { userData.additionalUserInfo = null; - MethodChannelUserCredential testUser = - MethodChannelUserCredential(auth, userData); + MethodChannelUserCredential testUser = MethodChannelUserCredential( + auth, + userData, + ); expect(testUser.additionalUserInfo, isNull); }); test('set additionalUserInfo.profile to empty map', () { userData.additionalUserInfo?.profile = null; - MethodChannelUserCredential testUser = - MethodChannelUserCredential(auth, userData); + MethodChannelUserCredential testUser = MethodChannelUserCredential( + auth, + userData, + ); expect(testUser.additionalUserInfo, isA()); expect( - testUser.additionalUserInfo!.profile, isA>()); + testUser.additionalUserInfo!.profile, + isA>(), + ); expect(testUser.additionalUserInfo!.profile, isEmpty); }); test('set authCredential to null', () { userData.credential = null; - MethodChannelUserCredential testUser = - MethodChannelUserCredential(auth, userData); + MethodChannelUserCredential testUser = MethodChannelUserCredential( + auth, + userData, + ); expect(testUser.credential, isNull); }); test('set user to null', () { userData.user = null; - MethodChannelUserCredential testUser = - MethodChannelUserCredential(auth, userData); + MethodChannelUserCredential testUser = MethodChannelUserCredential( + auth, + userData, + ); expect(testUser.user, isNull); }); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/utils_tests/exception_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/utils_tests/exception_test.dart index 5669b1e6aa9e..7a3b5de62a25 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/utils_tests/exception_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/utils_tests/exception_test.dart @@ -19,37 +19,53 @@ void main() { ); }); - test('should catch a [PlatformException] and throw a [FirebaseException]', - () async { - PlatformException platformException = PlatformException(code: 'UNKNOWN'); - - expect( - () => convertPlatformException(platformException, StackTrace.empty), - throwsA( - isA().having((e) => e.code, 'code', 'unknown'), - ), - ); - }); - test( - 'should catch a [PlatformException] and throw a [FirebaseException] with the correct message', - () async { - PlatformException platformException = PlatformException( - code: 'UNKNOWN', - message: - 'An internal error has occurred. [ BLOCKING_FUNCTION_ERROR_RESPONSE:HTTP Cloud Function returned an error: {"error":{"details":"The user is not allowed to log in","message":"","status":"PERMISSION_DENIED"}} ]', - ); + 'should catch a [PlatformException] and throw a [FirebaseException]', + () async { + PlatformException platformException = PlatformException( + code: 'UNKNOWN', + ); + + expect( + () => convertPlatformException(platformException, StackTrace.empty), + throwsA( + isA().having( + (e) => e.code, + 'code', + 'unknown', + ), + ), + ); + }, + ); - expect( - () => convertPlatformException(platformException, StackTrace.empty), - throwsA( - isA() - .having((e) => e.code, 'code', 'blocking-function-error-response') - .having((e) => e.message, 'message', - '{"error":{"details":"The user is not allowed to log in","message":"","status":"PERMISSION_DENIED"}}'), - ), - ); - }); + test( + 'should catch a [PlatformException] and throw a [FirebaseException] with the correct message', + () async { + PlatformException platformException = PlatformException( + code: 'UNKNOWN', + message: + 'An internal error has occurred. [ BLOCKING_FUNCTION_ERROR_RESPONSE:HTTP Cloud Function returned an error: {"error":{"details":"The user is not allowed to log in","message":"","status":"PERMISSION_DENIED"}} ]', + ); + + expect( + () => convertPlatformException(platformException, StackTrace.empty), + throwsA( + isA() + .having( + (e) => e.code, + 'code', + 'blocking-function-error-response', + ) + .having( + (e) => e.message, + 'message', + '{"error":{"details":"The user is not allowed to log in","message":"","status":"PERMISSION_DENIED"}}', + ), + ), + ); + }, + ); test('should catch a [PlatformException] with non-Map details', () async { PlatformException platformException = PlatformException( @@ -81,9 +97,9 @@ void main() { details: 'Native error details', ); - FirebaseAuthException result = platformExceptionToFirebaseAuthException( - platformException, - ) as FirebaseAuthException; + FirebaseAuthException result = + platformExceptionToFirebaseAuthException(platformException) + as FirebaseAuthException; expect(result.code, equals('internal-error')); expect(result.message, equals('An internal error has occurred')); @@ -99,16 +115,19 @@ void main() { ); PlatformException platformException = PlatformException( - code: 'unknown', - message: 'PlatformException Message', - details: { - 'additionalData': {'authCredential': authCredential.asMap()} - }); - - FirebaseAuthException result = platformExceptionToFirebaseAuthException( - platformException, - fromPigeon: false, - ) as FirebaseAuthException; + code: 'unknown', + message: 'PlatformException Message', + details: { + 'additionalData': {'authCredential': authCredential.asMap()}, + }, + ); + + FirebaseAuthException result = + platformExceptionToFirebaseAuthException( + platformException, + fromPigeon: false, + ) + as FirebaseAuthException; expect(result.code, equals('unknown')); expect(result.message, equals('PlatformException Message')); expect(result.email, isNull); @@ -124,22 +143,29 @@ void main() { test('sets correct values from additionalData', () { AuthCredential authCredential = EmailAuthProvider.credential( - email: 'test@email.com', password: 'testPassword'); - - PlatformException platformException = - PlatformException(code: 'native', message: 'a message', details: { - 'code': 'A Known Code', - 'message': 'A Known Message', - 'additionalData': { - 'email': 'test@email.com', - 'authCredential': authCredential.asMap(), - } - }); - - FirebaseAuthException result = platformExceptionToFirebaseAuthException( - platformException, - fromPigeon: false, - ) as FirebaseAuthException; + email: 'test@email.com', + password: 'testPassword', + ); + + PlatformException platformException = PlatformException( + code: 'native', + message: 'a message', + details: { + 'code': 'A Known Code', + 'message': 'A Known Message', + 'additionalData': { + 'email': 'test@email.com', + 'authCredential': authCredential.asMap(), + }, + }, + ); + + FirebaseAuthException result = + platformExceptionToFirebaseAuthException( + platformException, + fromPigeon: false, + ) + as FirebaseAuthException; expect(result.code, equals('A Known Code')); expect(result.message, equals('A Known Message')); expect(result.email, 'test@email.com'); @@ -148,7 +174,9 @@ void main() { expect(result.credential!.providerId, equals(authCredential.providerId)); expect(result.credential!.token, equals(authCredential.token)); expect( - result.credential!.signInMethod, equals(authCredential.signInMethod)); + result.credential!.signInMethod, + equals(authCredential.signInMethod), + ); }); test('details = null', () { @@ -157,10 +185,12 @@ void main() { message: 'a message', ); - FirebaseAuthException result = platformExceptionToFirebaseAuthException( - platformException, - fromPigeon: false, - ) as FirebaseAuthException; + FirebaseAuthException result = + platformExceptionToFirebaseAuthException( + platformException, + fromPigeon: false, + ) + as FirebaseAuthException; expect(result.code, equals('unknown')); expect(result.message, equals('a message')); expect(result.email, null); @@ -170,14 +200,17 @@ void main() { test('additionalData = null', () { PlatformException platformException = PlatformException( - code: 'native', - message: 'a message', - details: {'additionalData': null}); - - FirebaseAuthException result = platformExceptionToFirebaseAuthException( - platformException, - fromPigeon: false, - ) as FirebaseAuthException; + code: 'native', + message: 'a message', + details: {'additionalData': null}, + ); + + FirebaseAuthException result = + platformExceptionToFirebaseAuthException( + platformException, + fromPigeon: false, + ) + as FirebaseAuthException; expect(result.code, equals('unknown')); expect(result.message, equals('a message')); expect(result.email, isNull); @@ -192,14 +225,16 @@ void main() { details: { 'code': 'A Known Code', 'message': 'A Known Message', - 'additionalData': {'email': 'test@email.com'} + 'additionalData': {'email': 'test@email.com'}, }, ); - FirebaseAuthException result = platformExceptionToFirebaseAuthException( - platformException, - fromPigeon: false, - ) as FirebaseAuthException; + FirebaseAuthException result = + platformExceptionToFirebaseAuthException( + platformException, + fromPigeon: false, + ) + as FirebaseAuthException; expect(result.code, equals('A Known Code')); expect(result.message, equals('A Known Message')); expect(result.email, 'test@email.com'); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/utils_tests/phone_auth_callbacks_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/utils_tests/phone_auth_callbacks_test.dart index d57a2ff08632..5befe5d32cf8 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/utils_tests/phone_auth_callbacks_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/utils_tests/phone_auth_callbacks_test.dart @@ -15,22 +15,26 @@ void main() { final PhoneVerificationFailed verificationFailed = (FirebaseAuthException authException) {}; - final PhoneCodeSent codeSent = ( - String verificationId, [ - int? forceResendingToken, - ]) async {}; + final PhoneCodeSent codeSent = + (String verificationId, [int? forceResendingToken]) async {}; final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout = (String verificationId) {}; - final callbacks = PhoneAuthCallbacks(verificationCompleted, - verificationFailed, codeSent, codeAutoRetrievalTimeout); + final callbacks = PhoneAuthCallbacks( + verificationCompleted, + verificationFailed, + codeSent, + codeAutoRetrievalTimeout, + ); expect(callbacks, isA()); expect(callbacks.verificationCompleted, isA()); expect(callbacks.verificationFailed, isA()); expect(callbacks.codeSent, isA()); - expect(callbacks.codeAutoRetrievalTimeout, - isA()); + expect( + callbacks.codeAutoRetrievalTimeout, + isA(), + ); }); } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/mock.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/mock.dart index 99b0b6c123d3..62782d1cb1c3 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/mock.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/mock.dart @@ -24,23 +24,21 @@ void setupFirebaseAuthMocks([Callback? customHandlers]) { setupFirebaseCoreMocks(); } -void handleEventChannel( - final String name, [ - List? log, -]) { +void handleEventChannel(final String name, [List? log]) { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(MethodChannel(name), - (MethodCall methodCall) async { - log?.add(methodCall); - switch (methodCall.method) { - case 'listen': - break; - case 'cancel': - default: + .setMockMethodCallHandler(MethodChannel(name), ( + MethodCall methodCall, + ) async { + log?.add(methodCall); + switch (methodCall.method) { + case 'listen': + break; + case 'cancel': + default: + return null; + } return null; - } - return null; - }); + }); } Future injectEventChannelResponse( @@ -49,31 +47,32 @@ Future injectEventChannelResponse( ) async { await TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .handlePlatformMessage( - channelName, - MethodChannelFirebaseAuth.channel.codec.encodeSuccessEnvelope(event), - (_) {}, - ); + channelName, + MethodChannelFirebaseAuth.channel.codec.encodeSuccessEnvelope(event), + (_) {}, + ); } void handleMethodCall(MethodCallCallback methodCallCallback) => TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(MethodChannelFirebaseAuth.channel, - (call) async { - return await methodCallCallback(call); - }); + .setMockMethodCallHandler(MethodChannelFirebaseAuth.channel, ( + call, + ) async { + return await methodCallCallback(call); + }); Future simulateEvent(String name, Map? user) async { await TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .handlePlatformMessage( - MethodChannelFirebaseAuth.channel.name, - MethodChannelFirebaseAuth.channel.codec.encodeMethodCall( - MethodCall( - name, - {'user': user, 'appName': defaultFirebaseAppName}, - ), - ), - (_) {}, - ); + MethodChannelFirebaseAuth.channel.name, + MethodChannelFirebaseAuth.channel.codec.encodeMethodCall( + MethodCall(name, { + 'user': user, + 'appName': defaultFirebaseAppName, + }), + ), + (_) {}, + ); } Future testExceptionHandling( diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/pigeon/test_api.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/pigeon/test_api.dart index bebd600ae4f2..cb438d50d009 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/pigeon/test_api.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/pigeon/test_api.dart @@ -149,59 +149,97 @@ abstract class TestFirebaseAuthHostApi { Future applyActionCode(AuthPigeonFirebaseApp app, String code); Future checkActionCode( - AuthPigeonFirebaseApp app, String code); + AuthPigeonFirebaseApp app, + String code, + ); Future confirmPasswordReset( - AuthPigeonFirebaseApp app, String code, String newPassword); + AuthPigeonFirebaseApp app, + String code, + String newPassword, + ); Future createUserWithEmailAndPassword( - AuthPigeonFirebaseApp app, String email, String password); + AuthPigeonFirebaseApp app, + String email, + String password, + ); Future signInAnonymously(AuthPigeonFirebaseApp app); Future signInWithCredential( - AuthPigeonFirebaseApp app, Map input); + AuthPigeonFirebaseApp app, + Map input, + ); Future signInWithCustomToken( - AuthPigeonFirebaseApp app, String token); + AuthPigeonFirebaseApp app, + String token, + ); Future signInWithEmailAndPassword( - AuthPigeonFirebaseApp app, String email, String password); + AuthPigeonFirebaseApp app, + String email, + String password, + ); Future signInWithEmailLink( - AuthPigeonFirebaseApp app, String email, String emailLink); + AuthPigeonFirebaseApp app, + String email, + String emailLink, + ); Future signInWithProvider( - AuthPigeonFirebaseApp app, InternalSignInProvider signInProvider); + AuthPigeonFirebaseApp app, + InternalSignInProvider signInProvider, + ); Future signOut(AuthPigeonFirebaseApp app); Future> fetchSignInMethodsForEmail( - AuthPigeonFirebaseApp app, String email); - - Future sendPasswordResetEmail(AuthPigeonFirebaseApp app, String email, - InternalActionCodeSettings? actionCodeSettings); - - Future sendSignInLinkToEmail(AuthPigeonFirebaseApp app, String email, - InternalActionCodeSettings actionCodeSettings); + AuthPigeonFirebaseApp app, + String email, + ); + + Future sendPasswordResetEmail( + AuthPigeonFirebaseApp app, + String email, + InternalActionCodeSettings? actionCodeSettings, + ); + + Future sendSignInLinkToEmail( + AuthPigeonFirebaseApp app, + String email, + InternalActionCodeSettings actionCodeSettings, + ); Future setLanguageCode( - AuthPigeonFirebaseApp app, String? languageCode); + AuthPigeonFirebaseApp app, + String? languageCode, + ); /// Applies auth settings. When [InternalFirebaseAuthSettings.migrateCurrentUser] /// is true and a user was migrated, returns that user so Dart can reconcile /// [currentUser] before auth-state events arrive. Otherwise returns null. Future setSettings( - AuthPigeonFirebaseApp app, InternalFirebaseAuthSettings settings); + AuthPigeonFirebaseApp app, + InternalFirebaseAuthSettings settings, + ); Future verifyPasswordResetCode( - AuthPigeonFirebaseApp app, String code); + AuthPigeonFirebaseApp app, + String code, + ); Future verifyPhoneNumber( - AuthPigeonFirebaseApp app, InternalVerifyPhoneNumberRequest request); + AuthPigeonFirebaseApp app, + InternalVerifyPhoneNumberRequest request, + ); Future revokeTokenWithAuthorizationCode( - AuthPigeonFirebaseApp app, String authorizationCode); + AuthPigeonFirebaseApp app, + String authorizationCode, + ); Future revokeAccessToken(AuthPigeonFirebaseApp app, String accessToken); @@ -212,703 +250,881 @@ abstract class TestFirebaseAuthHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.registerIdTokenListener$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.registerIdTokenListener$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - try { - final String output = await api.registerIdTokenListener(arg_app); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + try { + final String output = await api.registerIdTokenListener( + arg_app, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.registerAuthStateListener$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.registerAuthStateListener$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - try { - final String output = await api.registerAuthStateListener(arg_app); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + try { + final String output = await api.registerAuthStateListener( + arg_app, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.useEmulator$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.useEmulator$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_host = args[1]! as String; - final int arg_port = args[2]! as int; - try { - await api.useEmulator(arg_app, arg_host, arg_port); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_host = args[1]! as String; + final int arg_port = args[2]! as int; + try { + await api.useEmulator(arg_app, arg_host, arg_port); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.applyActionCode$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.applyActionCode$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_code = args[1]! as String; - try { - await api.applyActionCode(arg_app, arg_code); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_code = args[1]! as String; + try { + await api.applyActionCode(arg_app, arg_code); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.checkActionCode$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.checkActionCode$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_code = args[1]! as String; - try { - final InternalActionCodeInfo output = - await api.checkActionCode(arg_app, arg_code); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_code = args[1]! as String; + try { + final InternalActionCodeInfo output = await api.checkActionCode( + arg_app, + arg_code, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.confirmPasswordReset$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.confirmPasswordReset$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_code = args[1]! as String; - final String arg_newPassword = args[2]! as String; - try { - await api.confirmPasswordReset(arg_app, arg_code, arg_newPassword); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_code = args[1]! as String; + final String arg_newPassword = args[2]! as String; + try { + await api.confirmPasswordReset( + arg_app, + arg_code, + arg_newPassword, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.createUserWithEmailAndPassword$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.createUserWithEmailAndPassword$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_email = args[1]! as String; - final String arg_password = args[2]! as String; - try { - final InternalUserCredential output = - await api.createUserWithEmailAndPassword( - arg_app, arg_email, arg_password); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_email = args[1]! as String; + final String arg_password = args[2]! as String; + try { + final InternalUserCredential output = await api + .createUserWithEmailAndPassword( + arg_app, + arg_email, + arg_password, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInAnonymously$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInAnonymously$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - try { - final InternalUserCredential output = - await api.signInAnonymously(arg_app); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + try { + final InternalUserCredential output = await api + .signInAnonymously(arg_app); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInWithCredential$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInWithCredential$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final Map arg_input = - (args[1]! as Map).cast(); - try { - final InternalUserCredential output = - await api.signInWithCredential(arg_app, arg_input); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final Map arg_input = + (args[1]! as Map).cast(); + try { + final InternalUserCredential output = await api + .signInWithCredential(arg_app, arg_input); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInWithCustomToken$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInWithCustomToken$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_token = args[1]! as String; - try { - final InternalUserCredential output = - await api.signInWithCustomToken(arg_app, arg_token); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_token = args[1]! as String; + try { + final InternalUserCredential output = await api + .signInWithCustomToken(arg_app, arg_token); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInWithEmailAndPassword$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInWithEmailAndPassword$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_email = args[1]! as String; - final String arg_password = args[2]! as String; - try { - final InternalUserCredential output = await api - .signInWithEmailAndPassword(arg_app, arg_email, arg_password); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_email = args[1]! as String; + final String arg_password = args[2]! as String; + try { + final InternalUserCredential output = await api + .signInWithEmailAndPassword( + arg_app, + arg_email, + arg_password, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInWithEmailLink$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInWithEmailLink$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_email = args[1]! as String; - final String arg_emailLink = args[2]! as String; - try { - final InternalUserCredential output = await api.signInWithEmailLink( - arg_app, arg_email, arg_emailLink); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_email = args[1]! as String; + final String arg_emailLink = args[2]! as String; + try { + final InternalUserCredential output = await api + .signInWithEmailLink(arg_app, arg_email, arg_emailLink); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInWithProvider$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInWithProvider$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final InternalSignInProvider arg_signInProvider = - args[1]! as InternalSignInProvider; - try { - final InternalUserCredential output = - await api.signInWithProvider(arg_app, arg_signInProvider); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final InternalSignInProvider arg_signInProvider = + args[1]! as InternalSignInProvider; + try { + final InternalUserCredential output = await api + .signInWithProvider(arg_app, arg_signInProvider); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signOut$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signOut$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - try { - await api.signOut(arg_app); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + try { + await api.signOut(arg_app); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.fetchSignInMethodsForEmail$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.fetchSignInMethodsForEmail$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_email = args[1]! as String; - try { - final List output = - await api.fetchSignInMethodsForEmail(arg_app, arg_email); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_email = args[1]! as String; + try { + final List output = await api + .fetchSignInMethodsForEmail(arg_app, arg_email); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.sendPasswordResetEmail$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.sendPasswordResetEmail$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_email = args[1]! as String; - final InternalActionCodeSettings? arg_actionCodeSettings = - args[2] as InternalActionCodeSettings?; - try { - await api.sendPasswordResetEmail( - arg_app, arg_email, arg_actionCodeSettings); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_email = args[1]! as String; + final InternalActionCodeSettings? arg_actionCodeSettings = + args[2] as InternalActionCodeSettings?; + try { + await api.sendPasswordResetEmail( + arg_app, + arg_email, + arg_actionCodeSettings, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.sendSignInLinkToEmail$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.sendSignInLinkToEmail$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_email = args[1]! as String; - final InternalActionCodeSettings arg_actionCodeSettings = - args[2]! as InternalActionCodeSettings; - try { - await api.sendSignInLinkToEmail( - arg_app, arg_email, arg_actionCodeSettings); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_email = args[1]! as String; + final InternalActionCodeSettings arg_actionCodeSettings = + args[2]! as InternalActionCodeSettings; + try { + await api.sendSignInLinkToEmail( + arg_app, + arg_email, + arg_actionCodeSettings, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.setLanguageCode$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.setLanguageCode$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String? arg_languageCode = args[1] as String?; - try { - final String output = - await api.setLanguageCode(arg_app, arg_languageCode); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String? arg_languageCode = args[1] as String?; + try { + final String output = await api.setLanguageCode( + arg_app, + arg_languageCode, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.setSettings$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.setSettings$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final InternalFirebaseAuthSettings arg_settings = - args[1]! as InternalFirebaseAuthSettings; - try { - final InternalUserDetails? output = - await api.setSettings(arg_app, arg_settings); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final InternalFirebaseAuthSettings arg_settings = + args[1]! as InternalFirebaseAuthSettings; + try { + final InternalUserDetails? output = await api.setSettings( + arg_app, + arg_settings, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.verifyPasswordResetCode$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.verifyPasswordResetCode$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_code = args[1]! as String; - try { - final String output = - await api.verifyPasswordResetCode(arg_app, arg_code); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_code = args[1]! as String; + try { + final String output = await api.verifyPasswordResetCode( + arg_app, + arg_code, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.verifyPhoneNumber$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.verifyPhoneNumber$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final InternalVerifyPhoneNumberRequest arg_request = - args[1]! as InternalVerifyPhoneNumberRequest; - try { - final String output = - await api.verifyPhoneNumber(arg_app, arg_request); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final InternalVerifyPhoneNumberRequest arg_request = + args[1]! as InternalVerifyPhoneNumberRequest; + try { + final String output = await api.verifyPhoneNumber( + arg_app, + arg_request, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.revokeTokenWithAuthorizationCode$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.revokeTokenWithAuthorizationCode$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_authorizationCode = args[1]! as String; - try { - await api.revokeTokenWithAuthorizationCode( - arg_app, arg_authorizationCode); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_authorizationCode = args[1]! as String; + try { + await api.revokeTokenWithAuthorizationCode( + arg_app, + arg_authorizationCode, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.revokeAccessToken$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.revokeAccessToken$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_accessToken = args[1]! as String; - try { - await api.revokeAccessToken(arg_app, arg_accessToken); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_accessToken = args[1]! as String; + try { + await api.revokeAccessToken(arg_app, arg_accessToken); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.initializeRecaptchaConfig$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.initializeRecaptchaConfig$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - try { - await api.initializeRecaptchaConfig(arg_app); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + try { + await api.initializeRecaptchaConfig(arg_app); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } @@ -922,458 +1138,586 @@ abstract class TestFirebaseAuthUserHostApi { Future delete(AuthPigeonFirebaseApp app); Future getIdToken( - AuthPigeonFirebaseApp app, bool forceRefresh); + AuthPigeonFirebaseApp app, + bool forceRefresh, + ); Future linkWithCredential( - AuthPigeonFirebaseApp app, Map input); + AuthPigeonFirebaseApp app, + Map input, + ); Future linkWithProvider( - AuthPigeonFirebaseApp app, InternalSignInProvider signInProvider); + AuthPigeonFirebaseApp app, + InternalSignInProvider signInProvider, + ); Future reauthenticateWithCredential( - AuthPigeonFirebaseApp app, Map input); + AuthPigeonFirebaseApp app, + Map input, + ); Future reauthenticateWithProvider( - AuthPigeonFirebaseApp app, InternalSignInProvider signInProvider); + AuthPigeonFirebaseApp app, + InternalSignInProvider signInProvider, + ); Future reload(AuthPigeonFirebaseApp app); - Future sendEmailVerification(AuthPigeonFirebaseApp app, - InternalActionCodeSettings? actionCodeSettings); + Future sendEmailVerification( + AuthPigeonFirebaseApp app, + InternalActionCodeSettings? actionCodeSettings, + ); Future unlink( - AuthPigeonFirebaseApp app, String providerId); + AuthPigeonFirebaseApp app, + String providerId, + ); Future updateEmail( - AuthPigeonFirebaseApp app, String newEmail); + AuthPigeonFirebaseApp app, + String newEmail, + ); Future updatePassword( - AuthPigeonFirebaseApp app, String newPassword); + AuthPigeonFirebaseApp app, + String newPassword, + ); Future updatePhoneNumber( - AuthPigeonFirebaseApp app, Map input); + AuthPigeonFirebaseApp app, + Map input, + ); Future updateProfile( - AuthPigeonFirebaseApp app, InternalUserProfile profile); + AuthPigeonFirebaseApp app, + InternalUserProfile profile, + ); - Future verifyBeforeUpdateEmail(AuthPigeonFirebaseApp app, - String newEmail, InternalActionCodeSettings? actionCodeSettings); + Future verifyBeforeUpdateEmail( + AuthPigeonFirebaseApp app, + String newEmail, + InternalActionCodeSettings? actionCodeSettings, + ); static void setUp( TestFirebaseAuthUserHostApi? api, { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.delete$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.delete$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - try { - await api.delete(arg_app); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + try { + await api.delete(arg_app); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.getIdToken$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.getIdToken$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final bool arg_forceRefresh = args[1]! as bool; - try { - final InternalIdTokenResult output = - await api.getIdToken(arg_app, arg_forceRefresh); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final bool arg_forceRefresh = args[1]! as bool; + try { + final InternalIdTokenResult output = await api.getIdToken( + arg_app, + arg_forceRefresh, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.linkWithCredential$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.linkWithCredential$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final Map arg_input = - (args[1]! as Map).cast(); - try { - final InternalUserCredential output = - await api.linkWithCredential(arg_app, arg_input); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final Map arg_input = + (args[1]! as Map).cast(); + try { + final InternalUserCredential output = await api + .linkWithCredential(arg_app, arg_input); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.linkWithProvider$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.linkWithProvider$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final InternalSignInProvider arg_signInProvider = - args[1]! as InternalSignInProvider; - try { - final InternalUserCredential output = - await api.linkWithProvider(arg_app, arg_signInProvider); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final InternalSignInProvider arg_signInProvider = + args[1]! as InternalSignInProvider; + try { + final InternalUserCredential output = await api + .linkWithProvider(arg_app, arg_signInProvider); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.reauthenticateWithCredential$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.reauthenticateWithCredential$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final Map arg_input = - (args[1]! as Map).cast(); - try { - final InternalUserCredential output = - await api.reauthenticateWithCredential(arg_app, arg_input); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final Map arg_input = + (args[1]! as Map).cast(); + try { + final InternalUserCredential output = await api + .reauthenticateWithCredential(arg_app, arg_input); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.reauthenticateWithProvider$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.reauthenticateWithProvider$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final InternalSignInProvider arg_signInProvider = - args[1]! as InternalSignInProvider; - try { - final InternalUserCredential output = await api - .reauthenticateWithProvider(arg_app, arg_signInProvider); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final InternalSignInProvider arg_signInProvider = + args[1]! as InternalSignInProvider; + try { + final InternalUserCredential output = await api + .reauthenticateWithProvider(arg_app, arg_signInProvider); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.reload$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.reload$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - try { - final InternalUserDetails output = await api.reload(arg_app); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + try { + final InternalUserDetails output = await api.reload(arg_app); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.sendEmailVerification$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.sendEmailVerification$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final InternalActionCodeSettings? arg_actionCodeSettings = - args[1] as InternalActionCodeSettings?; - try { - await api.sendEmailVerification(arg_app, arg_actionCodeSettings); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final InternalActionCodeSettings? arg_actionCodeSettings = + args[1] as InternalActionCodeSettings?; + try { + await api.sendEmailVerification( + arg_app, + arg_actionCodeSettings, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.unlink$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.unlink$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_providerId = args[1]! as String; - try { - final InternalUserCredential output = - await api.unlink(arg_app, arg_providerId); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_providerId = args[1]! as String; + try { + final InternalUserCredential output = await api.unlink( + arg_app, + arg_providerId, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.updateEmail$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.updateEmail$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_newEmail = args[1]! as String; - try { - final InternalUserDetails output = - await api.updateEmail(arg_app, arg_newEmail); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_newEmail = args[1]! as String; + try { + final InternalUserDetails output = await api.updateEmail( + arg_app, + arg_newEmail, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.updatePassword$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.updatePassword$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_newPassword = args[1]! as String; - try { - final InternalUserDetails output = - await api.updatePassword(arg_app, arg_newPassword); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_newPassword = args[1]! as String; + try { + final InternalUserDetails output = await api.updatePassword( + arg_app, + arg_newPassword, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.updatePhoneNumber$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.updatePhoneNumber$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final Map arg_input = - (args[1]! as Map).cast(); - try { - final InternalUserDetails output = - await api.updatePhoneNumber(arg_app, arg_input); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final Map arg_input = + (args[1]! as Map).cast(); + try { + final InternalUserDetails output = await api.updatePhoneNumber( + arg_app, + arg_input, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.updateProfile$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.updateProfile$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final InternalUserProfile arg_profile = - args[1]! as InternalUserProfile; - try { - final InternalUserDetails output = - await api.updateProfile(arg_app, arg_profile); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final InternalUserProfile arg_profile = + args[1]! as InternalUserProfile; + try { + final InternalUserDetails output = await api.updateProfile( + arg_app, + arg_profile, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.verifyBeforeUpdateEmail$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthUserHostApi.verifyBeforeUpdateEmail$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_newEmail = args[1]! as String; - final InternalActionCodeSettings? arg_actionCodeSettings = - args[2] as InternalActionCodeSettings?; - try { - await api.verifyBeforeUpdateEmail( - arg_app, arg_newEmail, arg_actionCodeSettings); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_newEmail = args[1]! as String; + final InternalActionCodeSettings? arg_actionCodeSettings = + args[2] as InternalActionCodeSettings?; + try { + await api.verifyBeforeUpdateEmail( + arg_app, + arg_newEmail, + arg_actionCodeSettings, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } @@ -1384,167 +1728,206 @@ abstract class TestMultiFactorUserHostApi { TestDefaultBinaryMessengerBinding.instance; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - Future enrollPhone(AuthPigeonFirebaseApp app, - InternalPhoneMultiFactorAssertion assertion, String? displayName); + Future enrollPhone( + AuthPigeonFirebaseApp app, + InternalPhoneMultiFactorAssertion assertion, + String? displayName, + ); Future enrollTotp( - AuthPigeonFirebaseApp app, String assertionId, String? displayName); + AuthPigeonFirebaseApp app, + String assertionId, + String? displayName, + ); Future getSession(AuthPigeonFirebaseApp app); Future unenroll(AuthPigeonFirebaseApp app, String factorUid); Future> getEnrolledFactors( - AuthPigeonFirebaseApp app); + AuthPigeonFirebaseApp app, + ); static void setUp( TestMultiFactorUserHostApi? api, { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorUserHostApi.enrollPhone$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorUserHostApi.enrollPhone$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final InternalPhoneMultiFactorAssertion arg_assertion = - args[1]! as InternalPhoneMultiFactorAssertion; - final String? arg_displayName = args[2] as String?; - try { - await api.enrollPhone(arg_app, arg_assertion, arg_displayName); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final InternalPhoneMultiFactorAssertion arg_assertion = + args[1]! as InternalPhoneMultiFactorAssertion; + final String? arg_displayName = args[2] as String?; + try { + await api.enrollPhone(arg_app, arg_assertion, arg_displayName); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorUserHostApi.enrollTotp$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorUserHostApi.enrollTotp$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_assertionId = args[1]! as String; - final String? arg_displayName = args[2] as String?; - try { - await api.enrollTotp(arg_app, arg_assertionId, arg_displayName); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_assertionId = args[1]! as String; + final String? arg_displayName = args[2] as String?; + try { + await api.enrollTotp(arg_app, arg_assertionId, arg_displayName); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorUserHostApi.getSession$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorUserHostApi.getSession$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - try { - final InternalMultiFactorSession output = - await api.getSession(arg_app); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + try { + final InternalMultiFactorSession output = await api.getSession( + arg_app, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorUserHostApi.unenroll$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorUserHostApi.unenroll$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - final String arg_factorUid = args[1]! as String; - try { - await api.unenroll(arg_app, arg_factorUid); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + final String arg_factorUid = args[1]! as String; + try { + await api.unenroll(arg_app, arg_factorUid); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorUserHostApi.getEnrolledFactors$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorUserHostApi.getEnrolledFactors$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final AuthPigeonFirebaseApp arg_app = - args[0]! as AuthPigeonFirebaseApp; - try { - final List output = - await api.getEnrolledFactors(arg_app); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final AuthPigeonFirebaseApp arg_app = + args[0]! as AuthPigeonFirebaseApp; + try { + final List output = await api + .getEnrolledFactors(arg_app); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } @@ -1555,44 +1938,57 @@ abstract class TestMultiFactoResolverHostApi { TestDefaultBinaryMessengerBinding.instance; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); - Future resolveSignIn(String resolverId, - InternalPhoneMultiFactorAssertion? assertion, String? totpAssertionId); + Future resolveSignIn( + String resolverId, + InternalPhoneMultiFactorAssertion? assertion, + String? totpAssertionId, + ); static void setUp( TestMultiFactoResolverHostApi? api, { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactoResolverHostApi.resolveSignIn$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactoResolverHostApi.resolveSignIn$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_resolverId = args[0]! as String; - final InternalPhoneMultiFactorAssertion? arg_assertion = - args[1] as InternalPhoneMultiFactorAssertion?; - final String? arg_totpAssertionId = args[2] as String?; - try { - final InternalUserCredential output = await api.resolveSignIn( - arg_resolverId, arg_assertion, arg_totpAssertionId); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_resolverId = args[0]! as String; + final InternalPhoneMultiFactorAssertion? arg_assertion = + args[1] as InternalPhoneMultiFactorAssertion?; + final String? arg_totpAssertionId = args[2] as String?; + try { + final InternalUserCredential output = await api.resolveSignIn( + arg_resolverId, + arg_assertion, + arg_totpAssertionId, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } @@ -1606,99 +2002,127 @@ abstract class TestMultiFactoResolverHostApi { Future generateSecret(String sessionId); Future getAssertionForEnrollment( - String secretKey, String oneTimePassword); + String secretKey, + String oneTimePassword, + ); Future getAssertionForSignIn( - String enrollmentId, String oneTimePassword); + String enrollmentId, + String oneTimePassword, + ); static void setUp( TestMultiFactoResolverHostApi? api, { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorTotpHostApi.generateSecret$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorTotpHostApi.generateSecret$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_sessionId = args[0]! as String; - try { - final InternalTotpSecret output = - await api.generateSecret(arg_sessionId); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_sessionId = args[0]! as String; + try { + final InternalTotpSecret output = await api.generateSecret( + arg_sessionId, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorTotpHostApi.getAssertionForEnrollment$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorTotpHostApi.getAssertionForEnrollment$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_secretKey = args[0]! as String; - final String arg_oneTimePassword = args[1]! as String; - try { - final String output = await api.getAssertionForEnrollment( - arg_secretKey, arg_oneTimePassword); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_secretKey = args[0]! as String; + final String arg_oneTimePassword = args[1]! as String; + try { + final String output = await api.getAssertionForEnrollment( + arg_secretKey, + arg_oneTimePassword, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorTotpHostApi.getAssertionForSignIn$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorTotpHostApi.getAssertionForSignIn$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_enrollmentId = args[0]! as String; - final String arg_oneTimePassword = args[1]! as String; - try { - final String output = await api.getAssertionForSignIn( - arg_enrollmentId, arg_oneTimePassword); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_enrollmentId = args[0]! as String; + final String arg_oneTimePassword = args[1]! as String; + try { + final String output = await api.getAssertionForSignIn( + arg_enrollmentId, + arg_oneTimePassword, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } @@ -1710,7 +2134,10 @@ abstract class TestMultiFactoResolverHostApi { static const MessageCodec pigeonChannelCodec = _PigeonCodec(); Future generateQrCodeUrl( - String secretKey, String? accountName, String? issuer); + String secretKey, + String? accountName, + String? issuer, + ); Future openInOtpApp(String secretKey, String qrCodeUrl); @@ -1719,62 +2146,78 @@ abstract class TestMultiFactoResolverHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorTotpSecretHostApi.generateQrCodeUrl$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorTotpSecretHostApi.generateQrCodeUrl$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_secretKey = args[0]! as String; - final String? arg_accountName = args[1] as String?; - final String? arg_issuer = args[2] as String?; - try { - final String output = await api.generateQrCodeUrl( - arg_secretKey, arg_accountName, arg_issuer); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_secretKey = args[0]! as String; + final String? arg_accountName = args[1] as String?; + final String? arg_issuer = args[2] as String?; + try { + final String output = await api.generateQrCodeUrl( + arg_secretKey, + arg_accountName, + arg_issuer, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorTotpSecretHostApi.openInOtpApp$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_auth_platform_interface.MultiFactorTotpSecretHostApi.openInOtpApp$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_secretKey = args[0]! as String; - final String arg_qrCodeUrl = args[1]! as String; - try { - await api.openInOtpApp(arg_secretKey, arg_qrCodeUrl); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_secretKey = args[0]! as String; + final String arg_qrCodeUrl = args[1]! as String; + try { + await api.openInOtpApp(arg_secretKey, arg_qrCodeUrl); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_auth_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_auth_test.dart index 94371d8568af..93be65837200 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_auth_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_auth_test.dart @@ -31,9 +31,7 @@ void main() { ), ); - firebaseAuthPlatform = TestFirebaseAuthPlatform( - app, - ); + firebaseAuthPlatform = TestFirebaseAuthPlatform(app); handleMethodCall((call) async { switch (call.method) { case 'Auth#registerIdTokenListener': @@ -57,8 +55,10 @@ void main() { test('get.instance', () { expect(FirebaseAuthPlatform.instance, isA()); - expect(FirebaseAuthPlatform.instance.app.name, - equals(defaultFirebaseAppName)); + expect( + FirebaseAuthPlatform.instance.app.name, + equals(defaultFirebaseAppName), + ); }); group('set.instance', () { @@ -85,16 +85,15 @@ void main() { }); test('throws if get.currentUser', () { - expect( - () => firebaseAuthPlatform.currentUser, - throwsUnimplementedError, - ); + expect(() => firebaseAuthPlatform.currentUser, throwsUnimplementedError); }); test('throws if set.currentUser', () { expect( () => firebaseAuthPlatform.sendAuthChangesEvent( - defaultFirebaseAppName, null), + defaultFirebaseAppName, + null, + ), throwsUnimplementedError, ); try { @@ -107,10 +106,7 @@ void main() { }); test('throws if languageCode', () { - expect( - () => firebaseAuthPlatform.languageCode, - throwsUnimplementedError, - ); + expect(() => firebaseAuthPlatform.languageCode, throwsUnimplementedError); }); test('throws if sendAuthChangesEvent()', () { @@ -267,10 +263,7 @@ void main() { test('throws if signInWithCredential()', () async { await expectLater( () => firebaseAuthPlatform.signInWithCredential( - const AuthCredential( - providerId: 'provider', - signInMethod: 'method', - ), + const AuthCredential(providerId: 'provider', signInMethod: 'method'), ), throwsUnimplementedError, ); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_confirmation_result_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_confirmation_result_test.dart index d4b5ba03d1f9..9a938ee091d7 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_confirmation_result_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_confirmation_result_test.dart @@ -14,8 +14,9 @@ void main() { late TestConfirmationResultPlatform confirmationResultPlatform; setUpAll(() async { - confirmationResultPlatform = - TestConfirmationResultPlatform(kMockVerificationId); + confirmationResultPlatform = TestConfirmationResultPlatform( + kMockVerificationId, + ); }); test('Constructor', () { diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_recaptcha_verifier_factory_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_recaptcha_verifier_factory_test.dart index 1e538d219237..278e20c7baf2 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_recaptcha_verifier_factory_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_recaptcha_verifier_factory_test.dart @@ -16,8 +16,10 @@ void main() { }); test('Constructor', () { - expect(recaptchaVerifierFactoryPlatform, - isA()); + expect( + recaptchaVerifierFactoryPlatform, + isA(), + ); expect(recaptchaVerifierFactoryPlatform, isA()); }); @@ -47,7 +49,8 @@ void main() { test('calls successfully', () { try { RecaptchaVerifierFactoryPlatform.verifyExtends( - recaptchaVerifierFactoryPlatform); + recaptchaVerifierFactoryPlatform, + ); return; } catch (_) { fail('thrown an unexpected exception'); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_user_credential_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_user_credential_test.dart index ea8540a8842d..e2644a2d08c5 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_user_credential_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_user_credential_test.dart @@ -44,13 +44,22 @@ void main() { profile: {}, isNewUser: false, ); - kMockUser = - TestUserPlatform(auth, TestMultiFactorPlatform(auth), kMockUserData); + kMockUser = TestUserPlatform( + auth, + TestMultiFactorPlatform(auth), + kMockUserData, + ); kMockCredential = EmailAuthProvider.credential( - email: kMockEmail, password: kMockPassword); + email: kMockEmail, + password: kMockPassword, + ); userCredentialPlatform = TestUserCredentialPlatform( - auth, kMockAdditionalUserInfo, kMockCredential, kMockUser); + auth, + kMockAdditionalUserInfo, + kMockCredential, + kMockUser, + ); }); group('Constructor', () { @@ -102,27 +111,27 @@ void main() { } class TestUserPlatform extends UserPlatform { - TestUserPlatform(FirebaseAuthPlatform auth, - MultiFactorPlatform multiFactorPlatform, InternalUserDetails data) - : super(auth, multiFactorPlatform, data); + TestUserPlatform( + FirebaseAuthPlatform auth, + MultiFactorPlatform multiFactorPlatform, + InternalUserDetails data, + ) : super(auth, multiFactorPlatform, data); } class TestMultiFactorPlatform extends MultiFactorPlatform { - TestMultiFactorPlatform(FirebaseAuthPlatform auth) - : super( - auth, - ); + TestMultiFactorPlatform(FirebaseAuthPlatform auth) : super(auth); } class TestUserCredentialPlatform extends UserCredentialPlatform { TestUserCredentialPlatform( - FirebaseAuthPlatform auth, - AdditionalUserInfo additionalUserInfo, - AuthCredential credential, - UserPlatform user) - : super( - auth: auth, - additionalUserInfo: additionalUserInfo, - credential: credential, - user: user); + FirebaseAuthPlatform auth, + AdditionalUserInfo additionalUserInfo, + AuthCredential credential, + UserPlatform user, + ) : super( + auth: auth, + additionalUserInfo: additionalUserInfo, + credential: credential, + user: user, + ); } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_user_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_user_test.dart index 9247c1796229..0eefa20f9229 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_user_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/platform_interface_tests/platform_interface_user_test.dart @@ -23,10 +23,12 @@ void main() { const String kMockPhoneNumber = TEST_PHONE_NUMBER; const String kMockRefreshToken = 'test'; const String kMockTenantId = 'test-tenant-id'; - final int kMockCreationTimestamp = - DateTime.now().subtract(const Duration(days: 2)).millisecondsSinceEpoch; - final int kMockLastSignInTimestamp = - DateTime.now().subtract(const Duration(days: 1)).millisecondsSinceEpoch; + final int kMockCreationTimestamp = DateTime.now() + .subtract(const Duration(days: 2)) + .millisecondsSinceEpoch; + final int kMockLastSignInTimestamp = DateTime.now() + .subtract(const Duration(days: 1)) + .millisecondsSinceEpoch; final List> kMockInitialProviderData = [ { 'providerId': kMockProviderId, @@ -36,7 +38,7 @@ void main() { 'email': kMockEmail, 'phoneNumber': kMockPhoneNumber, 'isEmailVerified': false, - 'isAnonymous': true + 'isAnonymous': true, }, ]; group('$UserPlatform()', () { @@ -62,8 +64,11 @@ void main() { providerData: kMockInitialProviderData, ); - userPlatform = - TestUserPlatform(auth, TestMultiFactorPlatform(auth), kMockUser); + userPlatform = TestUserPlatform( + auth, + TestMultiFactorPlatform(auth), + kMockUser, + ); }); group('Constructor', () { @@ -104,10 +109,14 @@ void main() { test('UserPlatform.metadata', () { expect(userPlatform.metadata, isA()); - expect(userPlatform.metadata.creationTime!.millisecondsSinceEpoch, - equals(kMockCreationTimestamp)); - expect(userPlatform.metadata.lastSignInTime!.millisecondsSinceEpoch, - equals(kMockLastSignInTimestamp)); + expect( + userPlatform.metadata.creationTime!.millisecondsSinceEpoch, + equals(kMockCreationTimestamp), + ); + expect( + userPlatform.metadata.lastSignInTime!.millisecondsSinceEpoch, + equals(kMockLastSignInTimestamp), + ); }); test('UserPlatform.phoneNumber', () { expect(userPlatform.phoneNumber, equals(kMockPhoneNumber)); @@ -172,7 +181,9 @@ void main() { test('throws if .linkWithCredential', () async { AuthCredential credential = EmailAuthProvider.credential( - email: 'test@email.com', password: 'testPassword'); + email: 'test@email.com', + password: 'testPassword', + ); try { await userPlatform.linkWithCredential(credential); } on UnimplementedError catch (e) { @@ -184,12 +195,16 @@ void main() { test('throws if .reauthenticateWithCredential', () async { AuthCredential credential = EmailAuthProvider.credential( - email: 'test@email.com', password: 'testPassword'); + email: 'test@email.com', + password: 'testPassword', + ); try { await userPlatform.reauthenticateWithCredential(credential); } on UnimplementedError catch (e) { - expect(e.message, - equals('reauthenticateWithCredential() is not implemented')); + expect( + e.message, + equals('reauthenticateWithCredential() is not implemented'), + ); return; } fail('Should have thrown an [UnimplementedError]'); @@ -206,8 +221,9 @@ void main() { }); test('throws if .sendEmailVerification', () async { - ActionCodeSettings actionCodeSettings = - ActionCodeSettings(url: 'www.test.com'); + ActionCodeSettings actionCodeSettings = ActionCodeSettings( + url: 'www.test.com', + ); try { await userPlatform.sendEmailVerification(actionCodeSettings); } on UnimplementedError catch (e) { @@ -272,14 +288,19 @@ void main() { }); test('throws if .verifyBeforeUpdateEmail', () async { - ActionCodeSettings actionCodeSettings = - ActionCodeSettings(url: 'www.test.com'); + ActionCodeSettings actionCodeSettings = ActionCodeSettings( + url: 'www.test.com', + ); try { await userPlatform.verifyBeforeUpdateEmail( - 'test@email.com', actionCodeSettings); + 'test@email.com', + actionCodeSettings, + ); } on UnimplementedError catch (e) { expect( - e.message, equals('verifyBeforeUpdateEmail() is not implemented')); + e.message, + equals('verifyBeforeUpdateEmail() is not implemented'), + ); return; } fail('Should have thrown an [UnimplementedError]'); @@ -288,7 +309,9 @@ void main() { } class TestUserPlatform extends UserPlatform { - TestUserPlatform(FirebaseAuthPlatform auth, MultiFactorPlatform multiFactor, - InternalUserDetails data) - : super(auth, multiFactor, data); + TestUserPlatform( + FirebaseAuthPlatform auth, + MultiFactorPlatform multiFactor, + InternalUserDetails data, + ) : super(auth, multiFactor, data); } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/email_auth_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/email_auth_test.dart index 8429a886751c..41aca1e83e66 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/email_auth_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/email_auth_test.dart @@ -29,7 +29,9 @@ void main() { test('EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD', () { expect(EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD, isA()); expect( - EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD, equals('password')); + EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD, + equals('password'), + ); }); test('EmailAuthProvider.PROVIDER_ID', () { @@ -40,7 +42,9 @@ void main() { group('EmailAuthProvider.credential()', () { test('creates a new [EmailAuthCredential]', () { final result = EmailAuthProvider.credential( - email: kMockEmail, password: kMockPassword); + email: kMockEmail, + password: kMockPassword, + ); expect(result, isA()); expect(result.token, isNull); expect(result.signInMethod, equals('password')); @@ -50,7 +54,9 @@ void main() { group('EmailAuthProvider.credentialWithLink()', () { test('creates a new [EmailAuthCredential]', () { final result = EmailAuthProvider.credentialWithLink( - email: kMockEmail, emailLink: kMockEmailLink); + email: kMockEmail, + emailLink: kMockEmailLink, + ); expect(result, isA()); expect(result.token, isNull); expect(result.signInMethod, equals('emailLink')); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/facebook_auth_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/facebook_auth_test.dart index 882cb4d129b8..494071b6707d 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/facebook_auth_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/facebook_auth_test.dart @@ -20,8 +20,10 @@ void main() { test('FacebookAuthProvider.FACEBOOK_SIGN_IN_METHOD', () { expect(FacebookAuthProvider.FACEBOOK_SIGN_IN_METHOD, isA()); - expect(FacebookAuthProvider.FACEBOOK_SIGN_IN_METHOD, - equals(kMockProviderId)); + expect( + FacebookAuthProvider.FACEBOOK_SIGN_IN_METHOD, + equals(kMockProviderId), + ); }); test('FacebookAuthProvider.PROVIDER_ID', () { @@ -55,8 +57,9 @@ void main() { final Map kCustomOAuthParameters = { 'display': 'popup', }; - final result = - facebookAuthProvider.setCustomParameters(kCustomOAuthParameters); + final result = facebookAuthProvider.setCustomParameters( + kCustomOAuthParameters, + ); expect(result, isA()); expect(result.parameters['display'], isA()); expect(result.parameters['display'], equals('popup')); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/github_auth_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/github_auth_test.dart index 72c40aa15a00..73ed53b1ea44 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/github_auth_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/github_auth_test.dart @@ -54,8 +54,9 @@ void main() { final Map kCustomOAuthParameters = { 'allow_signup': 'false', }; - final result = - githubAuthProvider.setCustomParameters(kCustomOAuthParameters); + final result = githubAuthProvider.setCustomParameters( + kCustomOAuthParameters, + ); expect(result, isA()); expect(result.parameters['allow_signup'], isA()); expect(result.parameters['allow_signup'], equals('false')); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/google_auth_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/google_auth_test.dart index 8127fabed3e3..a239a89d7428 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/google_auth_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/google_auth_test.dart @@ -53,10 +53,11 @@ void main() { group('setCustomParameters()', () { test('sets custom parameters', () { final Map kCustomOAuthParameters = { - 'login_hint': 'user@example.com' + 'login_hint': 'user@example.com', }; - final result = - googleAuthProvider.setCustomParameters(kCustomOAuthParameters); + final result = googleAuthProvider.setCustomParameters( + kCustomOAuthParameters, + ); expect(result, isA()); expect(result.parameters['login_hint'], isA()); expect(result.parameters['login_hint'], equals('user@example.com')); @@ -67,8 +68,9 @@ void main() { const String kMockAccessToken = 'test-access-token'; const String kMockIdToken = 'test-id-token'; test('creates a new [GoogleAuthCredential]', () { - final result = - GoogleAuthProvider.credential(accessToken: kMockAccessToken); + final result = GoogleAuthProvider.credential( + accessToken: kMockAccessToken, + ); expect(result, isA()); expect(result.token, isNull); expect(result.idToken, isNull); @@ -79,24 +81,24 @@ void main() { test('allows accessToken to be null', () { expect( - GoogleAuthProvider.credential( - idToken: kMockIdToken, - ), - isA()); + GoogleAuthProvider.credential(idToken: kMockIdToken), + isA(), + ); }); test('allows idToken to be null', () { expect( - GoogleAuthProvider.credential( - accessToken: kMockAccessToken, - ), - isA()); + GoogleAuthProvider.credential(accessToken: kMockAccessToken), + isA(), + ); }); - test('throws [AssertionError] when accessToken and idTokenResult is null', - () { - expect(GoogleAuthProvider.credential, throwsAssertionError); - }); + test( + 'throws [AssertionError] when accessToken and idTokenResult is null', + () { + expect(GoogleAuthProvider.credential, throwsAssertionError); + }, + ); }); }); } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/oauth_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/oauth_test.dart index da2e71883969..4087595367f8 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/oauth_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/oauth_test.dart @@ -49,8 +49,9 @@ void main() { final Map kCustomOAuthParameters = { 'allow_signup': 'false', }; - final result = - oAuthProvider.setCustomParameters(kCustomOAuthParameters); + final result = oAuthProvider.setCustomParameters( + kCustomOAuthParameters, + ); expect(result, isA()); expect(result.parameters['allow_signup'], isA()); expect(result.parameters['allow_signup'], equals('false')); @@ -64,10 +65,11 @@ void main() { const String kMockRawNonce = 'test-raw-nonce'; test('creates a new [OAuthCredential]', () { final result = oAuthProvider.credential( - accessToken: kMockAccessToken, - secret: kMockSecret, - idToken: kMockIdToken, - rawNonce: kMockRawNonce); + accessToken: kMockAccessToken, + secret: kMockSecret, + idToken: kMockIdToken, + rawNonce: kMockRawNonce, + ); expect(result, isA()); expect(result.token, isNull); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/twitter_auth_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/twitter_auth_test.dart index dd1462f2fc94..6fb03254f04e 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/twitter_auth_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/providers_tests/twitter_auth_test.dart @@ -21,7 +21,9 @@ void main() { test('TwitterAuthProvider.TWITTER_SIGN_IN_METHOD', () { expect(TwitterAuthProvider.TWITTER_SIGN_IN_METHOD, isA()); expect( - TwitterAuthProvider.TWITTER_SIGN_IN_METHOD, equals(kMockProviderId)); + TwitterAuthProvider.TWITTER_SIGN_IN_METHOD, + equals(kMockProviderId), + ); }); test('TwitterAuthProvider.PROVIDER_ID', () { @@ -36,8 +38,9 @@ void main() { group('setCustomParameters()', () { test('sets custom parameters', () { final Map kCustomOAuthParameters = {'lang': 'es'}; - final result = - twitterAuthProvider.setCustomParameters(kCustomOAuthParameters); + final result = twitterAuthProvider.setCustomParameters( + kCustomOAuthParameters, + ); expect(result, isA()); expect(result.parameters['lang'], isA()); expect(result.parameters['lang'], equals('es')); @@ -49,7 +52,9 @@ void main() { const String kMockSecret = 'test-secret'; test('creates a new [TwitterAuthCredential]', () { final result = TwitterAuthProvider.credential( - accessToken: kMockAccessToken, secret: kMockSecret); + accessToken: kMockAccessToken, + secret: kMockSecret, + ); expect(result, isA()); expect(result.token, isNull); expect(result.idToken, isNull); diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/user_metadata_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/user_metadata_test.dart index 88aac25b802a..93020b9a192c 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/user_metadata_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/user_metadata_test.dart @@ -10,28 +10,38 @@ void main() { const int kMockCreationTimestamp = 12345677; const int kMockLastSignInTimeTimestamp = 12345678; group('$UserMetadata', () { - final userMetadata = - UserMetadata(kMockCreationTimestamp, kMockLastSignInTimeTimestamp); + final userMetadata = UserMetadata( + kMockCreationTimestamp, + kMockLastSignInTimeTimestamp, + ); group('Constructor', () { test('returns an instance of [UserMetadata]', () { expect(userMetadata, isA()); - expect(userMetadata.creationTime!.millisecondsSinceEpoch, - kMockCreationTimestamp); - expect(userMetadata.lastSignInTime!.millisecondsSinceEpoch, - kMockLastSignInTimeTimestamp); + expect( + userMetadata.creationTime!.millisecondsSinceEpoch, + kMockCreationTimestamp, + ); + expect( + userMetadata.lastSignInTime!.millisecondsSinceEpoch, + kMockLastSignInTimeTimestamp, + ); }); }); group('creationTime', () { test('returns an instance of [DateTime]', () { expect(userMetadata.creationTime, isA()); - expect(userMetadata.creationTime!.millisecondsSinceEpoch, - kMockCreationTimestamp); + expect( + userMetadata.creationTime!.millisecondsSinceEpoch, + kMockCreationTimestamp, + ); }); test('returns null', () { - UserMetadata testUserMetadata = - UserMetadata(null, kMockLastSignInTimeTimestamp); + UserMetadata testUserMetadata = UserMetadata( + null, + kMockLastSignInTimeTimestamp, + ); expect(testUserMetadata.creationTime, isNull); }); @@ -40,20 +50,26 @@ void main() { group('lastSignInTime', () { test('returns an instance of [DateTime]', () { expect(userMetadata.lastSignInTime, isA()); - expect(userMetadata.lastSignInTime!.millisecondsSinceEpoch, - kMockLastSignInTimeTimestamp); + expect( + userMetadata.lastSignInTime!.millisecondsSinceEpoch, + kMockLastSignInTimeTimestamp, + ); }); test('returns null', () { - UserMetadata testUserMetadata = - UserMetadata(kMockCreationTimestamp, null); + UserMetadata testUserMetadata = UserMetadata( + kMockCreationTimestamp, + null, + ); expect(testUserMetadata.lastSignInTime, isNull); }); }); test('toString()', () { - expect(userMetadata.toString(), - 'UserMetadata(creationTime: ${userMetadata.creationTime}, lastSignInTime: ${userMetadata.lastSignInTime})'); + expect( + userMetadata.toString(), + 'UserMetadata(creationTime: ${userMetadata.creationTime}, lastSignInTime: ${userMetadata.lastSignInTime})', + ); }); }); } diff --git a/packages/firebase_auth/firebase_auth_web/lib/firebase_auth_web.dart b/packages/firebase_auth/firebase_auth_web/lib/firebase_auth_web.dart index 860e6c5cce0d..c2a1354993d2 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/firebase_auth_web.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/firebase_auth_web.dart @@ -34,9 +34,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { /// Stub initializer to allow the [registerWith] to create an instance without /// registering the web delegates or listeners. - FirebaseAuthWeb._() - : _webAuth = null, - super(appInstance: null); + FirebaseAuthWeb._() : _webAuth = null, super(appInstance: null); Completer _initialized = Completer(); @@ -58,8 +56,9 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { final authDelegate = auth_interop.getAuthInstance(firebaseApp); // if localhost, and emulator was previously set in localStorage, use it if (web.window.location.hostname == 'localhost' && kDebugMode) { - final String? emulatorOrigin = web.window.sessionStorage - .getItem(getOriginName(firebaseApp.name)); + final String? emulatorOrigin = web.window.sessionStorage.getItem( + getOriginName(firebaseApp.name), + ); if (emulatorOrigin != null) { try { @@ -92,7 +91,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { } static Map> - _authStateChangesListeners = >{}; + _authStateChangesListeners = >{}; static Map> _idTokenChangesListeners = >{}; @@ -113,35 +112,36 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { case StateListener.authStateChange: _authStateChangesListeners[appName] = StreamController.broadcast( - onCancel: () { - _authStateChangesListeners[appName]!.close(); - _authStateChangesListeners.remove(appName); - delegate.authStateController?.close(); - }, - ); - delegate.onAuthStateChanged.map((auth_interop.User? webUser) { - if (!_initialized.isCompleted) { - _initialized.complete(); - } - - if (webUser == null) { - return null; - } else { - return UserWeb( - this, - MultiFactorWeb(this, multi_factor.multiFactor(webUser)), - webUser, - _webAuth, + onCancel: () { + _authStateChangesListeners[appName]!.close(); + _authStateChangesListeners.remove(appName); + delegate.authStateController?.close(); + }, ); - } - }).listen((UserWeb? webUser) { - _authStateChangesListeners[app.name]?.add(webUser); - }); + delegate.onAuthStateChanged + .map((auth_interop.User? webUser) { + if (!_initialized.isCompleted) { + _initialized.complete(); + } + + if (webUser == null) { + return null; + } else { + return UserWeb( + this, + MultiFactorWeb(this, multi_factor.multiFactor(webUser)), + webUser, + _webAuth, + ); + } + }) + .listen((UserWeb? webUser) { + _authStateChangesListeners[app.name]?.add(webUser); + }); break; case StateListener.idTokenChange: _cancelIdTokenStream = false; - _idTokenChangesListeners[appName] = - StreamController.broadcast( + _idTokenChangesListeners[appName] = StreamController.broadcast( onCancel: () { if (_userChangesListeners[appName] == null) { // We cannot remove if there is a userChanges listener as we use this stream for it @@ -162,26 +162,27 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { ); // Also triggers `userChanged` events - delegate.onIdTokenChanged.map((auth_interop.User? webUser) { - if (webUser == null) { - return null; - } else { - return UserWeb( - this, - MultiFactorWeb(this, multi_factor.multiFactor(webUser)), - webUser, - _webAuth, - ); - } - }).listen((UserWeb? webUser) { - _idTokenChangesListeners[app.name]?.add(webUser); - _userChangesListeners[app.name]?.add(webUser); - }); + delegate.onIdTokenChanged + .map((auth_interop.User? webUser) { + if (webUser == null) { + return null; + } else { + return UserWeb( + this, + MultiFactorWeb(this, multi_factor.multiFactor(webUser)), + webUser, + _webAuth, + ); + } + }) + .listen((UserWeb? webUser) { + _idTokenChangesListeners[app.name]?.add(webUser); + _userChangesListeners[app.name]?.add(webUser); + }); break; case StateListener.userStateChange: _cancelUserStream = false; - _userChangesListeners[appName] = - StreamController.broadcast( + _userChangesListeners[appName] = StreamController.broadcast( onCancel: () { if (_idTokenChangesListeners[appName] == null) { _userChangesListeners[appName]!.close(); @@ -261,9 +262,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { @override Future applyActionCode(String code) async { - await guardAuthExceptions( - () => delegate.applyActionCode(code), - ); + await guardAuthExceptions(() => delegate.applyActionCode(code)); } @override @@ -284,16 +283,14 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { @override Future createUserWithEmailAndPassword( - String email, String password) async { + String email, + String password, + ) async { final userCredential = await guardAuthExceptions( () => delegate.createUserWithEmailAndPassword(email, password), ); - return UserCredentialWeb( - this, - userCredential, - _webAuth, - ); + return UserCredentialWeb(this, userCredential, _webAuth); } @override @@ -305,14 +302,11 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { @override Future getRedirectResult() async { - final userCredential = - await guardAuthExceptions(delegate.getRedirectResult); - - return UserCredentialWeb( - this, - userCredential, - _webAuth, + final userCredential = await guardAuthExceptions( + delegate.getRedirectResult, ); + + return UserCredentialWeb(this, userCredential, _webAuth); } @override @@ -353,9 +347,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { return guardAuthExceptions( () => delegate.sendPasswordResetEmail( email, - convertPlatformActionCodeSettings( - actionCodeSettings, - ), + convertPlatformActionCodeSettings(actionCodeSettings), ), ); } @@ -368,9 +360,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { return guardAuthExceptions( () => delegate.sendSignInLinkToEmail( email, - convertPlatformActionCodeSettings( - actionCodeSettings, - ), + convertPlatformActionCodeSettings(actionCodeSettings), ), ); } @@ -404,11 +394,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { @override Future setPersistence(Persistence persistence) async { - return guardAuthExceptions( - () => delegate.setPersistence( - persistence, - ), - ); + return guardAuthExceptions(() => delegate.setPersistence(persistence)); } @override @@ -418,11 +404,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { auth: _webAuth, ); - return UserCredentialWeb( - this, - userCredential, - _webAuth, - ); + return UserCredentialWeb(this, userCredential, _webAuth); } @override @@ -435,11 +417,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { auth: _webAuth, ); - return UserCredentialWeb( - this, - authCredential, - _webAuth, - ); + return UserCredentialWeb(this, authCredential, _webAuth); } @override @@ -449,41 +427,33 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { auth: _webAuth, ); - return UserCredentialWeb( - this, - userCredential, - _webAuth, - ); + return UserCredentialWeb(this, userCredential, _webAuth); } @override Future signInWithEmailAndPassword( - String email, String password) async { + String email, + String password, + ) async { final userCredential = await guardAuthExceptions( () => delegate.signInWithEmailAndPassword(email, password), auth: _webAuth, ); - return UserCredentialWeb( - this, - userCredential, - _webAuth, - ); + return UserCredentialWeb(this, userCredential, _webAuth); } @override Future signInWithEmailLink( - String email, String emailLink) async { + String email, + String emailLink, + ) async { final userCredential = await guardAuthExceptions( () => delegate.signInWithEmailLink(email, emailLink), auth: _webAuth, ); - return UserCredentialWeb( - this, - userCredential, - _webAuth, - ); + return UserCredentialWeb(this, userCredential, _webAuth); } @override @@ -495,40 +465,25 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { auth_interop.RecaptchaVerifier verifier = applicationVerifier.delegate; final confirmationResult = await guardAuthExceptions( - () => delegate.signInWithPhoneNumber( - phoneNumber, - verifier, - ), - ); - return ConfirmationResultWeb( - this, - confirmationResult, - _webAuth, + () => delegate.signInWithPhoneNumber(phoneNumber, verifier), ); + return ConfirmationResultWeb(this, confirmationResult, _webAuth); } @override Future signInWithPopup(AuthProvider provider) async { final userCredential = await guardAuthExceptions( - () => delegate.signInWithPopup( - convertPlatformAuthProvider(provider), - ), + () => delegate.signInWithPopup(convertPlatformAuthProvider(provider)), auth: _webAuth, ); - return UserCredentialWeb( - this, - userCredential, - _webAuth, - ); + return UserCredentialWeb(this, userCredential, _webAuth); } @override Future signInWithRedirect(AuthProvider provider) async { return guardAuthExceptions( - () => delegate.signInWithRedirect( - convertPlatformAuthProvider(provider), - ), + () => delegate.signInWithRedirect(convertPlatformAuthProvider(provider)), auth: _webAuth, ); } @@ -542,8 +497,9 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { Future useAuthEmulator(String host, int port) async { try { // Get current session storage value - final String? emulatorOrigin = - web.window.sessionStorage.getItem(getOriginName(delegate.app.name)); + final String? emulatorOrigin = web.window.sessionStorage.getItem( + getOriginName(delegate.app.name), + ); // The generic platform interface is with host and port split to // centralize logic between android/ios native, but web takes the @@ -560,8 +516,10 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { // Save to session storage so that the emulator is used on refresh // only in debug mode if (kDebugMode) { - web.window.sessionStorage - .setItem(getOriginName(delegate.app.name), origin); + web.window.sessionStorage.setItem( + getOriginName(delegate.app.name), + origin, + ); } } catch (e) { // Cannot be done with 3.2 constraints @@ -580,9 +538,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { @override Future verifyPasswordResetCode(String code) async { - return guardAuthExceptions( - () => delegate.verifyPasswordResetCode(code), - ); + return guardAuthExceptions(() => delegate.verifyPasswordResetCode(code)); } @override @@ -619,13 +575,13 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { final phoneOptions = (data ?? phoneNumber)!; final provider = auth_interop.PhoneAuthProvider(_webAuth); - final verifier = RecaptchaVerifierFactoryWeb( - auth: this, - ).delegate; + final verifier = RecaptchaVerifierFactoryWeb(auth: this).delegate; /// We add the passthrough method for LegacyJsObject - final verificationId = - await provider.verifyPhoneNumber(phoneOptions.jsify(), verifier); + final verificationId = await provider.verifyPhoneNumber( + phoneOptions.jsify(), + verifier, + ); codeSent(verificationId, null); } catch (e) { @@ -635,7 +591,8 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { @override Future revokeTokenWithAuthorizationCode( - String authorizationCode) async { + String authorizationCode, + ) async { throw UnimplementedError( 'revokeTokenWithAuthorizationCode() is only available on apple platforms.', ); @@ -643,9 +600,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { @override Future initializeRecaptchaConfig() async { - await guardAuthExceptions( - () => delegate.initializeRecaptchaConfig(), - ); + await guardAuthExceptions(() => delegate.initializeRecaptchaConfig()); } } diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_confirmation_result.dart b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_confirmation_result.dart index 1c6217b6f13d..30ceb0cc870d 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_confirmation_result.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_confirmation_result.dart @@ -14,11 +14,8 @@ import 'utils/web_utils.dart'; /// The web delegate implementation for [ConfirmationResultPlatform]. class ConfirmationResultWeb extends ConfirmationResultPlatform { /// Creates a new [ConfirmationResultWeb] instance. - ConfirmationResultWeb( - this._auth, - this._webConfirmationResult, - this._webAuth, - ) : super(_webConfirmationResult.verificationId); + ConfirmationResultWeb(this._auth, this._webConfirmationResult, this._webAuth) + : super(_webConfirmationResult.verificationId); final FirebaseAuthPlatform _auth; @@ -30,10 +27,6 @@ class ConfirmationResultWeb extends ConfirmationResultPlatform { final userCredential = await guardAuthExceptions( () => _webConfirmationResult.confirm(verificationCode), ); - return UserCredentialWeb( - _auth, - userCredential, - _webAuth, - ); + return UserCredentialWeb(_auth, userCredential, _webAuth); } } diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_multi_factor.dart b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_multi_factor.dart index 2c588713625e..306c69fc9725 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_multi_factor.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_multi_factor.dart @@ -15,7 +15,7 @@ import 'utils/web_utils.dart'; /// Web delegate implementation of [UserPlatform]. class MultiFactorWeb extends MultiFactorPlatform { MultiFactorWeb(FirebaseAuthPlatform auth, this._webMultiFactorUser) - : super(auth); + : super(auth); final multi_factor_interop.MultiFactorUser _webMultiFactorUser; @@ -33,10 +33,7 @@ class MultiFactorWeb extends MultiFactorPlatform { }) async { final webAssertion = assertion as MultiFactorAssertionWeb; await guardAuthExceptions( - () => _webMultiFactorUser.enroll( - webAssertion.assertion, - displayName, - ), + () => _webMultiFactorUser.enroll(webAssertion.assertion, displayName), ); } @@ -52,9 +49,9 @@ class MultiFactorWeb extends MultiFactorPlatform { ); } - await guardAuthExceptions(() => _webMultiFactorUser.unenroll( - uidToUnenroll, - )); + await guardAuthExceptions( + () => _webMultiFactorUser.unenroll(uidToUnenroll), + ); } @override @@ -65,9 +62,7 @@ class MultiFactorWeb extends MultiFactorPlatform { } class MultiFactorAssertionWeb extends MultiFactorAssertionPlatform { - MultiFactorAssertionWeb( - this.assertion, - ) : super(); + MultiFactorAssertionWeb(this.assertion) : super(); final multi_factor_interop.MultiFactorAssertion assertion; } @@ -94,19 +89,12 @@ class MultiFactorResolverWeb extends MultiFactorResolverPlatform { () => _webMultiFactorResolver.resolveSignIn(webAssertion.assertion), ); - return UserCredentialWeb( - _auth, - userCredential, - _webAuth, - ); + return UserCredentialWeb(_auth, userCredential, _webAuth); } } class MultiFactorSessionWeb extends MultiFactorSession { - MultiFactorSessionWeb( - String id, - this.webSession, - ) : super(id); + MultiFactorSessionWeb(String id, this.webSession) : super(id); final multi_factor_interop.MultiFactorSession webSession; } @@ -116,9 +104,7 @@ class PhoneMultiFactorGeneratorWeb extends PhoneMultiFactorGeneratorPlatform { /// Transforms a PhoneAuthCredential into a [MultiFactorAssertion] /// which can be used to confirm ownership of a phone second factor. @override - MultiFactorAssertionPlatform getAssertion( - PhoneAuthCredential credential, - ) { + MultiFactorAssertionPlatform getAssertion(PhoneAuthCredential credential) { final verificationId = credential.verificationId; final verificationCode = credential.smsCode; @@ -129,46 +115,39 @@ class PhoneMultiFactorGeneratorWeb extends PhoneMultiFactorGeneratorPlatform { throw ArgumentError('verificationId must not be null'); } - final cred = - auth.PhoneAuthProvider.credential(verificationId, verificationCode); + final cred = auth.PhoneAuthProvider.credential( + verificationId, + verificationCode, + ); return MultiFactorAssertionWeb( - multi_factor_interop.PhoneMultiFactorGenerator.assertion(cred)); + multi_factor_interop.PhoneMultiFactorGenerator.assertion(cred), + ); } } class TotpSecretWeb extends TotpSecretPlatform { TotpSecretWeb( - this.webSecret, - super.codeIntervalSeconds, - super.codeLength, - super.enrollmentCompletionDeadline, - super.hashingAlgorithm, - super.secretKey); + this.webSecret, + super.codeIntervalSeconds, + super.codeLength, + super.enrollmentCompletionDeadline, + super.hashingAlgorithm, + super.secretKey, + ); final multi_factor_interop.TotpSecret webSecret; @override - /// Generate a TOTP secret for the authenticated user. @override - Future generateQrCodeUrl({ - String? accountName, - String? issuer, - }) { - return Future.value( - webSecret.generateQrCodeUrl( - accountName, - issuer, - ), - ); + Future generateQrCodeUrl({String? accountName, String? issuer}) { + return Future.value(webSecret.generateQrCodeUrl(accountName, issuer)); } /// Opens the specified QR Code URL in a password manager like iCloud Keychain. @override - Future openInOtpApp( - String qrCodeUrl, - ) async { + Future openInOtpApp(String qrCodeUrl) async { throw UnimplementedError('openInOtpApp() is not available on Web'); } } @@ -177,13 +156,12 @@ class TotpMultiFactorGeneratorWeb extends TotpMultiFactorGeneratorPlatform { /// Transforms a PhoneAuthCredential into a [MultiFactorAssertion] /// which can be used to confirm ownership of a phone second factor. @override - Future generateSecret( - MultiFactorSession session, - ) async { + Future generateSecret(MultiFactorSession session) async { final _webMultiFactorSession = session as MultiFactorSessionWeb; final _webSecret = await multi_factor_interop.TotpMultiFactorGenerator.generateSecret( - _webMultiFactorSession.webSession); + _webMultiFactorSession.webSession, + ); return TotpSecretWeb( _webSecret, @@ -205,9 +183,9 @@ class TotpMultiFactorGeneratorWeb extends TotpMultiFactorGeneratorPlatform { final _webSecret = secret as TotpSecretWeb; final totpAssertion = multi_factor_interop.TotpMultiFactorGenerator.assertionForEnrollment( - _webSecret.webSecret, - oneTimePassword, - ); + _webSecret.webSecret, + oneTimePassword, + ); return MultiFactorAssertionWeb(totpAssertion); } @@ -220,9 +198,9 @@ class TotpMultiFactorGeneratorWeb extends TotpMultiFactorGeneratorPlatform { ) async { final totpAssertion = multi_factor_interop.TotpMultiFactorGenerator.assertionForSignIn( - enrollmentId, - oneTimePassword, - ); + enrollmentId, + oneTimePassword, + ); return MultiFactorAssertionWeb(totpAssertion); } } diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_recaptcha_verifier_factory.dart b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_recaptcha_verifier_factory.dart index f3ed01d646e9..80e380c3d47c 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_recaptcha_verifier_factory.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_recaptcha_verifier_factory.dart @@ -66,8 +66,9 @@ class RecaptchaVerifierFactoryWeb extends RecaptchaVerifierFactoryPlatform { if (container == null || container.isEmpty) { parameters['size'] = 'invisible'.toJS; - web.Element? el = - web.window.document.getElementById(_kInvisibleElementId); + web.Element? el = web.window.document.getElementById( + _kInvisibleElementId, + ); // If an existing element exists, something may have already been rendered. if (el != null) { diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user.dart b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user.dart index 20c345d90a32..6166291ebfd7 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user.dart @@ -23,49 +23,56 @@ class UserWeb extends UserPlatform { this._webUser, this._webAuth, ) : super( - auth, - multiFactor, - InternalUserDetails( - userInfo: InternalUserInfo( - displayName: _webUser.displayName, - email: _webUser.email, - isEmailVerified: _webUser.emailVerified, - isAnonymous: _webUser.isAnonymous, - creationTimestamp: _webUser.metadata.creationTime != null - ? (js_interop.globalContext.getProperty('Date'.toJS)! - as js_interop.JSObject) - .callMethod( - 'parse'.toJS, _webUser.metadata.creationTime) - .toDartInt - : null, - lastSignInTimestamp: _webUser.metadata.lastSignInTime != null - ? (js_interop.globalContext.getProperty('Date'.toJS)! - as js_interop.JSObject) - .callMethod( - 'parse'.toJS, _webUser.metadata.lastSignInTime) - .toDartInt - : null, - phoneNumber: _webUser.phoneNumber, - photoUrl: _webUser.photoURL, - refreshToken: _webUser.refreshToken, - tenantId: _webUser.tenantId, - uid: _webUser.uid, - ), - providerData: _webUser.providerData - .map((auth_interop.UserInfo webUserInfo) => { - 'displayName': webUserInfo.displayName, - 'email': webUserInfo.email, - // isAnonymous is always false for providerData - 'isAnonymous': false, - // isEmailVerified is always true for providerData - 'isEmailVerified': true, - 'phoneNumber': webUserInfo.phoneNumber, - 'providerId': webUserInfo.providerId, - 'photoUrl': webUserInfo.photoURL, - 'uid': webUserInfo.uid, - }) - .toList()), - ); + auth, + multiFactor, + InternalUserDetails( + userInfo: InternalUserInfo( + displayName: _webUser.displayName, + email: _webUser.email, + isEmailVerified: _webUser.emailVerified, + isAnonymous: _webUser.isAnonymous, + creationTimestamp: _webUser.metadata.creationTime != null + ? (js_interop.globalContext.getProperty('Date'.toJS)! + as js_interop.JSObject) + .callMethod( + 'parse'.toJS, + _webUser.metadata.creationTime, + ) + .toDartInt + : null, + lastSignInTimestamp: _webUser.metadata.lastSignInTime != null + ? (js_interop.globalContext.getProperty('Date'.toJS)! + as js_interop.JSObject) + .callMethod( + 'parse'.toJS, + _webUser.metadata.lastSignInTime, + ) + .toDartInt + : null, + phoneNumber: _webUser.phoneNumber, + photoUrl: _webUser.photoURL, + refreshToken: _webUser.refreshToken, + tenantId: _webUser.tenantId, + uid: _webUser.uid, + ), + providerData: _webUser.providerData + .map( + (auth_interop.UserInfo webUserInfo) => { + 'displayName': webUserInfo.displayName, + 'email': webUserInfo.email, + // isAnonymous is always false for providerData + 'isAnonymous': false, + // isEmailVerified is always true for providerData + 'isEmailVerified': true, + 'phoneNumber': webUserInfo.phoneNumber, + 'providerId': webUserInfo.providerId, + 'photoUrl': webUserInfo.photoURL, + 'uid': webUserInfo.uid, + }, + ) + .toList(), + ), + ); final auth_interop.User _webUser; final auth_interop.Auth? _webAuth; @@ -89,54 +96,39 @@ class UserWeb extends UserPlatform { Future getIdTokenResult(bool forceRefresh) async { _assertIsSignedOut(auth); final result = convertWebIdTokenResult( - await guardAuthExceptions( - () => _webUser.getIdTokenResult(forceRefresh), - ), + await guardAuthExceptions(() => _webUser.getIdTokenResult(forceRefresh)), ); return result; } @override Future linkWithCredential( - AuthCredential credential) async { + AuthCredential credential, + ) async { _assertIsSignedOut(auth); final userCredential = await guardAuthExceptions( - () => _webUser.linkWithCredential( - convertPlatformCredential(credential), - ), + () => _webUser.linkWithCredential(convertPlatformCredential(credential)), auth: _webAuth, ); - return UserCredentialWeb( - auth, - userCredential, - _webAuth, - ); + return UserCredentialWeb(auth, userCredential, _webAuth); } @override Future linkWithPopup(AuthProvider provider) async { _assertIsSignedOut(auth); final userCredential = await guardAuthExceptions( - () => _webUser.linkWithPopup( - convertPlatformAuthProvider(provider), - ), + () => _webUser.linkWithPopup(convertPlatformAuthProvider(provider)), auth: _webAuth, ); - return UserCredentialWeb( - auth, - userCredential, - _webAuth, - ); + return UserCredentialWeb(auth, userCredential, _webAuth); } @override Future linkWithRedirect(AuthProvider provider) async { await guardAuthExceptions( - () => _webUser.linkWithRedirect( - convertPlatformAuthProvider(provider), - ), + () => _webUser.linkWithRedirect(convertPlatformAuthProvider(provider)), auth: _webAuth, ); } @@ -154,16 +146,13 @@ class UserWeb extends UserPlatform { () => _webUser.linkWithPhoneNumber(phoneNumber, verifier), auth: _webAuth, ); - return ConfirmationResultWeb( - auth, - confirmationResult, - _webAuth, - ); + return ConfirmationResultWeb(auth, confirmationResult, _webAuth); } @override Future reauthenticateWithCredential( - AuthCredential credential) async { + AuthCredential credential, + ) async { _assertIsSignedOut(auth); auth_interop.UserCredential userCredential = await guardAuthExceptions( @@ -177,7 +166,8 @@ class UserWeb extends UserPlatform { @override Future reauthenticateWithPopup( - AuthProvider provider) async { + AuthProvider provider, + ) async { _assertIsSignedOut(auth); auth_interop.UserCredential userCredential = await guardAuthExceptions( @@ -228,12 +218,7 @@ class UserWeb extends UserPlatform { auth: _webAuth, ); - return UserWeb( - auth, - multiFactor, - userPlatform, - _webAuth, - ); + return UserWeb(auth, multiFactor, userPlatform, _webAuth); } @override @@ -270,10 +255,7 @@ class UserWeb extends UserPlatform { ), auth: _webAuth, ); - await guardAuthExceptions( - _webUser.reload, - auth: _webAuth, - ); + await guardAuthExceptions(_webUser.reload, auth: _webAuth); auth.sendAuthChangesEvent(auth.app.name, auth.currentUser); } @@ -302,10 +284,7 @@ class UserWeb extends UserPlatform { () => _webUser.updateProfile(newProfile), auth: _webAuth, ); - await guardAuthExceptions( - _webUser.reload, - auth: _webAuth, - ); + await guardAuthExceptions(_webUser.reload, auth: _webAuth); auth.sendAuthChangesEvent(auth.app.name, auth.currentUser); } diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user_credential.dart b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user_credential.dart index edd315f37d38..19f48aa7d433 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user_credential.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user_credential.dart @@ -19,18 +19,18 @@ class UserCredentialWeb extends UserCredentialPlatform { auth_interop.UserCredential? webUserCredential, auth_interop.Auth? webAuth, ) : super( - auth: auth, - additionalUserInfo: convertWebAdditionalUserInfo( - webUserCredential?.additionalUserInfo, - ), - credential: convertWebOAuthCredential(webUserCredential), - user: webUserCredential == null - ? null - : UserWeb( - auth, - MultiFactorWeb(auth, multiFactor(webUserCredential.user!)), - webUserCredential.user!, - webAuth, - ), - ); + auth: auth, + additionalUserInfo: convertWebAdditionalUserInfo( + webUserCredential?.additionalUserInfo, + ), + credential: convertWebOAuthCredential(webUserCredential), + user: webUserCredential == null + ? null + : UserWeb( + auth, + MultiFactorWeb(auth, multiFactor(webUserCredential.user!)), + webUserCredential.user!, + webAuth, + ), + ); } diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/interop/auth.dart b/packages/firebase_auth/firebase_auth_web/lib/src/interop/auth.dart index 3002de1e878d..f00f6a66099d 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/interop/auth.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/interop/auth.dart @@ -64,7 +64,7 @@ class UserInfo /// Creates a new UserInfo from a [jsObject]. UserInfo._fromJsObject(auth_interop.UserInfoJsImpl jsObject) - : super.fromJsObject(jsObject as T); + : super.fromJsObject(jsObject as T); } /// User account. @@ -92,8 +92,10 @@ class User extends UserInfo { // explicitly typing the param as dynamic to work-around // https://github.com/dart-lang/sdk/issues/33537 // ignore: unnecessary_lambdas, false positive, data is dynamic - .map((dynamic data) => - UserInfo._fromJsObject(data)) + .map( + (dynamic data) => + UserInfo._fromJsObject(data), + ) .toList(); /// Refresh token for the user account. @@ -113,7 +115,7 @@ class User extends UserInfo { } User._fromJsObject(auth_interop.UserJsImpl jsObject) - : super._fromJsObject(jsObject); + : super._fromJsObject(jsObject); /// Deletes and signs out the user. Future delete() => jsObject.delete().toDart; @@ -133,21 +135,25 @@ class User extends UserInfo { /// Links the user account with the given credentials, and returns any /// available additional user information, such as user name. Future linkWithCredential( - auth_interop.OAuthCredential? credential) => - auth_interop - .linkWithCredential(jsObject, credential) - .toDart - .then(UserCredential.fromJsObject); + auth_interop.OAuthCredential? credential, + ) => auth_interop + .linkWithCredential(jsObject, credential) + .toDart + .then(UserCredential.fromJsObject); /// Links the user account with the given [phoneNumber] in E.164 format /// (e.g. +16505550101) and [applicationVerifier]. Future linkWithPhoneNumber( - String phoneNumber, ApplicationVerifier applicationVerifier) => - auth_interop - .linkWithPhoneNumber( - jsObject, phoneNumber.toJS, applicationVerifier.jsObject) - .toDart - .then(ConfirmationResult.fromJsObject); + String phoneNumber, + ApplicationVerifier applicationVerifier, + ) => auth_interop + .linkWithPhoneNumber( + jsObject, + phoneNumber.toJS, + applicationVerifier.jsObject, + ) + .toDart + .then(ConfirmationResult.fromJsObject); /// Links the authenticated [provider] to the user account using /// a pop-up based OAuth flow. @@ -165,11 +171,11 @@ class User extends UserInfo { /// Re-authenticates a user using a fresh credential, and returns any /// available additional user information, such as user name. Future reauthenticateWithCredential( - auth_interop.OAuthCredential credential) => - auth_interop - .reauthenticateWithCredential(jsObject, credential) - .toDart - .then(UserCredential.fromJsObject); + auth_interop.OAuthCredential credential, + ) => auth_interop + .reauthenticateWithCredential(jsObject, credential) + .toDart + .then(UserCredential.fromJsObject); /// Re-authenticates a user using a fresh credential. /// Use before operations such as [updatePassword] that require tokens @@ -177,12 +183,16 @@ class User extends UserInfo { /// /// The user's phone number is in E.164 format (e.g. +16505550101). Future reauthenticateWithPhoneNumber( - String phoneNumber, ApplicationVerifier applicationVerifier) => - auth_interop - .reauthenticateWithPhoneNumber( - jsObject, phoneNumber.toJS, applicationVerifier.jsObject) - .toDart - .then(ConfirmationResult.fromJsObject); + String phoneNumber, + ApplicationVerifier applicationVerifier, + ) => auth_interop + .reauthenticateWithPhoneNumber( + jsObject, + phoneNumber.toJS, + applicationVerifier.jsObject, + ) + .toDart + .then(ConfirmationResult.fromJsObject); /// Reauthenticates a user with the specified provider using /// a pop-up based OAuth flow. @@ -220,17 +230,18 @@ class User extends UserInfo { /// /// The Android package name and iOS bundle ID will be respected only if /// they are configured in the same Firebase Auth project used. - Future sendEmailVerification( - [auth_interop.ActionCodeSettings? actionCodeSettings]) => - auth_interop.sendEmailVerification(jsObject, actionCodeSettings).toDart; + Future sendEmailVerification([ + auth_interop.ActionCodeSettings? actionCodeSettings, + ]) => auth_interop.sendEmailVerification(jsObject, actionCodeSettings).toDart; /// Sends a verification email to a new email address. The user's email will be updated to the new one /// after being verified. - Future verifyBeforeUpdateEmail(String newEmail, - [auth_interop.ActionCodeSettings? actionCodeSettings]) => - auth_interop - .verifyBeforeUpdateEmail(jsObject, newEmail.toJS, actionCodeSettings) - .toDart; + Future verifyBeforeUpdateEmail( + String newEmail, [ + auth_interop.ActionCodeSettings? actionCodeSettings, + ]) => auth_interop + .verifyBeforeUpdateEmail(jsObject, newEmail.toJS, actionCodeSettings) + .toDart; /// Unlinks a provider with [providerId] from a user account. Future unlink(String providerId) => auth_interop @@ -250,8 +261,8 @@ class User extends UserInfo { /// Updates the user's phone number. Future updatePhoneNumber( - auth_interop.OAuthCredential? phoneCredential) => - auth_interop.updatePhoneNumber(jsObject, phoneCredential).toDart; + auth_interop.OAuthCredential? phoneCredential, + ) => auth_interop.updatePhoneNumber(jsObject, phoneCredential).toDart; /// Updates a user's profile data. Future updateProfile(auth_interop.UserProfile profile) => @@ -287,7 +298,7 @@ class User extends UserInfo { /// See https://firebase.google.com/docs/reference/js/firebase.auth.IDTokenResult.html class IdTokenResult extends JsObjectWrapper { IdTokenResult._fromJsObject(auth_interop.IdTokenResultImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); /// The authentication time. /// @@ -374,8 +385,10 @@ class Auth extends JsObjectWrapper { final errorWrapper = (JSAny e) => _changeController!.addError(e); - final unsubscribe = - jsObject.onAuthStateChanged(nextWrapper.toJS, errorWrapper.toJS); + final unsubscribe = jsObject.onAuthStateChanged( + nextWrapper.toJS, + errorWrapper.toJS, + ); await completer.future; unsubscribe.callAsFunction(); @@ -404,7 +417,7 @@ class Auth extends JsObjectWrapper { return 'no-op'; } -// purely for debug mode and tracking listeners to clean up on "hot restart" + // purely for debug mode and tracking listeners to clean up on "hot restart" final Map _idTokenStateListeners = {}; String _idTokenStateWindowsKey() { if (kDebugMode) { @@ -438,13 +451,12 @@ class Auth extends JsObjectWrapper { void startListen() { assert(_onAuthUnsubscribe == null); - final unsubscribe = - jsObject.onAuthStateChanged(nextWrapper.toJS, errorWrapper.toJS); - _onAuthUnsubscribe = unsubscribe; - setWindowsListener( - authStateKey, - unsubscribe, + final unsubscribe = jsObject.onAuthStateChanged( + nextWrapper.toJS, + errorWrapper.toJS, ); + _onAuthUnsubscribe = unsubscribe; + setWindowsListener(authStateKey, unsubscribe); } void stopListen() { @@ -488,13 +500,12 @@ class Auth extends JsObjectWrapper { void startListen() { assert(_onIdTokenChangedUnsubscribe == null); - final unsubscribe = - jsObject.onIdTokenChanged(nextWrapper.toJS, errorWrapper.toJS); - _onIdTokenChangedUnsubscribe = unsubscribe; - setWindowsListener( - idTokenKey, - unsubscribe, + final unsubscribe = jsObject.onIdTokenChanged( + nextWrapper.toJS, + errorWrapper.toJS, ); + _onIdTokenChangedUnsubscribe = unsubscribe; + setWindowsListener(idTokenKey, unsubscribe); } void stopListen() { @@ -519,7 +530,7 @@ class Auth extends JsObjectWrapper { } Auth._fromJsObject(auth_interop.AuthJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); /// Applies a verification [oobCode] sent to the user by e-mail or by other /// out-of-band mechanism. @@ -579,9 +590,12 @@ class Auth extends JsObjectWrapper { /// if sign is unsuccessful. /// The [UserCredential] with a null [User] is returned if no redirect /// operation was called. - Future getRedirectResult() => - auth_interop.getRedirectResult(jsObject).toDart.then( - (value) => value == null ? null : UserCredential.fromJsObject(value)); + Future getRedirectResult() => auth_interop + .getRedirectResult(jsObject) + .toDart + .then( + (value) => value == null ? null : UserCredential.fromJsObject(value), + ); /// Sends a sign-in email link to the user with the specified email. /// @@ -593,11 +607,12 @@ class Auth extends JsObjectWrapper { /// To complete sign in with the email link, call /// [Auth.signInWithEmailLink] with the email address and /// the email link supplied in the email sent to the user. - Future sendSignInLinkToEmail(String email, - [auth_interop.ActionCodeSettings? actionCodeSettings]) => - auth_interop - .sendSignInLinkToEmail(jsObject, email.toJS, actionCodeSettings) - .toDart; + Future sendSignInLinkToEmail( + String email, [ + auth_interop.ActionCodeSettings? actionCodeSettings, + ]) => auth_interop + .sendSignInLinkToEmail(jsObject, email.toJS, actionCodeSettings) + .toDart; /// Changes the current type of persistence on the current Auth instance for /// the currently saved Auth session and applies this type of persistence @@ -654,20 +669,21 @@ class Auth extends JsObjectWrapper { /// /// The Android package name and iOS bundle ID will be respected only if /// they are configured in the same Firebase Auth project used. - Future sendPasswordResetEmail(String email, - [auth_interop.ActionCodeSettings? actionCodeSettings]) => - auth_interop - .sendPasswordResetEmail(jsObject, email.toJS, actionCodeSettings) - .toDart; + Future sendPasswordResetEmail( + String email, [ + auth_interop.ActionCodeSettings? actionCodeSettings, + ]) => auth_interop + .sendPasswordResetEmail(jsObject, email.toJS, actionCodeSettings) + .toDart; /// Asynchronously signs in with the given credentials, and returns any /// available additional user information, such as user name. Future signInWithCredential( - auth_interop.OAuthCredential credential) => - auth_interop - .signInWithCredential(jsObject, credential) - .toDart - .then(UserCredential.fromJsObject); + auth_interop.OAuthCredential credential, + ) => auth_interop + .signInWithCredential(jsObject, credential) + .toDart + .then(UserCredential.fromJsObject); /// Asynchronously signs in as an anonymous user. // @@ -714,11 +730,12 @@ class Auth extends JsObjectWrapper { /// user, and the password is used to access the user's account in your /// Firebase project. Future signInWithEmailAndPassword( - String email, String password) => - auth_interop - .signInWithEmailAndPassword(jsObject, email.toJS, password.toJS) - .toDart - .then(UserCredential.fromJsObject); + String email, + String password, + ) => auth_interop + .signInWithEmailAndPassword(jsObject, email.toJS, password.toJS) + .toDart + .then(UserCredential.fromJsObject); /// Signs in using [email] and [emailLink] link. Future signInWithEmailLink(String email, String emailLink) => @@ -749,9 +766,7 @@ class Auth extends JsObjectWrapper { ) .toDart; - return ConfirmationResult.fromJsObject( - result, - ); + return ConfirmationResult.fromJsObject(result); } /// Signs in using a popup-based OAuth authentication flow with the @@ -821,19 +836,26 @@ class EmailAuthProvider /// Creates a new EmailAuthProvider from a [jsObject]. EmailAuthProvider.fromJsObject(auth_interop.EmailAuthProviderJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); /// Creates a credential for e-mail. static auth_interop.OAuthCredential credential( - String email, String password) => + String email, + String password, + ) => auth_interop.EmailAuthProviderJsImpl.credential(email.toJS, password.toJS) as auth_interop.OAuthCredential; /// Creates a credential for e-mail with link. static auth_interop.OAuthCredential credentialWithLink( - String email, String emailLink) => + String email, + String emailLink, + ) => auth_interop.EmailAuthProviderJsImpl.credentialWithLink( - email.toJS, emailLink.toJS) as auth_interop.OAuthCredential; + email.toJS, + emailLink.toJS, + ) + as auth_interop.OAuthCredential; } /// Facebook auth provider. @@ -846,12 +868,13 @@ class FacebookAuthProvider /// Creates a new FacebookAuthProvider. factory FacebookAuthProvider() => FacebookAuthProvider.fromJsObject( - auth_interop.FacebookAuthProviderJsImpl()); + auth_interop.FacebookAuthProviderJsImpl(), + ); /// Creates a new FacebookAuthProvider from a [jsObject]. FacebookAuthProvider.fromJsObject( - auth_interop.FacebookAuthProviderJsImpl jsObject) - : super.fromJsObject(jsObject); + auth_interop.FacebookAuthProviderJsImpl jsObject, + ) : super.fromJsObject(jsObject); /// Adds additional OAuth 2.0 scopes that you want to request from the /// authentication provider. @@ -892,8 +915,8 @@ class GithubAuthProvider /// Creates a new GithubAuthProvider from a [jsObject]. GithubAuthProvider.fromJsObject( - auth_interop.GithubAuthProviderJsImpl jsObject) - : super.fromJsObject(jsObject); + auth_interop.GithubAuthProviderJsImpl jsObject, + ) : super.fromJsObject(jsObject); /// Adds additional OAuth 2.0 scopes that you want to request from the /// authentication provider. @@ -934,8 +957,8 @@ class GoogleAuthProvider /// Creates a new GoogleAuthProvider from a [jsObject]. GoogleAuthProvider.fromJsObject( - auth_interop.GoogleAuthProviderJsImpl jsObject) - : super.fromJsObject(jsObject); + auth_interop.GoogleAuthProviderJsImpl jsObject, + ) : super.fromJsObject(jsObject); /// Adds additional OAuth 2.0 scopes that you want to request from the /// authentication provider. @@ -960,10 +983,13 @@ class GoogleAuthProvider /// Creates a credential for Google. /// At least one of [idToken] and [accessToken] is required. - static auth_interop.OAuthCredential credential( - [String? idToken, String? accessToken]) => - auth_interop.GoogleAuthProviderJsImpl.credential( - idToken?.toJS, accessToken?.toJS); + static auth_interop.OAuthCredential credential([ + String? idToken, + String? accessToken, + ]) => auth_interop.GoogleAuthProviderJsImpl.credential( + idToken?.toJS, + accessToken?.toJS, + ); } /// OAuth auth provider. @@ -972,11 +998,12 @@ class GoogleAuthProvider class OAuthProvider extends AuthProvider { /// Creates a new OAuthProvider. factory OAuthProvider(String providerId) => OAuthProvider.fromJsObject( - auth_interop.OAuthProviderJsImpl(providerId.toJS)); + auth_interop.OAuthProviderJsImpl(providerId.toJS), + ); /// Creates a new OAuthProvider from a [jsObject]. OAuthProvider.fromJsObject(auth_interop.OAuthProviderJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); /// Adds additional OAuth 2.0 scopes that you want to request from the /// authentication provider. @@ -998,13 +1025,13 @@ class OAuthProvider extends AuthProvider { /// Creates a credential for Google. /// At least one of [idToken] and [accessToken] is required. auth_interop.OAuthCredential credential( - auth_interop.OAuthCredentialOptions credentialOptions) => - jsObject.credential(credentialOptions); + auth_interop.OAuthCredentialOptions credentialOptions, + ) => jsObject.credential(credentialOptions); /// Used to extract the underlying OAuthCredential from a UserCredential. static auth_interop.OAuthCredential? credentialFromResult( - auth_interop.UserCredentialJsImpl userCredential) => - auth_interop.OAuthProviderJsImpl.credentialFromResult(userCredential); + auth_interop.UserCredentialJsImpl userCredential, + ) => auth_interop.OAuthProviderJsImpl.credentialFromResult(userCredential); } /// Twitter auth provider. @@ -1017,12 +1044,13 @@ class TwitterAuthProvider /// Creates a new TwitterAuthProvider. factory TwitterAuthProvider() => TwitterAuthProvider.fromJsObject( - auth_interop.TwitterAuthProviderJsImpl()); + auth_interop.TwitterAuthProviderJsImpl(), + ); /// Creates a new TwitterAuthProvider from a [jsObject]. TwitterAuthProvider.fromJsObject( - auth_interop.TwitterAuthProviderJsImpl jsObject) - : super.fromJsObject(jsObject); + auth_interop.TwitterAuthProviderJsImpl jsObject, + ) : super.fromJsObject(jsObject); /// Sets the OAuth custom parameters to pass in a Twitter OAuth request /// for popup and redirect sign-in operations. @@ -1040,7 +1068,9 @@ class TwitterAuthProvider /// Creates a credential for Twitter. static auth_interop.OAuthCredential credential(String token, String secret) => auth_interop.TwitterAuthProviderJsImpl.credential( - token.toJS, secret.toJS); + token.toJS, + secret.toJS, + ); } /// SAML auth provider. @@ -1051,16 +1081,17 @@ class SAMLAuthProvider /// Creates a new SAMLAuthProvider with the providerId. /// The providerId must start with "saml." factory SAMLAuthProvider(String providerId) => SAMLAuthProvider.fromJsObject( - auth_interop.SAMLAuthProviderJsImpl(providerId)); + auth_interop.SAMLAuthProviderJsImpl(providerId), + ); /// Creates a new SAMLAuthProvider from a [jsObject]. SAMLAuthProvider.fromJsObject(auth_interop.SAMLAuthProviderJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); /// Used to extract the underlying OAuthCredential from a UserCredential. static auth_interop.OAuthCredential? credentialFromResult( - auth_interop.UserCredentialJsImpl userCredential) => - auth_interop.SAMLAuthProviderJsImpl.credentialFromResult(userCredential); + auth_interop.UserCredentialJsImpl userCredential, + ) => auth_interop.SAMLAuthProviderJsImpl.credentialFromResult(userCredential); } /// Phone number auth provider. @@ -1073,14 +1104,15 @@ class PhoneAuthProvider /// Creates a new PhoneAuthProvider with the optional [Auth] instance /// in which sign-ins should occur. - factory PhoneAuthProvider([Auth? auth]) => - PhoneAuthProvider.fromJsObject(auth != null - ? auth_interop.PhoneAuthProviderJsImpl(auth.jsObject) - : auth_interop.PhoneAuthProviderJsImpl()); + factory PhoneAuthProvider([Auth? auth]) => PhoneAuthProvider.fromJsObject( + auth != null + ? auth_interop.PhoneAuthProviderJsImpl(auth.jsObject) + : auth_interop.PhoneAuthProviderJsImpl(), + ); /// Creates a new PhoneAuthProvider from a [jsObject]. PhoneAuthProvider.fromJsObject(auth_interop.PhoneAuthProviderJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); /// Starts a phone number authentication flow by sending a verification code /// to the given [phoneNumber] in E.164 format (e.g. +16505550101). @@ -1089,26 +1121,31 @@ class PhoneAuthProvider /// /// For abuse prevention, this method also requires an [ApplicationVerifier]. Future verifyPhoneNumber( - dynamic phoneOptions, ApplicationVerifier applicationVerifier) => - jsObject - .verifyPhoneNumber(phoneOptions, applicationVerifier.jsObject) - .toDart - .then((value) => (value! as JSString).toDart); + dynamic phoneOptions, + ApplicationVerifier applicationVerifier, + ) => jsObject + .verifyPhoneNumber(phoneOptions, applicationVerifier.jsObject) + .toDart + .then((value) => (value! as JSString).toDart); /// Creates a phone auth credential given the verification ID /// from [verifyPhoneNumber] and the [verificationCode] that was sent to the /// user's mobile device. static auth_interop.PhoneAuthCredentialJsImpl credential( - String verificationId, String verificationCode) => - auth_interop.PhoneAuthProviderJsImpl.credential( - verificationId.toJS, verificationCode.toJS); + String verificationId, + String verificationCode, + ) => auth_interop.PhoneAuthProviderJsImpl.credential( + verificationId.toJS, + verificationCode.toJS, + ); } /// A verifier for domain verification and abuse prevention. /// /// See: abstract class ApplicationVerifier< - T extends auth_interop.ApplicationVerifierJsImpl> + T extends auth_interop.ApplicationVerifierJsImpl +> extends JsObjectWrapper { /// Returns the type of application verifier (e.g. 'recaptcha'). String get type => jsObject.type.toDart; @@ -1157,7 +1194,10 @@ class RecaptchaVerifier /// } /// }); factory RecaptchaVerifier( - JSAny container, Map parameters, Auth auth) { + JSAny container, + Map parameters, + Auth auth, + ) { return RecaptchaVerifier.fromJsObject( auth_interop.RecaptchaVerifierJsImpl( auth.jsObject, @@ -1169,7 +1209,7 @@ class RecaptchaVerifier /// Creates a new RecaptchaVerifier from a [jsObject]. RecaptchaVerifier.fromJsObject(auth_interop.RecaptchaVerifierJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); /// Clears the reCAPTCHA widget from the page and destroys the current instance. void clear() => jsObject.clear(); @@ -1192,8 +1232,8 @@ class ConfirmationResult /// Creates a new ConfirmationResult from a [jsObject]. ConfirmationResult.fromJsObject( - auth_interop.ConfirmationResultJsImpl jsObject) - : super.fromJsObject(jsObject); + auth_interop.ConfirmationResultJsImpl jsObject, + ) : super.fromJsObject(jsObject); /// Finishes a phone number sign-in, link, or reauthentication, given /// the code that was sent to the user's mobile device. @@ -1218,11 +1258,12 @@ class UserCredential /// Returns additional user information from a federated identity provider. AdditionalUserInfo? get additionalUserInfo => AdditionalUserInfo.fromJsObject( - auth_interop.getAdditionalUserInfo(jsObject)); + auth_interop.getAdditionalUserInfo(jsObject), + ); /// Creates a new UserCredential from a [jsObject]. UserCredential.fromJsObject(auth_interop.UserCredentialJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); } /// A structure containing additional user information from @@ -1247,6 +1288,6 @@ class AdditionalUserInfo /// Creates a new AdditionalUserInfo from a [jsObject]. AdditionalUserInfo.fromJsObject( - auth_interop.AdditionalUserInfoJsImpl jsObject) - : super.fromJsObject(jsObject); + auth_interop.AdditionalUserInfoJsImpl jsObject, + ) : super.fromJsObject(jsObject); } diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/interop/auth_interop.dart b/packages/firebase_auth/firebase_auth_web/lib/src/interop/auth_interop.dart index 7d66865f0d35..64d4b345660a 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/interop/auth_interop.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/interop/auth_interop.dart @@ -48,20 +48,19 @@ external Persistence indexedDBLocalPersistence; @JS() external JSPromise checkActionCode( - AuthJsImpl auth, JSString oobCode); + AuthJsImpl auth, + JSString oobCode, +); @JS() -external JSPromise/**/ confirmPasswordReset( +external JSPromise /**/ confirmPasswordReset( AuthJsImpl auth, JSString oobCode, JSString newPassword, ); @JS() -external void connectAuthEmulator( - AuthJsImpl auth, - JSString origin, -); +external void connectAuthEmulator(AuthJsImpl auth, JSString origin); @JS() external JSPromise setPersistence(AuthJsImpl auth, Persistence persistence); @@ -75,25 +74,24 @@ external JSPromise createUserWithEmailAndPassword( @JS() external AdditionalUserInfoJsImpl getAdditionalUserInfo( - UserCredentialJsImpl userCredential); + UserCredentialJsImpl userCredential, +); @JS() -external JSPromise deleteUser( - UserJsImpl user, -); +external JSPromise deleteUser(UserJsImpl user); @JS() external JSPromise> fetchSignInMethodsForEmail( - AuthJsImpl auth, JSString email); + AuthJsImpl auth, + JSString email, +); @JS() external JSBoolean isSignInWithEmailLink(JSString emailLink); @JS() // Promise -external JSPromise getRedirectResult( - AuthJsImpl auth, -); +external JSPromise getRedirectResult(AuthJsImpl auth); @JS() external JSPromise sendSignInLinkToEmail( @@ -233,10 +231,7 @@ external JSPromise unlink(UserJsImpl user, JSString providerId); external JSPromise updateEmail(UserJsImpl user, JSString newEmail); @JS() -external JSPromise updatePassword( - UserJsImpl user, - JSString newPassword, -); +external JSPromise updatePassword(UserJsImpl user, JSString newPassword); @JS() external JSPromise updatePhoneNumber( @@ -245,19 +240,14 @@ external JSPromise updatePhoneNumber( ); @JS() -external JSPromise updateProfile( - UserJsImpl user, - UserProfile profile, -); +external JSPromise updateProfile(UserJsImpl user, UserProfile profile); @JS() external void useDeviceLanguage(AuthJsImpl auth); /// https://firebase.google.com/docs/reference/js/auth.md#multifactor @JS() -external MultiFactorUserJsImpl multiFactor( - UserJsImpl user, -); +external MultiFactorUserJsImpl multiFactor(UserJsImpl user); /// https://firebase.google.com/docs/reference/js/auth.md#multifactor @JS() @@ -319,8 +309,9 @@ extension type UserJsImpl._(JSObject _) implements UserInfoJsImpl { external UserMetadata get metadata; external JSPromise delete(); external JSPromise getIdToken([JSBoolean? opt_forceRefresh]); - external JSPromise getIdTokenResult( - [JSBoolean? opt_forceRefresh]); + external JSPromise getIdTokenResult([ + JSBoolean? opt_forceRefresh, + ]); external JSPromise reload(); external JSObject toJSON(); } @@ -465,8 +456,10 @@ abstract class GoogleAuthProviderJsImpl extends AuthProviderJsImpl { external factory GoogleAuthProviderJsImpl(); external static JSString get PROVIDER_ID; - external static OAuthCredential credential( - [JSString? idToken, JSString? accessToken]); + external static OAuthCredential credential([ + JSString? idToken, + JSString? accessToken, + ]); } extension GoogleAuthProviderJsImplExtension on GoogleAuthProviderJsImpl { @@ -490,9 +483,7 @@ class OAuthProviderJsImpl extends AuthProviderJsImpl { extension OAuthProviderJsImplExtension on OAuthProviderJsImpl { external OAuthProviderJsImpl addScope(JSString scope); - external OAuthProviderJsImpl setCustomParameters( - JSAny customOAuthParameters, - ); + external OAuthProviderJsImpl setCustomParameters(JSAny customOAuthParameters); external OAuthCredential credential(OAuthCredentialOptions credentialOptions); } @@ -771,7 +762,7 @@ extension AdditionalUserInfoJsImplExtension on AdditionalUserInfoJsImpl { @staticInterop @anonymous class AuthSettings { -// external factory AuthSettings({JSBoolean appVerificationDisabledForTesting}); + // external factory AuthSettings({JSBoolean appVerificationDisabledForTesting}); } extension AuthSettingsExtension on AuthSettings { @@ -792,7 +783,9 @@ class MultiFactorUserJsImpl {} extension MultiFactorUserJsImplExtension on MultiFactorUserJsImpl { external JSArray get enrolledFactors; external JSPromise enroll( - MultiFactorAssertionJsImpl assertion, JSString? displayName); + MultiFactorAssertionJsImpl assertion, + JSString? displayName, + ); external JSPromise getSession(); external JSPromise unenroll(JSAny /* MultiFactorInfo | string */ option); } @@ -825,7 +818,8 @@ extension MultiFactorResolverJsImplExtension on MultiFactorResolverJsImpl { external JSArray get hints; external MultiFactorSessionJsImpl get session; external JSPromise resolveSignIn( - MultiFactorAssertionJsImpl assertion); + MultiFactorAssertionJsImpl assertion, + ); } /// https://firebase.google.com/docs/reference/js/auth.multifactorresolver @@ -861,7 +855,8 @@ extension PhoneMultiFactorEnrollInfoOptionsJsImplExtension class PhoneMultiFactorGeneratorJsImpl { external static JSString get FACTOR_ID; external static PhoneMultiFactorAssertionJsImpl? assertion( - PhoneAuthCredentialJsImpl credential); + PhoneAuthCredentialJsImpl credential, + ); } extension PhoneMultiFactorGeneratorJsImplExtension @@ -885,11 +880,16 @@ extension type TotpSecretJsImpl._(JSObject _) implements JSObject { class TotpMultiFactorGeneratorJsImpl { external static JSString get FACTOR_ID; external static TotpMultiFactorAssertionJsImpl? assertionForEnrollment( - TotpSecretJsImpl secret, JSString oneTimePassword); + TotpSecretJsImpl secret, + JSString oneTimePassword, + ); external static TotpMultiFactorAssertionJsImpl? assertionForSignIn( - JSString enrollmentId, JSString oneTimePassword); + JSString enrollmentId, + JSString oneTimePassword, + ); external static JSPromise generateSecret( - MultiFactorSessionJsImpl session); + MultiFactorSessionJsImpl session, + ); } extension TotpMultiFactorGeneratorJsImplExtension @@ -913,7 +913,8 @@ class TotpMultiFactorAssertionJsImpl extends MultiFactorAssertionJsImpl {} @anonymous class PhoneAuthCredentialJsImpl extends AuthCredential { external static PhoneAuthCredentialJsImpl fromJSON( - JSAny /*object | string*/ json); + JSAny /*object | string*/ json, + ); } extension PhoneAuthCredentialJsImplExtension on PhoneAuthCredentialJsImpl { diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/interop/multi_factor.dart b/packages/firebase_auth/firebase_auth_web/lib/src/interop/multi_factor.dart index 5d1645e553aa..e12cf2cacc33 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/interop/multi_factor.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/interop/multi_factor.dart @@ -21,9 +21,12 @@ MultiFactorUser multiFactor(auth.User user) { /// Given an AppJSImp, return the Auth instance. MultiFactorResolver getMultiFactorResolver( - auth.Auth auth, auth.AuthError error) { + auth.Auth auth, + auth.AuthError error, +) { return MultiFactorResolver.fromJsObject( - auth_interop.getMultiFactorResolver(auth.jsObject, error)); + auth_interop.getMultiFactorResolver(auth.jsObject, error), + ); } /// The Firebase MultiFactorUser service class. @@ -35,12 +38,13 @@ class MultiFactorUser /// Creates a new Auth from a [jsObject]. static MultiFactorUser getInstance( - auth_interop.MultiFactorUserJsImpl jsObject) { + auth_interop.MultiFactorUserJsImpl jsObject, + ) { return _expando[jsObject] ??= MultiFactorUser._fromJsObject(jsObject); } MultiFactorUser._fromJsObject(auth_interop.MultiFactorUserJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); /// Returns a list of the user's enrolled second factors. List get enrolledFactors => @@ -97,8 +101,8 @@ class MultiFactorInfo class PhoneMultiFactorInfo extends MultiFactorInfo { PhoneMultiFactorInfo.fromJsObject( - auth_interop.PhoneMultiFactorInfoJsImpl jsObject) - : super.fromJsObject(jsObject); + auth_interop.PhoneMultiFactorInfoJsImpl jsObject, + ) : super.fromJsObject(jsObject); /// The user friendly name of the current second factor. String get phoneNumber => jsObject.phoneNumber.toDart; @@ -107,15 +111,15 @@ class PhoneMultiFactorInfo class TotpMultiFactorInfo extends MultiFactorInfo { TotpMultiFactorInfo.fromJsObject( - auth_interop.TotpMultiFactorInfoJsImpl jsObject) - : super.fromJsObject(jsObject); + auth_interop.TotpMultiFactorInfoJsImpl jsObject, + ) : super.fromJsObject(jsObject); } /// https://firebase.google.com/docs/reference/js/auth.multifactorsession.md#multifactorsession_interface class MultiFactorSession extends JsObjectWrapper { MultiFactorSession.fromJsObject(auth.MultiFactorSessionJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); } /// https://firebase.google.com/docs/reference/js/auth.multifactorsession.md#multifactorsession_interface @@ -130,15 +134,15 @@ class MultiFactorAssertion class PhoneMultiFactorAssertion extends MultiFactorAssertion { PhoneMultiFactorAssertion.fromJsObject( - auth.PhoneMultiFactorAssertionJsImpl jsObject) - : super.fromJsObject(jsObject); + auth.PhoneMultiFactorAssertionJsImpl jsObject, + ) : super.fromJsObject(jsObject); } /// https://firebase.google.com/docs/reference/js/auth#getmultifactorresolver class MultiFactorResolver extends JsObjectWrapper { MultiFactorResolver.fromJsObject(auth.MultiFactorResolverJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); List get hints => jsObject.hints.toDart .map(fromJsMultiFactorInfo) @@ -158,10 +162,12 @@ class MultiFactorResolver MultiFactorInfo fromJsMultiFactorInfo(auth.MultiFactorInfoJsImpl e) { if (e.factorId.toDart == 'phone') { return PhoneMultiFactorInfo.fromJsObject( - e as auth_interop.PhoneMultiFactorInfoJsImpl); + e as auth_interop.PhoneMultiFactorInfoJsImpl, + ); } else if (e.factorId.toDart == 'totp') { return TotpMultiFactorInfo.fromJsObject( - e as auth_interop.TotpMultiFactorInfoJsImpl); + e as auth_interop.TotpMultiFactorInfoJsImpl, + ); } else { return MultiFactorInfo.fromJsObject(e); } @@ -171,13 +177,15 @@ MultiFactorInfo fromJsMultiFactorInfo(auth.MultiFactorInfoJsImpl e) { class PhoneMultiFactorGenerator extends JsObjectWrapper { PhoneMultiFactorGenerator.fromJsObject( - auth.PhoneMultiFactorGeneratorJsImpl jsObject) - : super.fromJsObject(jsObject); + auth.PhoneMultiFactorGeneratorJsImpl jsObject, + ) : super.fromJsObject(jsObject); static PhoneMultiFactorAssertion assertion( - auth.PhoneAuthCredentialJsImpl credential) { + auth.PhoneAuthCredentialJsImpl credential, + ) { return PhoneMultiFactorAssertion.fromJsObject( - auth_interop.PhoneMultiFactorGeneratorJsImpl.assertion(credential)!); + auth_interop.PhoneMultiFactorGeneratorJsImpl.assertion(credential)!, + ); } } @@ -185,13 +193,13 @@ class PhoneMultiFactorGenerator class TotpMultiFactorAssertion extends MultiFactorAssertion { TotpMultiFactorAssertion.fromJsObject( - auth.TotpMultiFactorAssertionJsImpl jsObject) - : super.fromJsObject(jsObject); + auth.TotpMultiFactorAssertionJsImpl jsObject, + ) : super.fromJsObject(jsObject); } class TotpSecret extends JsObjectWrapper { TotpSecret.fromJsObject(auth_interop.TotpSecretJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); int get codeInterval => jsObject.codeIntervalSeconds.toDartInt; int get codeLength => jsObject.codeLength.toDartInt; @@ -208,19 +216,25 @@ class TotpSecret extends JsObjectWrapper { class TotpMultiFactorGenerator extends JsObjectWrapper { TotpMultiFactorGenerator.fromJsObject( - auth.TotpMultiFactorGeneratorJsImpl jsObject) - : super.fromJsObject(jsObject); + auth.TotpMultiFactorGeneratorJsImpl jsObject, + ) : super.fromJsObject(jsObject); static TotpMultiFactorAssertion assertionForSignIn( - String enrollmentId, String oneTimePassword) { + String enrollmentId, + String oneTimePassword, + ) { return TotpMultiFactorAssertion.fromJsObject( auth_interop.TotpMultiFactorGeneratorJsImpl.assertionForSignIn( - enrollmentId.toJS, oneTimePassword.toJS)!, + enrollmentId.toJS, + oneTimePassword.toJS, + )!, ); } static TotpMultiFactorAssertion assertionForEnrollment( - TotpSecret secret, String oneTimePassword) { + TotpSecret secret, + String oneTimePassword, + ) { return TotpMultiFactorAssertion.fromJsObject( auth_interop.TotpMultiFactorGeneratorJsImpl.assertionForEnrollment( secret.jsObject, @@ -231,8 +245,7 @@ class TotpMultiFactorGenerator static Future generateSecret(MultiFactorSession session) { return auth_interop.TotpMultiFactorGeneratorJsImpl.generateSecret( - session.jsObject) - .toDart - .then(TotpSecret.fromJsObject); + session.jsObject, + ).toDart.then(TotpSecret.fromJsObject); } } diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/utils/web_utils.dart b/packages/firebase_auth/firebase_auth_web/lib/src/utils/web_utils.dart index 1dd2681fc52e..0fbb7515491b 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/utils/web_utils.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/utils/web_utils.dart @@ -28,17 +28,15 @@ bool _hasFirebaseAuthErrorCodeAndMessage(JSError e) { } } -R guardAuthExceptions( - R Function() cb, { - auth_interop.Auth? auth, -}) { +R guardAuthExceptions(R Function() cb, {auth_interop.Auth? auth}) { try { final value = cb(); if (value is Future) { return value.catchError((err, stack) { - final exception = getFirebaseAuthException(err, auth); - return Error.throwWithStackTrace(exception, stack); - }) as R; + final exception = getFirebaseAuthException(err, auth); + return Error.throwWithStackTrace(exception, stack); + }) + as R; } return value; @@ -64,8 +62,9 @@ FirebaseAuthException getFirebaseAuthException( auth_interop.Auth? auth, ]) { final exception = objectException as JSError; - final authJsCredential = - auth_interop.OAuthProviderJsImpl.credentialFromError(exception); + final authJsCredential = auth_interop.OAuthProviderJsImpl.credentialFromError( + exception, + ); OAuthCredential? credential; @@ -166,14 +165,16 @@ MultiFactorInfo fromInteropMultiFactorInfo( /// Converts a [auth_interop.ActionCodeInfo] into a [ActionCodeInfo]. ActionCodeInfo? convertWebActionCodeInfo( - auth_interop.ActionCodeInfo? webActionCodeInfo) { + auth_interop.ActionCodeInfo? webActionCodeInfo, +) { if (webActionCodeInfo == null) { return null; } return ActionCodeInfo( - operation: - _convertWebActionCodeOperation(webActionCodeInfo.operation.toDart), + operation: _convertWebActionCodeOperation( + webActionCodeInfo.operation.toDart, + ), data: ActionCodeInfoData( email: webActionCodeInfo.data.email?.toDart, previousEmail: webActionCodeInfo.data.previousEmail?.toDart, @@ -235,7 +236,8 @@ IdTokenResult convertWebIdTokenResult( /// Converts a [ActionCodeSettings] into a [auth_interop.ActionCodeSettings]. auth_interop.ActionCodeSettings? convertPlatformActionCodeSettings( - ActionCodeSettings? actionCodeSettings) { + ActionCodeSettings? actionCodeSettings, +) { if (actionCodeSettings == null) { return null; } @@ -290,8 +292,9 @@ auth_interop.AuthProvider convertPlatformAuthProvider( } if (authProvider is AppleAuthProvider) { - auth_interop.OAuthProvider oAuthProvider = - auth_interop.OAuthProvider(authProvider.providerId); + auth_interop.OAuthProvider oAuthProvider = auth_interop.OAuthProvider( + authProvider.providerId, + ); authProvider.scopes.forEach(oAuthProvider.addScope); oAuthProvider.setCustomParameters(authProvider.parameters); @@ -317,8 +320,9 @@ auth_interop.AuthProvider convertPlatformAuthProvider( } if (authProvider is MicrosoftAuthProvider) { - auth_interop.OAuthProvider oAuthProvider = - auth_interop.OAuthProvider(authProvider.providerId); + auth_interop.OAuthProvider oAuthProvider = auth_interop.OAuthProvider( + authProvider.providerId, + ); authProvider.scopes.forEach(oAuthProvider.addScope); oAuthProvider.setCustomParameters(authProvider.parameters); @@ -326,8 +330,9 @@ auth_interop.AuthProvider convertPlatformAuthProvider( } if (authProvider is YahooAuthProvider) { - auth_interop.OAuthProvider oAuthProvider = - auth_interop.OAuthProvider(authProvider.providerId); + auth_interop.OAuthProvider oAuthProvider = auth_interop.OAuthProvider( + authProvider.providerId, + ); authProvider.scopes.forEach(oAuthProvider.addScope); oAuthProvider.setCustomParameters(authProvider.parameters); @@ -347,8 +352,9 @@ auth_interop.AuthProvider convertPlatformAuthProvider( } if (authProvider is OAuthProvider) { - auth_interop.OAuthProvider oAuthProvider = - auth_interop.OAuthProvider(authProvider.providerId); + auth_interop.OAuthProvider oAuthProvider = auth_interop.OAuthProvider( + authProvider.providerId, + ); authProvider.scopes.forEach(oAuthProvider.addScope); oAuthProvider.setCustomParameters(authProvider.parameters); @@ -364,7 +370,8 @@ auth_interop.AuthProvider convertPlatformAuthProvider( /// Converts a [auth_interop.AuthCredential] into a [AuthCredential]. AuthCredential? convertWebAuthCredential( - auth_interop.AuthCredential? authCredential) { + auth_interop.AuthCredential? authCredential, +) { if (authCredential == null) { return null; } @@ -418,7 +425,8 @@ auth_interop.OAuthCredential? convertPlatformCredential( if (credential is FacebookAuthCredential) { return auth_interop.FacebookAuthProvider.credential( - credential.accessToken!); + credential.accessToken!, + ); } if (credential is GithubAuthCredential) { @@ -441,20 +449,22 @@ auth_interop.OAuthCredential? convertPlatformCredential( if (credential is PhoneAuthCredential) { return auth_interop.PhoneAuthProvider.credential( - credential.verificationId!, - credential.smsCode!, - ) as auth_interop.OAuthCredential; + credential.verificationId!, + credential.smsCode!, + ) + as auth_interop.OAuthCredential; } if (credential is OAuthCredential) { auth_interop.OAuthCredentialOptions credentialOptions = auth_interop.OAuthCredentialOptions( - accessToken: credential.accessToken?.toJS, - rawNonce: credential.rawNonce?.toJS, - idToken: credential.idToken?.toJS, - ); - return auth_interop.OAuthProvider(credential.providerId) - .credential(credentialOptions); + accessToken: credential.accessToken?.toJS, + rawNonce: credential.rawNonce?.toJS, + idToken: credential.idToken?.toJS, + ); + return auth_interop.OAuthProvider( + credential.providerId, + ).credential(credentialOptions); } return null; @@ -482,6 +492,7 @@ String convertRecaptchaVerifierTheme(RecaptchaVerifierTheme theme) { /// Converts a [multi_factor_interop.MultiFactorSession] into a [MultiFactorSession]. MultiFactorSession convertMultiFactorSession( - multi_factor_interop.MultiFactorSession multiFactorSession) { + multi_factor_interop.MultiFactorSession multiFactorSession, +) { return MultiFactorSessionWeb('web', multiFactorSession); } diff --git a/packages/firebase_auth/firebase_auth_web/pubspec.yaml b/packages/firebase_auth/firebase_auth_web/pubspec.yaml index a38b520ae700..6211826f5023 100644 --- a/packages/firebase_auth/firebase_auth_web/pubspec.yaml +++ b/packages/firebase_auth/firebase_auth_web/pubspec.yaml @@ -6,8 +6,8 @@ version: 6.2.7 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.22.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_auth_platform_interface: ^9.0.7 diff --git a/packages/firebase_core/firebase_core/example/lib/firebase_options.dart b/packages/firebase_core/firebase_core/example/lib/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/firebase_core/firebase_core/example/lib/firebase_options.dart +++ b/packages/firebase_core/firebase_core/example/lib/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/firebase_core/firebase_core/example/lib/main.dart b/packages/firebase_core/firebase_core/example/lib/main.dart index 78a4243b8085..e43b47062844 100644 --- a/packages/firebase_core/firebase_core/example/lib/main.dart +++ b/packages/firebase_core/firebase_core/example/lib/main.dart @@ -61,9 +61,7 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( home: Scaffold( - appBar: AppBar( - title: const Text('Firebase Core example app'), - ), + appBar: AppBar(title: const Text('Firebase Core example app')), body: Padding( padding: const EdgeInsets.all(20), child: Column( @@ -85,10 +83,7 @@ class MyApp extends StatelessWidget { onPressed: initializeSecondary, child: const Text('Initialize secondary app'), ), - ElevatedButton( - onPressed: apps, - child: const Text('List apps'), - ), + ElevatedButton(onPressed: apps, child: const Text('List apps')), ElevatedButton( onPressed: options, child: const Text('List default options'), diff --git a/packages/firebase_core/firebase_core/example/pubspec.yaml b/packages/firebase_core/firebase_core/example/pubspec.yaml index d8029f187c3b..6a258dcefbaf 100644 --- a/packages/firebase_core/firebase_core/example/pubspec.yaml +++ b/packages/firebase_core/firebase_core/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the firebase_core plugin. resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core: ^4.14.0 diff --git a/packages/firebase_core/firebase_core/pubspec.yaml b/packages/firebase_core/firebase_core/pubspec.yaml index f4e8d1952d10..dda907d0c822 100644 --- a/packages/firebase_core/firebase_core/pubspec.yaml +++ b/packages/firebase_core/firebase_core/pubspec.yaml @@ -13,8 +13,8 @@ false_secrets: - example/** environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core_platform_interface: ^8.1.1 diff --git a/packages/firebase_core/firebase_core/test/firebase_core_test.dart b/packages/firebase_core/firebase_core/test/firebase_core_test.dart index 4354f38c5824..4faacdd3ad95 100755 --- a/packages/firebase_core/firebase_core/test/firebase_core_test.dart +++ b/packages/firebase_core/firebase_core/test/firebase_core_test.dart @@ -28,13 +28,16 @@ void main() { clearInteractions(mock); Firebase.delegatePackingProperty = mock; - final FirebaseAppPlatform platformApp = - FirebaseAppPlatform(testAppName, testOptions); + final FirebaseAppPlatform platformApp = FirebaseAppPlatform( + testAppName, + testOptions, + ); when(mock.apps).thenReturn([platformApp]); when(mock.app(testAppName)).thenReturn(platformApp); - when(mock.initializeApp(name: testAppName, options: testOptions)) - .thenAnswer((_) { + when( + mock.initializeApp(name: testAppName, options: testOptions), + ).thenAnswer((_) { return Future.value(platformApp); }); }); @@ -54,8 +57,10 @@ void main() { }); test('.initializeApp()', () async { - FirebaseApp initializedApp = - await Firebase.initializeApp(name: testAppName, options: testOptions); + FirebaseApp initializedApp = await Firebase.initializeApp( + name: testAppName, + options: testOptions, + ); FirebaseApp app = Firebase.app(testAppName); expect(initializedApp, app); @@ -76,8 +81,10 @@ void main() { test('.getService() returns null when registry is null', () { String nullAppName = 'nullApp'; - final FirebaseAppPlatform nullPlatformApp = - FirebaseAppPlatform(nullAppName, testOptions); + final FirebaseAppPlatform nullPlatformApp = FirebaseAppPlatform( + nullAppName, + testOptions, + ); when(mock.app(nullAppName)).thenReturn(nullPlatformApp); FirebaseApp app = Firebase.app(nullAppName); @@ -89,32 +96,34 @@ void main() { expect(app.getService(), isNull); }); - test('.delete() disposes registered services before deleting app', - () async { - final calls = []; - final platformApp = TestFirebaseAppPlatform( - testAppName, - testOptions, - onDelete: () async { - calls.add('app'); - }, - ); - when(mock.app(testAppName)).thenReturn(platformApp); - - FirebaseApp app = Firebase.app(testAppName); - final testService = TestService(); - app.registerService( - testService, - dispose: (_) async { - calls.add('service'); - }, - ); - - await app.delete(); - - expect(calls, ['service', 'app']); - expect(app.getService(), isNull); - }); + test( + '.delete() disposes registered services before deleting app', + () async { + final calls = []; + final platformApp = TestFirebaseAppPlatform( + testAppName, + testOptions, + onDelete: () async { + calls.add('app'); + }, + ); + when(mock.app(testAppName)).thenReturn(platformApp); + + FirebaseApp app = Firebase.app(testAppName); + final testService = TestService(); + app.registerService( + testService, + dispose: (_) async { + calls.add('service'); + }, + ); + + await app.delete(); + + expect(calls, ['service', 'app']); + expect(app.getService(), isNull); + }, + ); }); test('.initializeApp() with demoProjectId', () async { @@ -131,13 +140,16 @@ void main() { final mock = MockFirebaseCore(); Firebase.delegatePackingProperty = mock; - final FirebaseAppPlatform platformApp = - FirebaseAppPlatform(expectedName, expectedOptions); + final FirebaseAppPlatform platformApp = FirebaseAppPlatform( + expectedName, + expectedOptions, + ); when(mock.apps).thenReturn([platformApp]); when(mock.app(expectedName)).thenReturn(platformApp); - when(mock.initializeApp(name: expectedName, options: expectedOptions)) - .thenAnswer((_) => Future.value(platformApp)); + when( + mock.initializeApp(name: expectedName, options: expectedOptions), + ).thenAnswer((_) => Future.value(platformApp)); // Initialize the app with only a demo project id. The implementation will // set the name and options accordingly. @@ -148,10 +160,7 @@ void main() { expect(initializedApp, app); verifyInOrder([ - mock.initializeApp( - name: expectedName, - options: expectedOptions, - ), + mock.initializeApp(name: expectedName, options: expectedOptions), mock.app(expectedName), ]); }); @@ -161,8 +170,7 @@ class MockFirebaseCore extends Mock with // ignore: prefer_mixin, plugin_platform_interface needs to migrate to use `mixin` MockPlatformInterfaceMixin - implements - FirebasePlatform { + implements FirebasePlatform { @override FirebaseAppPlatform app([String name = defaultFirebaseAppName]) { return super.noSuchMethod( @@ -178,14 +186,10 @@ class MockFirebaseCore extends Mock FirebaseOptions? options, }) { return super.noSuchMethod( - Invocation.method( - #initializeApp, - const [], - { - #name: name, - #options: options, - }, - ), + Invocation.method(#initializeApp, const [], { + #name: name, + #options: options, + }), returnValue: Future.value(FakeFirebaseAppPlatform()), returnValueForMissingStub: Future.value(FakeFirebaseAppPlatform()), ); @@ -205,11 +209,7 @@ class MockFirebaseCore extends Mock class FakeFirebaseAppPlatform extends Fake implements FirebaseAppPlatform {} class TestFirebaseAppPlatform extends FirebaseAppPlatform { - TestFirebaseAppPlatform( - super.name, - super.options, { - this.onDelete, - }); + TestFirebaseAppPlatform(super.name, super.options, {this.onDelete}); final Future Function()? onDelete; diff --git a/packages/firebase_core/firebase_core_platform_interface/lib/src/firebase_core_exceptions.dart b/packages/firebase_core/firebase_core_platform_interface/lib/src/firebase_core_exceptions.dart index c231518bf540..ccebac2c8bc4 100644 --- a/packages/firebase_core/firebase_core_platform_interface/lib/src/firebase_core_exceptions.dart +++ b/packages/firebase_core/firebase_core_platform_interface/lib/src/firebase_core_exceptions.dart @@ -9,19 +9,21 @@ part of '../firebase_core_platform_interface.dart'; /// no app has been created. FirebaseException noAppExists(String appName) { return FirebaseException( - plugin: 'core', - code: 'no-app', - message: - "No Firebase App '$appName' has been created - call Firebase.initializeApp()"); + plugin: 'core', + code: 'no-app', + message: + "No Firebase App '$appName' has been created - call Firebase.initializeApp()", + ); } /// Throws a consistent cross-platform error message when an app is being created /// which already exists. FirebaseException duplicateApp(String appName) { return FirebaseException( - plugin: 'core', - code: 'duplicate-app', - message: 'A Firebase App named "$appName" already exists'); + plugin: 'core', + code: 'duplicate-app', + message: 'A Firebase App named "$appName" already exists', + ); } /// Throws a consistent cross-platform error message if the user attempts to @@ -29,7 +31,8 @@ FirebaseException duplicateApp(String appName) { FirebaseException noDefaultAppInitialization() { return FirebaseException( plugin: 'core', - message: 'The $defaultFirebaseAppName app cannot be initialized here. ' + message: + 'The $defaultFirebaseAppName app cannot be initialized here. ' 'To initialize the default app, follow the installation instructions ' 'for the specific platform you are developing with.', ); @@ -47,7 +50,10 @@ View the documentation for more information: https://firebase.google.com/docs/fl '''; return FirebaseException( - plugin: 'core', code: 'not-initialized', message: message); + plugin: 'core', + code: 'not-initialized', + message: message, + ); } /// Throws a consistent cross-platform error message if the user attempts diff --git a/packages/firebase_core/firebase_core_platform_interface/lib/src/firebase_options.dart b/packages/firebase_core/firebase_core_platform_interface/lib/src/firebase_options.dart index 3487164bb4a9..82539e95a42e 100644 --- a/packages/firebase_core/firebase_core_platform_interface/lib/src/firebase_options.dart +++ b/packages/firebase_core/firebase_core_platform_interface/lib/src/firebase_options.dart @@ -59,22 +59,22 @@ class FirebaseOptions { /// [FirebaseOptions] instance, for example when data is sent back from a /// [MethodChannel]. FirebaseOptions.fromPigeon(CoreFirebaseOptions options) - : apiKey = options.apiKey, - appId = options.appId, - messagingSenderId = options.messagingSenderId, - projectId = options.projectId, - authDomain = options.authDomain, - databaseURL = options.databaseURL, - storageBucket = options.storageBucket, - measurementId = options.measurementId, - trackingId = options.trackingId, - deepLinkURLScheme = options.deepLinkURLScheme, - androidClientId = options.androidClientId, - iosClientId = options.iosClientId, - iosBundleId = options.iosBundleId, - appGroupId = options.appGroupId, - recaptchaSiteKey = - ''; // Placeholder to coordinate with fluttefire cli current operation. + : apiKey = options.apiKey, + appId = options.appId, + messagingSenderId = options.messagingSenderId, + projectId = options.projectId, + authDomain = options.authDomain, + databaseURL = options.databaseURL, + storageBucket = options.storageBucket, + measurementId = options.measurementId, + trackingId = options.trackingId, + deepLinkURLScheme = options.deepLinkURLScheme, + androidClientId = options.androidClientId, + iosClientId = options.iosClientId, + iosBundleId = options.iosBundleId, + appGroupId = options.appGroupId, + recaptchaSiteKey = + ''; // Placeholder to coordinate with fluttefire cli current operation. /// Returns a copy of this FirebaseOptions with the given fields replaced with /// the new values. diff --git a/packages/firebase_core/firebase_core_platform_interface/lib/src/method_channel/method_channel_firebase.dart b/packages/firebase_core/firebase_core_platform_interface/lib/src/method_channel/method_channel_firebase.dart index ad3dff75c9de..ee15f9251cfd 100644 --- a/packages/firebase_core/firebase_core_platform_interface/lib/src/method_channel/method_channel_firebase.dart +++ b/packages/firebase_core/firebase_core_platform_interface/lib/src/method_channel/method_channel_firebase.dart @@ -37,11 +37,11 @@ class MethodChannelFirebase extends FirebasePlatform { void _initializeFirebaseAppFromMap(CoreInitializeResponse response) { MethodChannelFirebaseApp methodChannelFirebaseApp = MethodChannelFirebaseApp( - response.name, - FirebaseOptions.fromPigeon(response.options), - isAutomaticDataCollectionEnabled: - response.isAutomaticDataCollectionEnabled, - ); + response.name, + FirebaseOptions.fromPigeon(response.options), + isAutomaticDataCollectionEnabled: + response.isAutomaticDataCollectionEnabled, + ); appInstances[methodChannelFirebaseApp.name] = methodChannelFirebaseApp; @@ -89,25 +89,27 @@ class MethodChannelFirebase extends FirebasePlatform { // If no options are present & no default app has been setup, the user is // trying to initialize default from Dart if (defaultApp == null && _options != null) { - _initializeFirebaseAppFromMap(await api.initializeApp( - defaultFirebaseAppName, - CoreFirebaseOptions( - apiKey: _options.apiKey, - appId: _options.appId, - messagingSenderId: _options.messagingSenderId, - projectId: _options.projectId, - authDomain: _options.authDomain, - databaseURL: _options.databaseURL, - storageBucket: _options.storageBucket, - measurementId: _options.measurementId, - trackingId: _options.trackingId, - deepLinkURLScheme: _options.deepLinkURLScheme, - androidClientId: _options.androidClientId, - iosClientId: _options.iosClientId, - iosBundleId: _options.iosBundleId, - appGroupId: _options.appGroupId, + _initializeFirebaseAppFromMap( + await api.initializeApp( + defaultFirebaseAppName, + CoreFirebaseOptions( + apiKey: _options.apiKey, + appId: _options.appId, + messagingSenderId: _options.messagingSenderId, + projectId: _options.projectId, + authDomain: _options.authDomain, + databaseURL: _options.databaseURL, + storageBucket: _options.storageBucket, + measurementId: _options.measurementId, + trackingId: _options.trackingId, + deepLinkURLScheme: _options.deepLinkURLScheme, + androidClientId: _options.androidClientId, + iosClientId: _options.iosClientId, + iosBundleId: _options.iosBundleId, + appGroupId: _options.appGroupId, + ), ), - )); + ); defaultApp = appInstances[defaultFirebaseAppName]; } @@ -156,25 +158,27 @@ class MethodChannelFirebase extends FirebasePlatform { } } - _initializeFirebaseAppFromMap(await api.initializeApp( - name, - CoreFirebaseOptions( - apiKey: options!.apiKey, - appId: options.appId, - messagingSenderId: options.messagingSenderId, - projectId: options.projectId, - authDomain: options.authDomain, - databaseURL: options.databaseURL, - storageBucket: options.storageBucket, - measurementId: options.measurementId, - trackingId: options.trackingId, - deepLinkURLScheme: options.deepLinkURLScheme, - androidClientId: options.androidClientId, - iosClientId: options.iosClientId, - iosBundleId: options.iosBundleId, - appGroupId: options.appGroupId, + _initializeFirebaseAppFromMap( + await api.initializeApp( + name, + CoreFirebaseOptions( + apiKey: options!.apiKey, + appId: options.appId, + messagingSenderId: options.messagingSenderId, + projectId: options.projectId, + authDomain: options.authDomain, + databaseURL: options.databaseURL, + storageBucket: options.storageBucket, + measurementId: options.measurementId, + trackingId: options.trackingId, + deepLinkURLScheme: options.deepLinkURLScheme, + androidClientId: options.androidClientId, + iosClientId: options.iosClientId, + iosBundleId: options.iosBundleId, + appGroupId: options.appGroupId, + ), ), - )); + ); return appInstances[name]!; } diff --git a/packages/firebase_core/firebase_core_platform_interface/lib/src/method_channel/method_channel_firebase_app.dart b/packages/firebase_core/firebase_core_platform_interface/lib/src/method_channel/method_channel_firebase_app.dart index 4bfc28642b15..50c4c0216b23 100644 --- a/packages/firebase_core/firebase_core_platform_interface/lib/src/method_channel/method_channel_firebase_app.dart +++ b/packages/firebase_core/firebase_core_platform_interface/lib/src/method_channel/method_channel_firebase_app.dart @@ -19,9 +19,9 @@ class MethodChannelFirebaseApp extends FirebaseAppPlatform { String name, FirebaseOptions options, { bool? isAutomaticDataCollectionEnabled, - }) : _isAutomaticDataCollectionEnabled = - isAutomaticDataCollectionEnabled ?? false, - super(name, options); + }) : _isAutomaticDataCollectionEnabled = + isAutomaticDataCollectionEnabled ?? false, + super(name, options); /// Keeps track of whether this app has been deleted by the user. bool _isDeleted = false; diff --git a/packages/firebase_core/firebase_core_platform_interface/lib/src/pigeon/messages.pigeon.dart b/packages/firebase_core/firebase_core_platform_interface/lib/src/pigeon/messages.pigeon.dart index 6d4123a1f1cb..a668f49d7b08 100644 --- a/packages/firebase_core/firebase_core_platform_interface/lib/src/pigeon/messages.pigeon.dart +++ b/packages/firebase_core/firebase_core_platform_interface/lib/src/pigeon/messages.pigeon.dart @@ -37,8 +37,11 @@ Object? _extractReplyValueOrThrow( return replyList.firstOrNull; } -List wrapResponse( - {Object? result, PlatformException? error, bool empty = false}) { +List wrapResponse({ + Object? result, + PlatformException? error, + bool empty = false, +}) { if (empty) { return []; } @@ -60,8 +63,9 @@ bool _deepEquals(Object? a, Object? b) { } if (a is List && b is List) { return a.length == b.length && - a.indexed - .every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1])); + a.indexed.every( + ((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]), + ); } if (a is Map && b is Map) { if (a.length != b.length) { @@ -264,8 +268,8 @@ class CoreInitializeResponse { name: result[0]! as String, options: result[1]! as CoreFirebaseOptions, isAutomaticDataCollectionEnabled: result[2] as bool?, - pluginConstants: - (result[3]! as Map).cast(), + pluginConstants: (result[3]! as Map) + .cast(), ); } @@ -280,8 +284,10 @@ class CoreInitializeResponse { } return _deepEquals(name, other.name) && _deepEquals(options, other.options) && - _deepEquals(isAutomaticDataCollectionEnabled, - other.isAutomaticDataCollectionEnabled) && + _deepEquals( + isAutomaticDataCollectionEnabled, + other.isAutomaticDataCollectionEnabled, + ) && _deepEquals(pluginConstants, other.pluginConstants); } @@ -325,11 +331,13 @@ class FirebaseCoreHostApi { /// Constructor for [FirebaseCoreHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - FirebaseCoreHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + FirebaseCoreHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -337,7 +345,9 @@ class FirebaseCoreHostApi { final String pigeonVar_messageChannelSuffix; Future initializeApp( - String appName, CoreFirebaseOptions initializeAppRequest) async { + String appName, + CoreFirebaseOptions initializeAppRequest, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_core_platform_interface.FirebaseCoreHostApi.initializeApp$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -345,8 +355,9 @@ class FirebaseCoreHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName, initializeAppRequest]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName, initializeAppRequest], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -401,11 +412,13 @@ class FirebaseAppHostApi { /// Constructor for [FirebaseAppHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - FirebaseAppHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + FirebaseAppHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -413,7 +426,9 @@ class FirebaseAppHostApi { final String pigeonVar_messageChannelSuffix; Future setAutomaticDataCollectionEnabled( - String appName, bool enabled) async { + String appName, + bool enabled, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_core_platform_interface.FirebaseAppHostApi.setAutomaticDataCollectionEnabled$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -421,8 +436,9 @@ class FirebaseAppHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName, enabled]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName, enabled], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -433,7 +449,9 @@ class FirebaseAppHostApi { } Future setAutomaticResourceManagementEnabled( - String appName, bool enabled) async { + String appName, + bool enabled, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_core_platform_interface.FirebaseAppHostApi.setAutomaticResourceManagementEnabled$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -441,8 +459,9 @@ class FirebaseAppHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName, enabled]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName, enabled], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -460,8 +479,9 @@ class FirebaseAppHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( diff --git a/packages/firebase_core/firebase_core_platform_interface/lib/src/pigeon/test_api.dart b/packages/firebase_core/firebase_core_platform_interface/lib/src/pigeon/test_api.dart index 4ef43849e98b..fc50255eb331 100644 --- a/packages/firebase_core/firebase_core_platform_interface/lib/src/pigeon/test_api.dart +++ b/packages/firebase_core/firebase_core_platform_interface/lib/src/pigeon/test_api.dart @@ -50,7 +50,9 @@ abstract class TestFirebaseCoreHostApi { static const MessageCodec pigeonChannelCodec = _PigeonCodec(); Future initializeApp( - String appName, CoreFirebaseOptions initializeAppRequest); + String appName, + CoreFirebaseOptions initializeAppRequest, + ); Future> initializeCore(); @@ -61,84 +63,106 @@ abstract class TestFirebaseCoreHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_core_platform_interface.FirebaseCoreHostApi.initializeApp$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_core_platform_interface.FirebaseCoreHostApi.initializeApp$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_appName = args[0]! as String; - final CoreFirebaseOptions arg_initializeAppRequest = - args[1]! as CoreFirebaseOptions; - try { - final CoreInitializeResponse output = - await api.initializeApp(arg_appName, arg_initializeAppRequest); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_appName = args[0]! as String; + final CoreFirebaseOptions arg_initializeAppRequest = + args[1]! as CoreFirebaseOptions; + try { + final CoreInitializeResponse output = await api.initializeApp( + arg_appName, + arg_initializeAppRequest, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_core_platform_interface.FirebaseCoreHostApi.initializeCore$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_core_platform_interface.FirebaseCoreHostApi.initializeCore$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - try { - final List output = - await api.initializeCore(); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + try { + final List output = await api + .initializeCore(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_core_platform_interface.FirebaseCoreHostApi.optionsFromResource$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_core_platform_interface.FirebaseCoreHostApi.optionsFromResource$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - try { - final CoreFirebaseOptions output = await api.optionsFromResource(); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + try { + final CoreFirebaseOptions output = await api + .optionsFromResource(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } @@ -152,7 +176,9 @@ abstract class TestFirebaseAppHostApi { Future setAutomaticDataCollectionEnabled(String appName, bool enabled); Future setAutomaticResourceManagementEnabled( - String appName, bool enabled); + String appName, + bool enabled, + ); Future delete(String appName); @@ -161,88 +187,111 @@ abstract class TestFirebaseAppHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_core_platform_interface.FirebaseAppHostApi.setAutomaticDataCollectionEnabled$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_core_platform_interface.FirebaseAppHostApi.setAutomaticDataCollectionEnabled$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_appName = args[0]! as String; - final bool arg_enabled = args[1]! as bool; - try { - await api.setAutomaticDataCollectionEnabled( - arg_appName, arg_enabled); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_appName = args[0]! as String; + final bool arg_enabled = args[1]! as bool; + try { + await api.setAutomaticDataCollectionEnabled( + arg_appName, + arg_enabled, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_core_platform_interface.FirebaseAppHostApi.setAutomaticResourceManagementEnabled$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_core_platform_interface.FirebaseAppHostApi.setAutomaticResourceManagementEnabled$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_appName = args[0]! as String; - final bool arg_enabled = args[1]! as bool; - try { - await api.setAutomaticResourceManagementEnabled( - arg_appName, arg_enabled); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_appName = args[0]! as String; + final bool arg_enabled = args[1]! as bool; + try { + await api.setAutomaticResourceManagementEnabled( + arg_appName, + arg_enabled, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_core_platform_interface.FirebaseAppHostApi.delete$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_core_platform_interface.FirebaseAppHostApi.delete$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_appName = args[0]! as String; - try { - await api.delete(arg_appName); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_appName = args[0]! as String; + try { + await api.delete(arg_appName); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } diff --git a/packages/firebase_core/firebase_core_platform_interface/lib/src/platform_interface/platform_interface_firebase_app.dart b/packages/firebase_core/firebase_core_platform_interface/lib/src/platform_interface/platform_interface_firebase_app.dart index 6fb7eb59baf6..37be7d7f30e8 100644 --- a/packages/firebase_core/firebase_core_platform_interface/lib/src/platform_interface/platform_interface_firebase_app.dart +++ b/packages/firebase_core/firebase_core_platform_interface/lib/src/platform_interface/platform_interface_firebase_app.dart @@ -37,9 +37,7 @@ class FirebaseAppPlatform extends PlatformInterface { /// Deletes the current FirebaseApp. Future delete() async { - throw UnimplementedError( - 'delete() has not been implemented.', - ); + throw UnimplementedError('delete() has not been implemented.'); } /// Sets whether automatic data collection is enabled or disabled for this app. diff --git a/packages/firebase_core/firebase_core_platform_interface/lib/src/test_binding.dart b/packages/firebase_core/firebase_core_platform_interface/lib/src/test_binding.dart index e11c407b2793..e4d8adf45044 100644 --- a/packages/firebase_core/firebase_core_platform_interface/lib/src/test_binding.dart +++ b/packages/firebase_core/firebase_core_platform_interface/lib/src/test_binding.dart @@ -51,8 +51,9 @@ class TestBinaryMessenger { return; } _setMockMessageHandler(channel.name, (ByteData? message) async { - return channel.codec - .encodeMessage(await handler(channel.codec.decodeMessage(message))); + return channel.codec.encodeMessage( + await handler(channel.codec.decodeMessage(message)), + ); }); } diff --git a/packages/firebase_core/firebase_core_platform_interface/pigeons/messages.dart b/packages/firebase_core/firebase_core_platform_interface/pigeons/messages.dart index 8aa278379e6f..f91556633385 100644 --- a/packages/firebase_core/firebase_core_platform_interface/pigeons/messages.dart +++ b/packages/firebase_core/firebase_core_platform_interface/pigeons/messages.dart @@ -15,9 +15,7 @@ import 'package:pigeon/pigeon.dart'; dartPackageName: 'firebase_core_platform_interface', kotlinOut: '../firebase_core/android/src/main/kotlin/io/flutter/plugins/firebase/core/GeneratedAndroidFirebaseCore.g.kt', - kotlinOptions: KotlinOptions( - package: 'io.flutter.plugins.firebase.core', - ), + kotlinOptions: KotlinOptions(package: 'io.flutter.plugins.firebase.core'), swiftOut: '../firebase_core/ios/firebase_core/Sources/firebase_core/FirebaseCoreMessages.g.swift', cppHeaderOut: '../firebase_core/windows/messages.g.h', @@ -105,19 +103,11 @@ abstract class FirebaseCoreHostApi { @HostApi(dartHostTestHandler: 'TestFirebaseAppHostApi') abstract class FirebaseAppHostApi { @async - void setAutomaticDataCollectionEnabled( - String appName, - bool enabled, - ); + void setAutomaticDataCollectionEnabled(String appName, bool enabled); @async - void setAutomaticResourceManagementEnabled( - String appName, - bool enabled, - ); + void setAutomaticResourceManagementEnabled(String appName, bool enabled); @async - void delete( - String appName, - ); + void delete(String appName); } diff --git a/packages/firebase_core/firebase_core_platform_interface/pubspec.yaml b/packages/firebase_core/firebase_core_platform_interface/pubspec.yaml index d481587bd71a..5c5bdc315fdf 100644 --- a/packages/firebase_core/firebase_core_platform_interface/pubspec.yaml +++ b/packages/firebase_core/firebase_core_platform_interface/pubspec.yaml @@ -8,8 +8,8 @@ version: 8.1.1 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: collection: ^1.0.0 diff --git a/packages/firebase_core/firebase_core_platform_interface/test/firebase_exception_test.dart b/packages/firebase_core/firebase_core_platform_interface/test/firebase_exception_test.dart index 30e8f5d34eab..8d9b0af9dbaa 100644 --- a/packages/firebase_core/firebase_core_platform_interface/test/firebase_exception_test.dart +++ b/packages/firebase_core/firebase_core_platform_interface/test/firebase_exception_test.dart @@ -11,41 +11,51 @@ void main() { group('$FirebaseException', () { test('should return a formatted message', () async { - FirebaseException e = FirebaseException( - plugin: 'foo', - message: 'bar', - ); + FirebaseException e = FirebaseException(plugin: 'foo', message: 'bar'); expect(e.toString(), '[foo/unknown] bar'); }); test('should return a formatted message with a custom code', () async { - FirebaseException e = - FirebaseException(plugin: 'foo', message: 'bar', code: 'baz'); + FirebaseException e = FirebaseException( + plugin: 'foo', + message: 'bar', + code: 'baz', + ); expect(e.toString(), '[foo/baz] bar'); }); test('should return a formatted message with a stack trace', () async { FirebaseException e = FirebaseException( - plugin: 'foo', - message: 'bar', - code: 'baz', - stackTrace: StackTrace.current); + plugin: 'foo', + message: 'bar', + code: 'baz', + stackTrace: StackTrace.current, + ); // Anything with a stack trace adds 2 blanks lines following the message. expect(e.toString(), startsWith('[foo/baz] bar\n\n')); }); test('should override the == operator', () async { - FirebaseException e1 = - FirebaseException(plugin: 'foo', message: 'bar', code: 'baz'); + FirebaseException e1 = FirebaseException( + plugin: 'foo', + message: 'bar', + code: 'baz', + ); - FirebaseException e2 = - FirebaseException(plugin: 'foo', message: 'bar', code: 'baz'); + FirebaseException e2 = FirebaseException( + plugin: 'foo', + message: 'bar', + code: 'baz', + ); - FirebaseException e3 = - FirebaseException(plugin: 'foo', message: 'bar', code: 'baz'); + FirebaseException e3 = FirebaseException( + plugin: 'foo', + message: 'bar', + code: 'baz', + ); expect(e1 == e2, true); expect(e1 != e3, false); diff --git a/packages/firebase_core/firebase_core_platform_interface/test/platform_interface_tests/platform_interface_firebase_core_test.dart b/packages/firebase_core/firebase_core_platform_interface/test/platform_interface_tests/platform_interface_firebase_core_test.dart index 5393a22f99d8..812cc639433a 100644 --- a/packages/firebase_core/firebase_core_platform_interface/test/platform_interface_tests/platform_interface_firebase_core_test.dart +++ b/packages/firebase_core/firebase_core_platform_interface/test/platform_interface_tests/platform_interface_firebase_core_test.dart @@ -74,8 +74,7 @@ class FirebaseCoreMockPlatform extends Mock with // ignore: prefer_mixin, plugin_platform_interface needs to migrate to use `mixin` MockPlatformInterfaceMixin - implements - FirebasePlatform {} + implements FirebasePlatform {} class TestFirebasePlugin extends FirebasePlugin { TestFirebasePlugin() : super(defaultFirebaseAppName, 'test_plugin'); diff --git a/packages/firebase_core/firebase_core_web/lib/src/firebase_core_web.dart b/packages/firebase_core/firebase_core_web/lib/src/firebase_core_web.dart index ea15ec3cc17a..51dfd90923ff 100644 --- a/packages/firebase_core/firebase_core_web/lib/src/firebase_core_web.dart +++ b/packages/firebase_core/firebase_core_web/lib/src/firebase_core_web.dart @@ -27,9 +27,8 @@ class FirebaseWebService { }); } -typedef EnsurePluginInitialized = Future Function( - firebase.App firebaseApp, -)?; +typedef EnsurePluginInitialized = + Future Function(firebase.App firebaseApp)?; /// The entry point for accessing Firebase. /// @@ -117,8 +116,9 @@ class FirebaseCoreWeb extends FirebasePlatform { /// You must ensure the Firebase script is injected before using the service. List get _ignoredServiceScripts { try { - JSObject? ignored = - globalContext.getProperty('flutterfire_ignore_scripts'.toJS); + JSObject? ignored = globalContext.getProperty( + 'flutterfire_ignore_scripts'.toJS, + ); // Cannot be done with Dart 3.2 constraints // ignore: invalid_runtime_check_with_js_interop_types @@ -152,25 +152,23 @@ class FirebaseCoreWeb extends FirebasePlatform { 'TrustedTypes available. Creating policy: $trustedTypePolicyName'.toJS, ); try { - final web.TrustedTypePolicy policy = - web.window.trustedTypes.createPolicy( - trustedTypePolicyName, - web.TrustedTypePolicyOptions( - createScriptURL: ((JSString url) => src).toJS, - createScript: ((JSString script, JSString? type) => script).toJS, - ), - ); + final web.TrustedTypePolicy policy = web.window.trustedTypes + .createPolicy( + trustedTypePolicyName, + web.TrustedTypePolicyOptions( + createScriptURL: ((JSString url) => src).toJS, + createScript: + ((JSString script, JSString? type) => script).toJS, + ), + ); final trustedUrl = policy.createScriptURLNoArgs(src); final stringUrl = (trustedUrl as JSObject).callMethod('toString'.toJS); - final trustedScript = policy.createScript( - ''' + final trustedScript = policy.createScript(''' window.ff_trigger_$windowVar = async (callback) => { console.debug("Initializing Firebase $windowVar"); callback(await import("$stringUrl")); }; - ''', - null, - ); + ''', null); script.trustedScript = trustedScript; @@ -180,7 +178,8 @@ class FirebaseCoreWeb extends FirebasePlatform { } } else { final stringUrl = src; - script.text = ''' + script.text = + ''' window.ff_trigger_$windowVar = async (callback) => { console.debug("Initializing Firebase $windowVar"); callback(await import("$stringUrl")); @@ -300,12 +299,10 @@ class FirebaseCoreWeb extends FirebasePlatform { await _initializeCore(); guardNotInitialized(() => firebase.SDK_VERSION); - assert( - () { - if (firebase.SDK_VERSION != supportedFirebaseJsSdkVersion) { - // ignore: avoid_print - print( - ''' + assert(() { + if (firebase.SDK_VERSION != supportedFirebaseJsSdkVersion) { + // ignore: avoid_print + print(''' WARNING: FlutterFire for Web is explicitly tested against Firebase JS SDK version "$supportedFirebaseJsSdkVersion" but your currently specifying "${firebase.SDK_VERSION}" by either the imported Firebase JS SDKs in your web/index.html file or by providing an override - this may lead to unexpected issues in your application. It is recommended that you change all of the versions of the @@ -320,13 +317,11 @@ class FirebaseCoreWeb extends FirebasePlatform { If you import the Firebase scripts in index.html, instead allow FlutterFire to manage this for you by removing any Firebase scripts in your web/index.html file: e.g. remove: - ''', - ); - } + '''); + } - return true; - }(), - ); + return true; + }()); firebase.App? app; @@ -476,9 +471,7 @@ R guardNotInitialized(R Function() cb) { final value = cb(); if (value is Future) { - return value.catchError( - _handleException, - ) as R; + return value.catchError(_handleException) as R; } return value; diff --git a/packages/firebase_core/firebase_core_web/lib/src/interop/core.dart b/packages/firebase_core/firebase_core_web/lib/src/interop/core.dart index 3baa52ceb339..29be7f00c55b 100644 --- a/packages/firebase_core/firebase_core_web/lib/src/interop/core.dart +++ b/packages/firebase_core/firebase_core_web/lib/src/interop/core.dart @@ -60,8 +60,11 @@ App app([String? name]) { ); } -void registerVersion(String libraryKeyOrName, String version, - [String? variant]) { +void registerVersion( + String libraryKeyOrName, + String version, [ + String? variant, +]) { firebase_interop.registerVersion( libraryKeyOrName.toJS, version.toJS, diff --git a/packages/firebase_core/firebase_core_web/lib/src/interop/package_web_tweaks.dart b/packages/firebase_core/firebase_core_web/lib/src/interop/package_web_tweaks.dart index 764166eee7f3..242c12eaa644 100644 --- a/packages/firebase_core/firebase_core_web/lib/src/interop/package_web_tweaks.dart +++ b/packages/firebase_core/firebase_core_web/lib/src/interop/package_web_tweaks.dart @@ -24,9 +24,7 @@ extension NullableTrustedTypesGetter on web.Window { extension CreateScriptUrlWithoutArgs on web.TrustedTypePolicy { /// @JS('createScriptURL') - external web.TrustedScriptURL createScriptURLNoArgs( - String input, - ); + external web.TrustedScriptURL createScriptURLNoArgs(String input); } /// This extension allows setting a TrustedScriptURL as the src of a script element, diff --git a/packages/firebase_core/firebase_core_web/lib/src/interop/utils/utils.dart b/packages/firebase_core/firebase_core_web/lib/src/interop/utils/utils.dart index 0b7232b628f9..cf4dcd128303 100644 --- a/packages/firebase_core/firebase_core_web/lib/src/interop/utils/utils.dart +++ b/packages/firebase_core/firebase_core_web/lib/src/interop/utils/utils.dart @@ -18,25 +18,28 @@ import 'func.dart'; const bool _kDebugMode = !bool.fromEnvironment('dart.vm.product'); /// Handles the [Future] object with the provided [mapper] function. -JSPromise handleFutureWithMapper( - Future future, - Func1 mapper, -) { - return JSPromise((JSFunction resolve, JSFunction reject) { - future.then((T value) { - final Object? target = mapper(value); - final JSAny? jsVal = target?.jsify(); - resolve.callAsFunction(resolve, jsVal); - }, onError: (Object error, StackTrace stackTrace) { - final errorConstructor = - globalContext.getProperty('Error'.toJS)! as JSFunction; - final wrapper = errorConstructor - .callAsConstructor('Dart exception: $error'.toJS); - wrapper['error'] = error.toJSBox; - wrapper['stack'] = stackTrace.toString().toJS; - reject.callAsFunction(reject, wrapper); - }); - }.toJS); +JSPromise handleFutureWithMapper(Future future, Func1 mapper) { + return JSPromise( + (JSFunction resolve, JSFunction reject) { + future.then( + (T value) { + final Object? target = mapper(value); + final JSAny? jsVal = target?.jsify(); + resolve.callAsFunction(resolve, jsVal); + }, + onError: (Object error, StackTrace stackTrace) { + final errorConstructor = + globalContext.getProperty('Error'.toJS)! as JSFunction; + final wrapper = errorConstructor.callAsConstructor( + 'Dart exception: $error'.toJS, + ); + wrapper['error'] = error.toJSBox; + wrapper['stack'] = stackTrace.toString().toJS; + reject.callAsFunction(reject, wrapper); + }, + ); + }.toJS, + ); } // No way to unsubscribe from event listeners on hot reload so we set on the windows object diff --git a/packages/firebase_core/firebase_core_web/pubspec.yaml b/packages/firebase_core/firebase_core_web/pubspec.yaml index f3d8e159e7dd..cee9216992e6 100644 --- a/packages/firebase_core/firebase_core_web/pubspec.yaml +++ b/packages/firebase_core/firebase_core_web/pubspec.yaml @@ -6,8 +6,8 @@ version: 3.11.0 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.22.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core_platform_interface: ^8.1.1 diff --git a/packages/firebase_core/firebase_core_web/test/firebase_core_web_app_check_multi_app_test.dart b/packages/firebase_core/firebase_core_web/test/firebase_core_web_app_check_multi_app_test.dart index 88bfad5eb7a1..5a100bae3c9c 100644 --- a/packages/firebase_core/firebase_core_web/test/firebase_core_web_app_check_multi_app_test.dart +++ b/packages/firebase_core/firebase_core_web/test/firebase_core_web_app_check_multi_app_test.dart @@ -57,10 +57,7 @@ void main() { ); expect(FirebaseCoreWeb.isServiceRegistered('app-check'), isTrue); - expect( - initializedAppNames, - containsAll(['[DEFAULT]', 'prod']), - ); + expect(initializedAppNames, containsAll(['[DEFAULT]', 'prod'])); }, ); }); diff --git a/packages/firebase_core/firebase_core_web/test/firebase_core_web_exceptions_test.dart b/packages/firebase_core/firebase_core_web/test/firebase_core_web_exceptions_test.dart index ada205142773..8f904b8dcac7 100644 --- a/packages/firebase_core/firebase_core_web/test/firebase_core_web_exceptions_test.dart +++ b/packages/firebase_core/firebase_core_web/test/firebase_core_web_exceptions_test.dart @@ -18,13 +18,14 @@ void main() { }); test( - 'should throw exception if no default app is available & no options are provided', - () async { - await expectLater( - FirebasePlatform.instance.initializeApp, - throwsAssertionError, - ); - }); + 'should throw exception if no default app is available & no options are provided', + () async { + await expectLater( + FirebasePlatform.instance.initializeApp, + throwsAssertionError, + ); + }, + ); }); group('.initializeApp()', () { @@ -33,13 +34,15 @@ void main() { }); group('secondary apps', () { - test('should throw exception if no options are provided with a named app', - () async { - await expectLater( - () => FirebasePlatform.instance.initializeApp(name: 'foo'), - throwsAssertionError, - ); - }); + test( + 'should throw exception if no options are provided with a named app', + () async { + await expectLater( + () => FirebasePlatform.instance.initializeApp(name: 'foo'), + throwsAssertionError, + ); + }, + ); }); }); @@ -68,11 +71,7 @@ void main() { throwsA( isA() .having((error) => error.plugin, 'plugin', 'core') - .having( - (error) => error.code, - 'code', - 'not-initialized', - ), + .having((error) => error.code, 'code', 'not-initialized'), ), ); }); diff --git a/packages/firebase_crashlytics/firebase_crashlytics/example/integration_test/e2e_test.dart b/packages/firebase_crashlytics/firebase_crashlytics/example/integration_test/e2e_test.dart index de5f4262f7b5..9d994bc0b06d 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/example/integration_test/e2e_test.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics/example/integration_test/e2e_test.dart @@ -37,25 +37,23 @@ void main() { } }); - group( - 'isCrashlyticsCollectionEnabled', - () { - test( - 'checks isCrashlyticsCollectionEnabled value set from AndroidManifest.xml', - () async { + group('isCrashlyticsCollectionEnabled', () { + test( + 'checks isCrashlyticsCollectionEnabled value set from AndroidManifest.xml', + () async { bool isCrashlyticsCollectionEnabled = FirebaseCrashlytics.instance.isCrashlyticsCollectionEnabled; expect(isCrashlyticsCollectionEnabled, false); - }); - }, - skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android, - ); + }, + ); + }, skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android); group('checkForUnsentReports', () { test('should throw if automatic crash report is enabled', () async { - await FirebaseCrashlytics.instance - .setCrashlyticsCollectionEnabled(true); + await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled( + true, + ); await expectLater( FirebaseCrashlytics.instance.checkForUnsentReports, @@ -64,14 +62,15 @@ void main() { }); test('checks device cache for unsent crashlytics reports', () async { - await FirebaseCrashlytics.instance - .setCrashlyticsCollectionEnabled(false); + await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled( + false, + ); await FirebaseCrashlytics.instance.deleteUnsentReports(); // Only verify the API returns a bool without asserting a specific // value. After a killed test run (e.g. CI alarm timeout), unsent // reports may legitimately exist on device. - var unsentReports = - await FirebaseCrashlytics.instance.checkForUnsentReports(); + var unsentReports = await FirebaseCrashlytics.instance + .checkForUnsentReports(); expect(unsentReports, isA()); }); @@ -86,8 +85,8 @@ void main() { group('didCrashOnPreviousExecution', () { test('checks if app crashed on previous execution', () async { - var didCrash = - await FirebaseCrashlytics.instance.didCrashOnPreviousExecution(); + var didCrash = await FirebaseCrashlytics.instance + .didCrashOnPreviousExecution(); expect(didCrash, isFalse); }); }); @@ -102,52 +101,46 @@ void main() { }); // This is currently only testing that we can log flutter errors without crashing. - test( - 'should record flutter error', - () async { - await FirebaseCrashlytics.instance.recordFlutterError( - FlutterErrorDetails( - exception: 'foo exception', - stack: StackTrace.fromString(''), - context: DiagnosticsNode.message('bar reason'), - informationCollector: () => [ - DiagnosticsNode.message('first message'), - DiagnosticsNode.message('second message'), - ], - ), - ); - }, - ); + test('should record flutter error', () async { + await FirebaseCrashlytics.instance.recordFlutterError( + FlutterErrorDetails( + exception: 'foo exception', + stack: StackTrace.fromString(''), + context: DiagnosticsNode.message('bar reason'), + informationCollector: () => [ + DiagnosticsNode.message('first message'), + DiagnosticsNode.message('second message'), + ], + ), + ); + }); - test( - 'should have consistent error reason format', - () async { - const eventChannel = EventChannel( - 'plugins.flutter.io/firebase_crashlytics_test_stream', - ); - final eventStream = eventChannel.receiveBroadcastStream(); - - final completer = Completer(); - - final subscription = eventStream.listen((event) { - completer.complete(event.toString()); - }); - - await FirebaseCrashlytics.instance.recordError( - 'foo exception', - StackTrace.fromString('during testing'), - reason: 'foo reason', - ); - - // Fail the test rather than hang the suite if the native event - // channel never delivers. - final event = - await completer.future.timeout(const Duration(seconds: 30)); - expect(event, 'thrown foo reason'); - await subscription.cancel(); - }, - skip: kIsWeb || defaultTargetPlatform == TargetPlatform.macOS, - ); + test('should have consistent error reason format', () async { + const eventChannel = EventChannel( + 'plugins.flutter.io/firebase_crashlytics_test_stream', + ); + final eventStream = eventChannel.receiveBroadcastStream(); + + final completer = Completer(); + + final subscription = eventStream.listen((event) { + completer.complete(event.toString()); + }); + + await FirebaseCrashlytics.instance.recordError( + 'foo exception', + StackTrace.fromString('during testing'), + reason: 'foo reason', + ); + + // Fail the test rather than hang the suite if the native event + // channel never delivers. + final event = await completer.future.timeout( + const Duration(seconds: 30), + ); + expect(event, 'thrown foo reason'); + await subscription.cancel(); + }, skip: kIsWeb || defaultTargetPlatform == TargetPlatform.macOS); }); group('log', () { @@ -167,14 +160,16 @@ void main() { group('setCrashlyticsCollectionEnabled', () { // This is currently only testing that we can send unsent reports without crashing. test('should update to true', () async { - await FirebaseCrashlytics.instance - .setCrashlyticsCollectionEnabled(true); + await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled( + true, + ); }); // This is currently only testing that we can send unsent reports without crashing. test('should update to false', () async { - await FirebaseCrashlytics.instance - .setCrashlyticsCollectionEnabled(false); + await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled( + false, + ); }); }); diff --git a/packages/firebase_crashlytics/firebase_crashlytics/example/integration_test/report_test_results.dart b/packages/firebase_crashlytics/firebase_crashlytics/example/integration_test/report_test_results.dart index 038d20c39931..416b8cd76dd0 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/example/integration_test/report_test_results.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics/example/integration_test/report_test_results.dart @@ -26,8 +26,9 @@ void reportTestResultsToDriver(IntegrationTestWidgetsFlutterBinding binding) { for (final entry in binding.results.entries) if (entry.value is Failure) entry.key, ]; - bool didFail(String name) => failures - .any((failure) => name == failure || name.endsWith(' $failure')); + bool didFail(String name) => failures.any( + (failure) => name == failure || name.endsWith(' $failure'), + ); binding.reportData ??= {}; binding.reportData!['testResults'] = { diff --git a/packages/firebase_crashlytics/firebase_crashlytics/example/lib/firebase_options.dart b/packages/firebase_crashlytics/firebase_crashlytics/example/lib/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/example/lib/firebase_options.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics/example/lib/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/firebase_crashlytics/firebase_crashlytics/example/lib/main.dart b/packages/firebase_crashlytics/firebase_crashlytics/example/lib/main.dart index a43a1bc7b2c3..50837e240a6c 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/example/lib/main.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics/example/lib/main.dart @@ -22,9 +22,7 @@ const _kTestingCrashlytics = true; Future main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); + await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); const fatalError = true; // Non-async exceptions FlutterError.onError = (errorDetails) { @@ -79,8 +77,9 @@ class _MyAppState extends State { // Else only enable it in non-debug builds. // You could additionally extend this to allow users to opt-in. const enabled = !kDebugMode; - await FirebaseCrashlytics.instance - .setCrashlyticsCollectionEnabled(enabled); + await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled( + enabled, + ); _crashlyticsEnabled = enabled; } @@ -99,18 +98,14 @@ class _MyAppState extends State { Widget build(BuildContext context) { return MaterialApp( home: Scaffold( - appBar: AppBar( - title: const Text('Crashlytics example app'), - ), + appBar: AppBar(title: const Text('Crashlytics example app')), body: FutureBuilder( future: _initializeFlutterFireFuture, builder: (context, snapshot) { switch (snapshot.connectionState) { case ConnectionState.done: if (snapshot.hasError) { - return Center( - child: Text('Error: ${snapshot.error}'), - ); + return Center(child: Text('Error: ${snapshot.error}')); } return Center( child: Column( @@ -123,52 +118,67 @@ class _MyAppState extends State { setState(() { _crashlyticsEnabled = newValue; }); - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text( - 'Crashlytics reporting has been ${newValue ? 'enabled' : 'disabled'}.'), - duration: const Duration(seconds: 3), - )); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + 'Crashlytics reporting has been ${newValue ? 'enabled' : 'disabled'}.', + ), + duration: const Duration(seconds: 3), + ), + ); }, - child: Text(_crashlyticsEnabled - ? 'Disable Crashlytics' - : 'Enable Crashlytics'), + child: Text( + _crashlyticsEnabled + ? 'Disable Crashlytics' + : 'Enable Crashlytics', + ), ), ElevatedButton( onPressed: () { - FirebaseCrashlytics.instance - .setCustomKey('example', 'flutterfire'); - ScaffoldMessenger.of(context) - .showSnackBar(const SnackBar( - content: Text( + FirebaseCrashlytics.instance.setCustomKey( + 'example', + 'flutterfire', + ); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( 'Custom Key "example: flutterfire" has been set \n' - 'Key will appear in Firebase Console once an error has been reported.'), - duration: Duration(seconds: 5), - )); + 'Key will appear in Firebase Console once an error has been reported.', + ), + duration: Duration(seconds: 5), + ), + ); }, child: const Text('Key'), ), ElevatedButton( onPressed: () { - FirebaseCrashlytics.instance - .log('This is a log example'); - ScaffoldMessenger.of(context) - .showSnackBar(const SnackBar( - content: Text( + FirebaseCrashlytics.instance.log( + 'This is a log example', + ); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( 'The message "This is a log example" has been logged \n' - 'Message will appear in Firebase Console once an error has been reported.'), - duration: Duration(seconds: 5), - )); + 'Message will appear in Firebase Console once an error has been reported.', + ), + duration: Duration(seconds: 5), + ), + ); }, child: const Text('Log'), ), ElevatedButton( onPressed: () async { - ScaffoldMessenger.of(context) - .showSnackBar(const SnackBar( - content: Text('App will crash is 5 seconds \n' - 'Please reopen to send data to Crashlytics'), - duration: Duration(seconds: 5), - )); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + 'App will crash is 5 seconds \n' + 'Please reopen to send data to Crashlytics', + ), + duration: Duration(seconds: 5), + ), + ); // Delay crash for 5 seconds sleep(const Duration(seconds: 5)); @@ -181,12 +191,14 @@ class _MyAppState extends State { ), ElevatedButton( onPressed: () { - ScaffoldMessenger.of(context) - .showSnackBar(const SnackBar( - content: Text( - 'Thrown error has been caught and sent to Crashlytics.'), - duration: Duration(seconds: 5), - )); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + 'Thrown error has been caught and sent to Crashlytics.', + ), + duration: Duration(seconds: 5), + ), + ); // Example of thrown error, it will be caught and sent to // Crashlytics. @@ -196,22 +208,26 @@ class _MyAppState extends State { ), ElevatedButton( onPressed: () { - ScaffoldMessenger.of(context) - .showSnackBar(const SnackBar( - content: Text( - 'Uncaught Exception that is handled by second parameter of runZonedGuarded.'), - duration: Duration(seconds: 5), - )); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + 'Uncaught Exception that is handled by second parameter of runZonedGuarded.', + ), + duration: Duration(seconds: 5), + ), + ); // Example of an exception that does not get caught // by `FlutterError.onError` but is caught by // `runZonedGuarded`. runZonedGuarded(() { - Future.delayed(const Duration(seconds: 2), - () { - final List list = []; - print(list[100]); - }); + Future.delayed( + const Duration(seconds: 2), + () { + final List list = []; + print(list[100]); + }, + ); }, FirebaseCrashlytics.instance.recordError); }, child: const Text('Async out of bounds'), @@ -219,18 +235,22 @@ class _MyAppState extends State { ElevatedButton( onPressed: () async { try { - ScaffoldMessenger.of(context) - .showSnackBar(const SnackBar( - content: Text('Recorded Error'), - duration: Duration(seconds: 5), - )); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Recorded Error'), + duration: Duration(seconds: 5), + ), + ); throw Error(); } catch (e, s) { // "reason" will append the word "thrown" in the // Crashlytics console. - await FirebaseCrashlytics.instance.recordError(e, s, - reason: 'as an example of fatal error', - fatal: true); + await FirebaseCrashlytics.instance.recordError( + e, + s, + reason: 'as an example of fatal error', + fatal: true, + ); } }, child: const Text('Record Fatal Error'), @@ -238,17 +258,21 @@ class _MyAppState extends State { ElevatedButton( onPressed: () async { try { - ScaffoldMessenger.of(context) - .showSnackBar(const SnackBar( - content: Text('Recorded Error'), - duration: Duration(seconds: 5), - )); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Recorded Error'), + duration: Duration(seconds: 5), + ), + ); throw Error(); } catch (e, s) { // "reason" will append the word "thrown" in the // Crashlytics console. - await FirebaseCrashlytics.instance.recordError(e, s, - reason: 'as an example of non-fatal error'); + await FirebaseCrashlytics.instance.recordError( + e, + s, + reason: 'as an example of non-fatal error', + ); } }, child: const Text('Record Non-Fatal Error'), diff --git a/packages/firebase_crashlytics/firebase_crashlytics/example/pubspec.yaml b/packages/firebase_crashlytics/firebase_crashlytics/example/pubspec.yaml index 5bd982ade276..d9790116f0f6 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/example/pubspec.yaml +++ b/packages/firebase_crashlytics/firebase_crashlytics/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the firebase_crashlytics plugin. resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_analytics: ^12.5.0 diff --git a/packages/firebase_crashlytics/firebase_crashlytics/example/test_driver/integration_test.dart b/packages/firebase_crashlytics/firebase_crashlytics/example/test_driver/integration_test.dart index 691723cbbfe1..9ccbcc26ab97 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/example/test_driver/integration_test.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics/example/test_driver/integration_test.dart @@ -7,28 +7,32 @@ import 'dart:io'; import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver( - writeResponseOnFailure: true, - responseDataCallback: (Map? data) async { - final results = - (data?['testResults'] as Map?)?.cast() ?? - const {}; - var passed = 0; - var failed = 0; - for (final entry in results.entries) { - final ok = entry.value == 'success'; - ok ? passed++ : failed++; - // ignore: avoid_print - print('${ok ? '✅' : '❌'} ${entry.key}'); - } - // ignore: avoid_print - print('Web e2e summary: $passed passed, $failed failed, ' - '${results.length} total'); - if (results.isEmpty) { - // ignore: avoid_print - print('[E] No tests reported by the app - treating as ' - 'infrastructure failure.'); - exit(1); - } - await writeResponseData(data); - }, + writeResponseOnFailure: true, + responseDataCallback: (Map? data) async { + final results = + (data?['testResults'] as Map?)?.cast() ?? + const {}; + var passed = 0; + var failed = 0; + for (final entry in results.entries) { + final ok = entry.value == 'success'; + ok ? passed++ : failed++; + // ignore: avoid_print + print('${ok ? '✅' : '❌'} ${entry.key}'); + } + // ignore: avoid_print + print( + 'Web e2e summary: $passed passed, $failed failed, ' + '${results.length} total', ); + if (results.isEmpty) { + // ignore: avoid_print + print( + '[E] No tests reported by the app - treating as ' + 'infrastructure failure.', + ); + exit(1); + } + await writeResponseData(data); + }, +); diff --git a/packages/firebase_crashlytics/firebase_crashlytics/lib/src/firebase_crashlytics.dart b/packages/firebase_crashlytics/firebase_crashlytics/lib/src/firebase_crashlytics.dart index e6b07ca2efb0..2f2f9b91204d 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/lib/src/firebase_crashlytics.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics/lib/src/firebase_crashlytics.dart @@ -10,7 +10,7 @@ part of '../firebase_crashlytics.dart'; /// You can get an instance by calling [FirebaseCrashlytics.instance]. class FirebaseCrashlytics extends FirebasePlugin { FirebaseCrashlytics._({required this.app}) - : super(app.name, 'plugins.flutter.io/firebase_crashlytics'); + : super(app.name, 'plugins.flutter.io/firebase_crashlytics'); /// Cached instance of [FirebaseCrashlytics]; static FirebaseCrashlytics? _instance; @@ -22,7 +22,9 @@ class FirebaseCrashlytics extends FirebasePlugin { FirebaseCrashlyticsPlatform get _delegate { return _delegatePackingProperty ??= FirebaseCrashlyticsPlatform.instanceFor( - app: app, pluginConstants: pluginConstants); + app: app, + pluginConstants: pluginConstants, + ); } /// The [FirebaseApp] for this current [FirebaseCrashlytics] instance. @@ -76,11 +78,14 @@ class FirebaseCrashlytics extends FirebasePlugin { } /// Submits a Crashlytics report of a caught error. - Future recordError(dynamic exception, StackTrace? stack, - {dynamic reason, - Iterable information = const [], - bool? printDetails, - bool fatal = false}) async { + Future recordError( + dynamic exception, + StackTrace? stack, { + dynamic reason, + Iterable information = const [], + bool? printDetails, + bool fatal = false, + }) async { // Use the debug flag if printDetails is not provided printDetails ??= kDebugMode; @@ -120,8 +125,9 @@ class FirebaseCrashlytics extends FirebasePlugin { : stack; // Report error. - final List> stackTraceElements = - getStackTraceElements(stackTrace); + final List> stackTraceElements = getStackTraceElements( + stackTrace, + ); final String? buildId = getBuildId(stackTrace); final List loadingUnits = getLoadingUnits(stackTrace); @@ -138,8 +144,10 @@ class FirebaseCrashlytics extends FirebasePlugin { /// Submits a Crashlytics report of an error caught by the Flutter framework. /// Use [fatal] to indicate whether the error is a fatal or not. - Future recordFlutterError(FlutterErrorDetails flutterErrorDetails, - {bool fatal = false}) { + Future recordFlutterError( + FlutterErrorDetails flutterErrorDetails, { + bool fatal = false, + }) { FlutterError.presentError(flutterErrorDetails); final information = flutterErrorDetails.informationCollector?.call() ?? []; @@ -158,7 +166,8 @@ class FirebaseCrashlytics extends FirebasePlugin { /// Submits a Crashlytics report of a fatal error caught by the Flutter framework. Future recordFlutterFatalError( - FlutterErrorDetails flutterErrorDetails) { + FlutterErrorDetails flutterErrorDetails, + ) { return recordFlutterError(flutterErrorDetails, fatal: true); } diff --git a/packages/firebase_crashlytics/firebase_crashlytics/lib/src/utils.dart b/packages/firebase_crashlytics/firebase_crashlytics/lib/src/utils.dart index 74def5bc4d28..09cf4874d99e 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/lib/src/utils.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics/lib/src/utils.dart @@ -5,8 +5,9 @@ import 'package:stack_trace/stack_trace.dart'; -final _obfuscatedStackTraceLineRegExp = - RegExp(r'^(\s*#\d{2} abs )([\da-f]+)((?: virt [\da-f]+)?(?: .*)?)$'); +final _obfuscatedStackTraceLineRegExp = RegExp( + r'^(\s*#\d{2} abs )([\da-f]+)((?: virt [\da-f]+)?(?: .*)?)$', +); /// Returns a [List] containing detailed output of each line in a stack trace. List> getStackTraceElements(StackTrace stackTrace) { @@ -66,9 +67,7 @@ String? getBuildId(StackTrace stackTrace) { } List getLoadingUnits(StackTrace stackTrace) => - Trace.parseVM(stackTrace.toString()) - .terse - .frames + Trace.parseVM(stackTrace.toString()).terse.frames .whereType() .map((frame) => frame.member) .where((member) => member.startsWith('loading_unit: ')) diff --git a/packages/firebase_crashlytics/firebase_crashlytics/pubspec.yaml b/packages/firebase_crashlytics/firebase_crashlytics/pubspec.yaml index 3163941d6525..a3fdf997166c 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/pubspec.yaml +++ b/packages/firebase_crashlytics/firebase_crashlytics/pubspec.yaml @@ -16,8 +16,8 @@ false_secrets: - example/** environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core: ^4.14.0 diff --git a/packages/firebase_crashlytics/firebase_crashlytics/test/firebase_crashlytics_test.dart b/packages/firebase_crashlytics/firebase_crashlytics/test/firebase_crashlytics_test.dart index 8f0b8eec0416..0994580f5917 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/test/firebase_crashlytics_test.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics/test/firebase_crashlytics_test.dart @@ -60,8 +60,11 @@ void main() { const exception = 'foo exception'; const exceptionReason = 'bar reason'; - await crashlytics! - .recordError(exception, stack, reason: exceptionReason); + await crashlytics!.recordError( + exception, + stack, + reason: exceptionReason, + ); expect(hostApi.calls, ['recordError']); expect(hostApi.lastRecordError!.exception, exception); expect(hostApi.lastRecordError!.reason, exceptionReason); @@ -79,8 +82,11 @@ void main() { const exception = 'foo exception'; const exceptionReason = 'bar reason'; - await crashlytics! - .recordError(exception, null, reason: exceptionReason); + await crashlytics!.recordError( + exception, + null, + reason: exceptionReason, + ); expect(hostApi.calls, ['recordError']); expect(hostApi.lastRecordError!.exception, exception); expect(hostApi.lastRecordError!.reason, exceptionReason); @@ -120,8 +126,10 @@ void main() { expect(hostApi.lastRecordError!.exception, exception); expect(hostApi.lastRecordError!.reason, exceptionReason); expect(hostApi.lastRecordError!.fatal, isFalse); - expect(hostApi.lastRecordError!.information, - '$exceptionFirstMessage\n$exceptionSecondMessage'); + expect( + hostApi.lastRecordError!.information, + '$exceptionFirstMessage\n$exceptionSecondMessage', + ); expect(hostApi.lastRecordError!.buildId, ''); expect(hostApi.lastRecordError!.loadingUnits, isEmpty); expect( @@ -175,9 +183,13 @@ void main() { group('setCustomKey', () { test('should throw if null', () async { expect( - () => crashlytics!.setCustomKey('foo', []), throwsAssertionError); + () => crashlytics!.setCustomKey('foo', []), + throwsAssertionError, + ); expect( - () => crashlytics!.setCustomKey('foo', {}), throwsAssertionError); + () => crashlytics!.setCustomKey('foo', {}), + throwsAssertionError, + ); }); test('should call delegate method', () async { @@ -193,7 +205,7 @@ void main() { group('getStackTraceElements', () { test('with symbolic stack trace', () async { final List lines = [ - '#0 StatefulElement.build (package:flutter/src/widgets/framework.dart:3825:27)' + '#0 StatefulElement.build (package:flutter/src/widgets/framework.dart:3825:27)', ]; final StackTrace trace = StackTrace.fromString(lines.join('\n')); final List> elements = getStackTraceElements(trace); @@ -208,7 +220,7 @@ void main() { test('with symbolic stack trace and without class', () async { final List lines = [ - '#0 main (package:firebase_crashlytics/test/main.dart:12)' + '#0 main (package:firebase_crashlytics/test/main.dart:12)', ]; final StackTrace trace = StackTrace.fromString(lines.join('\n')); final List> elements = getStackTraceElements(trace); diff --git a/packages/firebase_crashlytics/firebase_crashlytics/test/mock.dart b/packages/firebase_crashlytics/firebase_crashlytics/test/mock.dart index aac300034597..d39ce5be224b 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics/test/mock.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics/test/mock.dart @@ -26,8 +26,8 @@ class MockFirebaseAppWithCollectionEnabled implements TestFirebaseCoreHostApi { ), pluginConstants: { 'plugins.flutter.io/firebase_crashlytics': { - 'isCrashlyticsCollectionEnabled': true - } + 'isCrashlyticsCollectionEnabled': true, + }, }, ); } @@ -45,10 +45,10 @@ class MockFirebaseAppWithCollectionEnabled implements TestFirebaseCoreHostApi { ), pluginConstants: { 'plugins.flutter.io/firebase_crashlytics': { - 'isCrashlyticsCollectionEnabled': true - } + 'isCrashlyticsCollectionEnabled': true, + }, }, - ) + ), ]; } diff --git a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/method_channel/method_channel_crashlytics.dart b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/method_channel/method_channel_crashlytics.dart index 52606b13ec8f..0274f5f8cad3 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/method_channel/method_channel_crashlytics.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/method_channel/method_channel_crashlytics.dart @@ -18,7 +18,7 @@ import '../platform_interface/platform_interface_crashlytics.dart'; class MethodChannelFirebaseCrashlytics extends FirebaseCrashlyticsPlatform { /// Create an instance of [MethodChannelFirebaseCrashlytics]. MethodChannelFirebaseCrashlytics({required FirebaseApp app}) - : super(appInstance: app); + : super(appInstance: app); static final pigeon.FirebaseCrashlyticsHostApi pigeonChannel = pigeon.FirebaseCrashlyticsHostApi(); @@ -42,7 +42,8 @@ class MethodChannelFirebaseCrashlytics extends FirebaseCrashlyticsPlatform { Future checkForUnsentReports() async { if (isCrashlyticsCollectionEnabled) { throw StateError( - "Crashlytics#setCrashlyticsCollectionEnabled has been set to 'true', all reports are automatically sent."); + "Crashlytics#setCrashlyticsCollectionEnabled has been set to 'true', all reports are automatically sent.", + ); } try { @@ -136,8 +137,8 @@ class MethodChannelFirebaseCrashlytics extends FirebaseCrashlyticsPlatform { @override Future setCrashlyticsCollectionEnabled(bool enabled) async { try { - _isCrashlyticsCollectionEnabled = - await pigeonChannel.setCrashlyticsCollectionEnabled(enabled); + _isCrashlyticsCollectionEnabled = await pigeonChannel + .setCrashlyticsCollectionEnabled(enabled); } catch (e, s) { convertPlatformException(e, s); } diff --git a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/pigeon/messages.pigeon.dart b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/pigeon/messages.pigeon.dart index fc72df791f61..8e7ce09c05cf 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/pigeon/messages.pigeon.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/pigeon/messages.pigeon.dart @@ -37,8 +37,11 @@ Object? _extractReplyValueOrThrow( return replyList.firstOrNull; } -List wrapResponse( - {Object? result, PlatformException? error, bool empty = false}) { +List wrapResponse({ + Object? result, + PlatformException? error, + bool empty = false, +}) { if (empty) { return []; } @@ -60,8 +63,9 @@ bool _deepEquals(Object? a, Object? b) { } if (a is List && b is List) { return a.length == b.length && - a.indexed - .every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1])); + a.indexed.every( + ((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]), + ); } if (a is Map && b is Map) { if (a.length != b.length) { @@ -128,12 +132,7 @@ class CrashlyticsStackFrame { String line; List _toList() { - return [ - className, - method, - file, - line, - ]; + return [className, method, file, line]; } Object encode() { @@ -220,8 +219,8 @@ class RecordErrorRequest { fatal: result[3]! as bool, buildId: result[4]! as String, loadingUnits: (result[5]! as List).cast(), - stackTraceElements: - (result[6]! as List).cast(), + stackTraceElements: (result[6]! as List) + .cast(), ); } @@ -283,11 +282,13 @@ class FirebaseCrashlyticsHostApi { /// Constructor for [FirebaseCrashlyticsHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - FirebaseCrashlyticsHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + FirebaseCrashlyticsHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -376,8 +377,9 @@ class FirebaseCrashlyticsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -395,8 +397,9 @@ class FirebaseCrashlyticsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([message]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [message], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -432,8 +435,9 @@ class FirebaseCrashlyticsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([enabled]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [enabled], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -452,8 +456,9 @@ class FirebaseCrashlyticsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([identifier]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [identifier], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -471,8 +476,9 @@ class FirebaseCrashlyticsHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([key, value]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [key, value], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( diff --git a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/pigeon/test_api.dart b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/pigeon/test_api.dart index ce8557309960..877031bfe3f7 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/pigeon/test_api.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/pigeon/test_api.dart @@ -74,258 +74,321 @@ abstract class TestFirebaseCrashlyticsHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.checkForUnsentReports$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.checkForUnsentReports$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - try { - final bool output = await api.checkForUnsentReports(); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + try { + final bool output = await api.checkForUnsentReports(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.crash$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.crash$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - try { - await api.crash(); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + try { + await api.crash(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.deleteUnsentReports$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.deleteUnsentReports$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - try { - await api.deleteUnsentReports(); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + try { + await api.deleteUnsentReports(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.didCrashOnPreviousExecution$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.didCrashOnPreviousExecution$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - try { - final bool output = await api.didCrashOnPreviousExecution(); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + try { + final bool output = await api.didCrashOnPreviousExecution(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.recordError$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.recordError$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final RecordErrorRequest arg_request = args[0]! as RecordErrorRequest; - try { - await api.recordError(arg_request); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final RecordErrorRequest arg_request = + args[0]! as RecordErrorRequest; + try { + await api.recordError(arg_request); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.log$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.log$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_message = args[0]! as String; - try { - await api.log(arg_message); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_message = args[0]! as String; + try { + await api.log(arg_message); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.sendUnsentReports$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.sendUnsentReports$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - try { - await api.sendUnsentReports(); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + try { + await api.sendUnsentReports(); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.setCrashlyticsCollectionEnabled$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.setCrashlyticsCollectionEnabled$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final bool arg_enabled = args[0]! as bool; - try { - final bool output = - await api.setCrashlyticsCollectionEnabled(arg_enabled); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final bool arg_enabled = args[0]! as bool; + try { + final bool output = await api.setCrashlyticsCollectionEnabled( + arg_enabled, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.setUserIdentifier$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.setUserIdentifier$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_identifier = args[0]! as String; - try { - await api.setUserIdentifier(arg_identifier); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_identifier = args[0]! as String; + try { + await api.setUserIdentifier(arg_identifier); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.setCustomKey$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_crashlytics_platform_interface.FirebaseCrashlyticsHostApi.setCustomKey$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_key = args[0]! as String; - final String arg_value = args[1]! as String; - try { - await api.setCustomKey(arg_key, arg_value); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_key = args[0]! as String; + final String arg_value = args[1]! as String; + try { + await api.setCustomKey(arg_key, arg_value); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } diff --git a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/platform_interface/platform_interface_crashlytics.dart b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/platform_interface/platform_interface_crashlytics.dart index 78a24ed2e356..36cfded1bbdf 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/platform_interface/platform_interface_crashlytics.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/platform_interface/platform_interface_crashlytics.dart @@ -18,12 +18,13 @@ import '../method_channel/method_channel_crashlytics.dart'; abstract class FirebaseCrashlyticsPlatform extends PlatformInterface { /// The [FirebaseApp] this instance was initialized with. FirebaseCrashlyticsPlatform({required this.appInstance}) - : super(token: _token); + : super(token: _token); /// Create an instance using [app] using the existing implementation - factory FirebaseCrashlyticsPlatform.instanceFor( - {required FirebaseApp app, - required Map pluginConstants}) { + factory FirebaseCrashlyticsPlatform.instanceFor({ + required FirebaseApp app, + required Map pluginConstants, + }) { // Only the default app is supported on Crashlytics. assert(app.name == defaultFirebaseAppName); // Must have bool collection enabled constant. @@ -69,7 +70,8 @@ abstract class FirebaseCrashlyticsPlatform extends PlatformInterface { /// See [setCrashlyticsCollectionEnabled] for toggling collection status. bool get isCrashlyticsCollectionEnabled { throw UnimplementedError( - 'isCrashlyticsCollectionEnabled is not implemented'); + 'isCrashlyticsCollectionEnabled is not implemented', + ); } /// Checks a device for any fatal or non-fatal crash reports that haven't yet @@ -103,7 +105,8 @@ abstract class FirebaseCrashlyticsPlatform extends PlatformInterface { /// Checks whether the app crashed on its previous run. Future didCrashOnPreviousExecution() { throw UnimplementedError( - 'didCrashOnPreviousExecution() is not implemented'); + 'didCrashOnPreviousExecution() is not implemented', + ); } /// Submits a Crashlytics report of a caught error. @@ -149,7 +152,8 @@ abstract class FirebaseCrashlyticsPlatform extends PlatformInterface { /// stored on the device without sending them to Crashlytics. Future setCrashlyticsCollectionEnabled(bool enabled) { throw UnimplementedError( - 'setCrashlyticsCollectionEnabled() is not implemented'); + 'setCrashlyticsCollectionEnabled() is not implemented', + ); } /// Records a user ID (identifier) that's associated with subsequent fatal and diff --git a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/pubspec.yaml b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/pubspec.yaml index 0bbc708ad99d..2ab1a64fca4e 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/pubspec.yaml +++ b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/pubspec.yaml @@ -6,8 +6,8 @@ homepage: https://github.com/firebase/flutterfire/tree/main/packages/firebase_cr repository: https://github.com/firebase/flutterfire/tree/main/packages/firebase_crashlytics/firebase_crashlytics_platform_interface environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/method_channel_tests/method_channel_crashlytics_test.dart b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/method_channel_tests/method_channel_crashlytics_test.dart index b5086952ff65..00b482e17e33 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/method_channel_tests/method_channel_crashlytics_test.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/method_channel_tests/method_channel_crashlytics_test.dart @@ -27,7 +27,7 @@ void main() { 'method': 'recordError', 'file': 'method_channel_crashlytics_test.dart', 'line': '99999', - } + }, ]; group('$MethodChannelFirebaseCrashlytics', () { @@ -57,15 +57,16 @@ void main() { }); test( - 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', - () async { - hostApi.throwPlatformException = true; - - await testExceptionHandling( - 'PLATFORM', - mockCrashlytics.checkForUnsentReports, - ); - }); + 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', + () async { + hostApi.throwPlatformException = true; + + await testExceptionHandling( + 'PLATFORM', + mockCrashlytics.checkForUnsentReports, + ); + }, + ); }); group('crash', () { @@ -76,12 +77,13 @@ void main() { }); test( - 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', - () async { - hostApi.throwPlatformException = true; + 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', + () async { + hostApi.throwPlatformException = true; - await testExceptionHandling('PLATFORM', crashlytics.crash); - }); + await testExceptionHandling('PLATFORM', crashlytics.crash); + }, + ); }); group('deleteUnsentReports', () { @@ -94,15 +96,16 @@ void main() { }); test( - 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', - () async { - hostApi.throwPlatformException = true; - - await testExceptionHandling( - 'PLATFORM', - crashlytics.deleteUnsentReports, - ); - }); + 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', + () async { + hostApi.throwPlatformException = true; + + await testExceptionHandling( + 'PLATFORM', + crashlytics.deleteUnsentReports, + ); + }, + ); }); group('didCrashOnPreviousExecution', () { @@ -114,15 +117,16 @@ void main() { }); test( - 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', - () async { - hostApi.throwPlatformException = true; - - await testExceptionHandling( - 'PLATFORM', - crashlytics.didCrashOnPreviousExecution, - ); - }); + 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', + () async { + hostApi.throwPlatformException = true; + + await testExceptionHandling( + 'PLATFORM', + crashlytics.didCrashOnPreviousExecution, + ); + }, + ); }); group('recordError', () { @@ -155,20 +159,21 @@ void main() { }); test( - 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', - () async { - hostApi.throwPlatformException = true; - - await testExceptionHandling( - 'PLATFORM', - () => crashlytics.recordError( - exception: 'test exception', - reason: 'test', - information: 'test', - stackTraceElements: [], - ), - ); - }); + 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', + () async { + hostApi.throwPlatformException = true; + + await testExceptionHandling( + 'PLATFORM', + () => crashlytics.recordError( + exception: 'test exception', + reason: 'test', + information: 'test', + stackTraceElements: [], + ), + ); + }, + ); }); test('log', () async { @@ -185,12 +190,16 @@ void main() { }); test( - 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', - () async { - hostApi.throwPlatformException = true; - - await testExceptionHandling('PLATFORM', crashlytics.sendUnsentReports); - }); + 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', + () async { + hostApi.throwPlatformException = true; + + await testExceptionHandling( + 'PLATFORM', + crashlytics.sendUnsentReports, + ); + }, + ); }); group('setCrashlyticsCollectionEnabled', () { @@ -201,15 +210,16 @@ void main() { }); test( - 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', - () async { - hostApi.throwPlatformException = true; - - await testExceptionHandling( - 'PLATFORM', - () => crashlytics.setCrashlyticsCollectionEnabled(true), - ); - }); + 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', + () async { + hostApi.throwPlatformException = true; + + await testExceptionHandling( + 'PLATFORM', + () => crashlytics.setCrashlyticsCollectionEnabled(true), + ); + }, + ); }); group('setUserIdentifier', () { @@ -220,15 +230,16 @@ void main() { }); test( - 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', - () async { - hostApi.throwPlatformException = true; - - await testExceptionHandling( - 'PLATFORM', - () => crashlytics.setUserIdentifier(kMockUserIdentifier), - ); - }); + 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', + () async { + hostApi.throwPlatformException = true; + + await testExceptionHandling( + 'PLATFORM', + () => crashlytics.setUserIdentifier(kMockUserIdentifier), + ); + }, + ); }); group('setCustomKey', () { @@ -240,15 +251,16 @@ void main() { }); test( - 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', - () async { - hostApi.throwPlatformException = true; - - await testExceptionHandling( - 'PLATFORM', - () => crashlytics.setCustomKey('foo', 'bar'), - ); - }); + 'catch a [PlatformException] error and throws a [FirebaseCrashlyticsException] error', + () async { + hostApi.throwPlatformException = true; + + await testExceptionHandling( + 'PLATFORM', + () => crashlytics.setCustomKey('foo', 'bar'), + ); + }, + ); }); }); } diff --git a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/method_channel_tests/utils_tests/exception_test.dart b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/method_channel_tests/utils_tests/exception_test.dart index 0c1164f31c1f..b03c5a1f73cf 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/method_channel_tests/utils_tests/exception_test.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/method_channel_tests/utils_tests/exception_test.dart @@ -19,16 +19,20 @@ void main() { ); }); - test('should catch a [PlatformException] and throw a [FirebaseException]', - () async { - PlatformException platformException = PlatformException(code: 'UNKNOWN'); + test( + 'should catch a [PlatformException] and throw a [FirebaseException]', + () async { + PlatformException platformException = PlatformException( + code: 'UNKNOWN', + ); - expect( - () => convertPlatformException(platformException, StackTrace.empty), - throwsA( - isA().having((e) => e.code, 'code', 'unknown'), - ), - ); - }); + expect( + () => convertPlatformException(platformException, StackTrace.empty), + throwsA( + isA().having((e) => e.code, 'code', 'unknown'), + ), + ); + }, + ); }); } diff --git a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/mock.dart b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/mock.dart index cf3d7c6261ea..745c59d4de3e 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/mock.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/mock.dart @@ -21,7 +21,8 @@ Future testExceptionHandling(String type, Function testMethod) async { return; } fail( - 'testExceptionHandling: $testMethod threw unexpected FirebaseException'); + 'testExceptionHandling: $testMethod threw unexpected FirebaseException', + ); } catch (e) { fail('testExceptionHandling: $testMethod threw invalid exception $e'); } diff --git a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/platform_interface_tests/platform_interface_crashlytics_test.dart b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/platform_interface_tests/platform_interface_crashlytics_test.dart index 15b6e67fe8ee..5557fef67733 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/platform_interface_tests/platform_interface_crashlytics_test.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/platform_interface_tests/platform_interface_crashlytics_test.dart @@ -31,9 +31,7 @@ void main() { ), ); - firebaseCrashlyticsPlatform = TestFirebaseCrashlyticsPlatform( - app, - ); + firebaseCrashlyticsPlatform = TestFirebaseCrashlyticsPlatform(app); }); test('Constructor', () { @@ -42,69 +40,108 @@ void main() { }); test('get.instance', () { - expect(FirebaseCrashlyticsPlatform.instance, - isA()); - expect(FirebaseCrashlyticsPlatform.instance.app.name, - equals(defaultFirebaseAppName)); + expect( + FirebaseCrashlyticsPlatform.instance, + isA(), + ); + expect( + FirebaseCrashlyticsPlatform.instance.app.name, + equals(defaultFirebaseAppName), + ); }); group('set.instance', () { test('sets the current instance', () { - FirebaseCrashlyticsPlatform.instance = - TestFirebaseCrashlyticsPlatform(secondaryApp); + FirebaseCrashlyticsPlatform.instance = TestFirebaseCrashlyticsPlatform( + secondaryApp, + ); - expect(FirebaseCrashlyticsPlatform.instance, - isA()); expect( - FirebaseCrashlyticsPlatform.instance.app.name, equals('testApp2')); + FirebaseCrashlyticsPlatform.instance, + isA(), + ); + expect( + FirebaseCrashlyticsPlatform.instance.app.name, + equals('testApp2'), + ); }); }); test('throws if .checkForUnsentReports', () { expect( () => firebaseCrashlyticsPlatform!.checkForUnsentReports(), - throwsA(isA().having((e) => e.message, 'message', - 'checkForUnsentReports() is not implemented')), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'checkForUnsentReports() is not implemented', + ), + ), ); }); test('throws if .crash', () { expect( () => firebaseCrashlyticsPlatform!.crash(), - throwsA(isA() - .having((e) => e.message, 'message', 'crash() is not implemented')), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'crash() is not implemented', + ), + ), ); }); test('throws if .deleteUnsentReports', () { expect( () => firebaseCrashlyticsPlatform!.deleteUnsentReports(), - throwsA(isA().having((e) => e.message, 'message', - 'deleteUnsentReports() is not implemented')), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'deleteUnsentReports() is not implemented', + ), + ), ); }); test('throws if .didCrashOnPreviousExecution', () { expect( () => firebaseCrashlyticsPlatform!.didCrashOnPreviousExecution(), - throwsA(isA().having((e) => e.message, 'message', - 'didCrashOnPreviousExecution() is not implemented')), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'didCrashOnPreviousExecution() is not implemented', + ), + ), ); }); test('throws if .log', () { expect( () => firebaseCrashlyticsPlatform!.log('foo'), - throwsA(isA() - .having((e) => e.message, 'message', 'log() is not implemented')), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'log() is not implemented', + ), + ), ); }); test('throws if .sendUnsentReports', () { expect( () => firebaseCrashlyticsPlatform!.sendUnsentReports(), - throwsA(isA().having((e) => e.message, 'message', - 'sendUnsentReports() is not implemented')), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'sendUnsentReports() is not implemented', + ), + ), ); }); @@ -112,8 +149,13 @@ void main() { expect( () => firebaseCrashlyticsPlatform!.setCrashlyticsCollectionEnabled(true), - throwsA(isA().having((e) => e.message, 'message', - 'setCrashlyticsCollectionEnabled() is not implemented')), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'setCrashlyticsCollectionEnabled() is not implemented', + ), + ), ); }); diff --git a/packages/firebase_data_connect/firebase_data_connect/example/integration_test/cache_e2e.dart b/packages/firebase_data_connect/firebase_data_connect/example/integration_test/cache_e2e.dart index 70f7621674ab..c2515553b8a7 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/integration_test/cache_e2e.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/integration_test/cache_e2e.dart @@ -9,77 +9,71 @@ import 'package:flutter_test/flutter_test.dart'; import 'query_e2e.dart'; // For deleteAllMovies void runCacheTests() { - group( - '$FirebaseDataConnect cache', - () { - setUp(() async { - final dataConnect = MoviesConnector.instance.dataConnect; - // Temporarily disable cache during database cleanup to prevent populating it - dataConnect.cacheSettings = null; - dataConnect.useDataConnectEmulator('127.0.0.1', 9399); + group('$FirebaseDataConnect cache', () { + setUp(() async { + final dataConnect = MoviesConnector.instance.dataConnect; + // Temporarily disable cache during database cleanup to prevent populating it + dataConnect.cacheSettings = null; + dataConnect.useDataConnectEmulator('127.0.0.1', 9399); - await deleteAllMovies(); + await deleteAllMovies(); - // Enable cache with memory storage and a large TTL for testing. - dataConnect.cacheSettings = CacheSettings( - storage: CacheStorage.memory, - maxAge: const Duration(minutes: 5), - ); - // Re-apply emulator to force cache manager recreation with new settings - dataConnect.useDataConnectEmulator('127.0.0.1', 9399); - }); + // Enable cache with memory storage and a large TTL for testing. + dataConnect.cacheSettings = CacheSettings( + storage: CacheStorage.memory, + maxAge: const Duration(minutes: 5), + ); + // Re-apply emulator to force cache manager recreation with new settings + dataConnect.useDataConnectEmulator('127.0.0.1', 9399); + }); - testWidgets('test cache flow: serverOnly, cacheOnly, preferCache', - (WidgetTester tester) async { - final moviesConnector = MoviesConnector.instance; + testWidgets('test cache flow: serverOnly, cacheOnly, preferCache', ( + WidgetTester tester, + ) async { + final moviesConnector = MoviesConnector.instance; - // 1. Initial query with preferCache should result in server hit because cache is empty. - final res1 = await moviesConnector.listMovies().ref().execute( - fetchPolicy: QueryFetchPolicy.preferCache, - ); - expect(res1.source, DataSource.server); - expect(res1.data.movies, isEmpty); + // 1. Initial query with preferCache should result in server hit because cache is empty. + final res1 = await moviesConnector.listMovies().ref().execute( + fetchPolicy: QueryFetchPolicy.preferCache, + ); + expect(res1.source, DataSource.server); + expect(res1.data.movies, isEmpty); - // 2. Second query with preferCache should result in cache hit. - final res2 = await moviesConnector.listMovies().ref().execute( - fetchPolicy: QueryFetchPolicy.preferCache, - ); - expect(res2.source, DataSource.cache); - expect(res2.data.movies, isEmpty); + // 2. Second query with preferCache should result in cache hit. + final res2 = await moviesConnector.listMovies().ref().execute( + fetchPolicy: QueryFetchPolicy.preferCache, + ); + expect(res2.source, DataSource.cache); + expect(res2.data.movies, isEmpty); - // 3. Mutation to add a movie. This goes to server. - await moviesConnector - .createMovie( - genre: 'Sci-Fi', - title: 'Inception', - releaseYear: 2010, - ) - .ref() - .execute(); + // 3. Mutation to add a movie. This goes to server. + await moviesConnector + .createMovie(genre: 'Sci-Fi', title: 'Inception', releaseYear: 2010) + .ref() + .execute(); - // 4. Query with cacheOnly should still return empty list (cache hit, stale data). - final res3 = await moviesConnector.listMovies().ref().execute( - fetchPolicy: QueryFetchPolicy.cacheOnly, - ); - expect(res3.source, DataSource.cache); - expect(res3.data.movies, isEmpty); + // 4. Query with cacheOnly should still return empty list (cache hit, stale data). + final res3 = await moviesConnector.listMovies().ref().execute( + fetchPolicy: QueryFetchPolicy.cacheOnly, + ); + expect(res3.source, DataSource.cache); + expect(res3.data.movies, isEmpty); - // 5. Query with serverOnly should return the new movie (server hit) and update cache. - final res4 = await moviesConnector.listMovies().ref().execute( - fetchPolicy: QueryFetchPolicy.serverOnly, - ); - expect(res4.source, DataSource.server); - expect(res4.data.movies.length, 1); - expect(res4.data.movies[0].title, 'Inception'); + // 5. Query with serverOnly should return the new movie (server hit) and update cache. + final res4 = await moviesConnector.listMovies().ref().execute( + fetchPolicy: QueryFetchPolicy.serverOnly, + ); + expect(res4.source, DataSource.server); + expect(res4.data.movies.length, 1); + expect(res4.data.movies[0].title, 'Inception'); - // 6. Query with cacheOnly should now return the new movie (cache hit). - final res5 = await moviesConnector.listMovies().ref().execute( - fetchPolicy: QueryFetchPolicy.cacheOnly, - ); - expect(res5.source, DataSource.cache); - expect(res5.data.movies.length, 1); - expect(res5.data.movies[0].title, 'Inception'); - }); - }, - ); + // 6. Query with cacheOnly should now return the new movie (cache hit). + final res5 = await moviesConnector.listMovies().ref().execute( + fetchPolicy: QueryFetchPolicy.cacheOnly, + ); + expect(res5.source, DataSource.cache); + expect(res5.data.movies.length, 1); + expect(res5.data.movies[0].title, 'Inception'); + }); + }); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/integration_test/e2e_test.dart b/packages/firebase_data_connect/firebase_data_connect/example/integration_test/e2e_test.dart index 4e99c608a398..e25ee3f2740c 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/integration_test/e2e_test.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/integration_test/e2e_test.dart @@ -32,10 +32,7 @@ Future _signInTestUser() async { return; } on FirebaseAuthException catch (e) { if (e.code == 'email-already-in-use') { - await auth.signInWithEmailAndPassword( - email: email, - password: password, - ); + await auth.signInWithEmailAndPassword(email: email, password: password); return; } @@ -71,8 +68,9 @@ void main() { final connector = MoviesConnector.connectorConfig; - FirebaseDataConnect.instanceFor(connectorConfig: connector) - .useDataConnectEmulator('127.0.0.1', 9399); + FirebaseDataConnect.instanceFor( + connectorConfig: connector, + ).useDataConnectEmulator('127.0.0.1', 9399); await FirebaseAuth.instance.useAuthEmulator('127.0.0.1', 9099); await _signInTestUser(); diff --git a/packages/firebase_data_connect/firebase_data_connect/example/integration_test/generation_e2e.dart b/packages/firebase_data_connect/firebase_data_connect/example/integration_test/generation_e2e.dart index ccedb69f4930..f658878702e7 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/integration_test/generation_e2e.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/integration_test/generation_e2e.dart @@ -7,63 +7,61 @@ import 'package:firebase_data_connect_example/generated/movies.dart'; import 'package:flutter_test/flutter_test.dart'; void runGenerationTest() { - group( - '$FirebaseDataConnect generation', - () { - late FirebaseDataConnect fdc; + group('$FirebaseDataConnect generation', () { + late FirebaseDataConnect fdc; - setUpAll(() async { - fdc = FirebaseDataConnect.instanceFor( - connectorConfig: MoviesConnector.connectorConfig, - ); - }); + setUpAll(() async { + fdc = FirebaseDataConnect.instanceFor( + connectorConfig: MoviesConnector.connectorConfig, + ); + }); - testWidgets('should have generated correct MoviesConnector', - (WidgetTester tester) async { - final connector = MoviesConnector(dataConnect: fdc); - expect(connector, isNotNull); - expect(connector.addPerson, isNotNull); - expect(connector.createMovie, isNotNull); - expect(connector.listMovies, isNotNull); - expect(connector.addDirectorToMovie, isNotNull); - }); + testWidgets('should have generated correct MoviesConnector', ( + WidgetTester tester, + ) async { + final connector = MoviesConnector(dataConnect: fdc); + expect(connector, isNotNull); + expect(connector.addPerson, isNotNull); + expect(connector.createMovie, isNotNull); + expect(connector.listMovies, isNotNull); + expect(connector.addDirectorToMovie, isNotNull); + }); - testWidgets('should have generated correct MutationRef', - (WidgetTester tester) async { - final ref = MoviesConnector.instance - .createMovie( - genre: 'Action', - title: 'The Matrix', - releaseYear: 1999, - ) - .rating(4.5); - expect(ref, isNotNull); - expect(ref.execute, isNotNull); - }); + testWidgets('should have generated correct MutationRef', ( + WidgetTester tester, + ) async { + final ref = MoviesConnector.instance + .createMovie(genre: 'Action', title: 'The Matrix', releaseYear: 1999) + .rating(4.5); + expect(ref, isNotNull); + expect(ref.execute, isNotNull); + }); - testWidgets('should have generated correct QueryRef', - (WidgetTester tester) async { - final ref = MoviesConnector.instance.listMovies().ref(); - expect(ref, isNotNull); - expect(ref.execute, isNotNull); - }); + testWidgets('should have generated correct QueryRef', ( + WidgetTester tester, + ) async { + final ref = MoviesConnector.instance.listMovies().ref(); + expect(ref, isNotNull); + expect(ref.execute, isNotNull); + }); - testWidgets('should have generated correct MutationRef using name', - (WidgetTester tester) async { - final ref = MoviesConnector.instance.addPerson().name('Keanu Reeves'); - expect(ref, isNotNull); - expect(ref.execute, isNotNull); - }); + testWidgets('should have generated correct MutationRef using name', ( + WidgetTester tester, + ) async { + final ref = MoviesConnector.instance.addPerson().name('Keanu Reeves'); + expect(ref, isNotNull); + expect(ref.execute, isNotNull); + }); - testWidgets('should have generated correct MutationRef using nested id', - (WidgetTester tester) async { - final ref = MoviesConnector.instance - .addDirectorToMovie() - .movieId('movieId') - .personId(AddDirectorToMovieVariablesPersonId(id: 'personId')); - expect(ref, isNotNull); - expect(ref.execute, isNotNull); - }); - }, - ); + testWidgets('should have generated correct MutationRef using nested id', ( + WidgetTester tester, + ) async { + final ref = MoviesConnector.instance + .addDirectorToMovie() + .movieId('movieId') + .personId(AddDirectorToMovieVariablesPersonId(id: 'personId')); + expect(ref, isNotNull); + expect(ref.execute, isNotNull); + }); + }); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/integration_test/instance_e2e.dart b/packages/firebase_data_connect/firebase_data_connect/example/integration_test/instance_e2e.dart index 475af5d79a5a..2fe710655fc5 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/integration_test/instance_e2e.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/integration_test/instance_e2e.dart @@ -8,27 +8,24 @@ import 'package:firebase_data_connect_example/generated/movies.dart'; import 'package:flutter_test/flutter_test.dart'; void runInstanceTests() { - group( - '$FirebaseDataConnect.instance', - () { - late FirebaseDataConnect fdc; - late FirebaseApp app; + group('$FirebaseDataConnect.instance', () { + late FirebaseDataConnect fdc; + late FirebaseApp app; - setUpAll(() async { - app = Firebase.app(); - fdc = FirebaseDataConnect.instanceFor( - app: app, - connectorConfig: MoviesConnector.connectorConfig, - ); - }); + setUpAll(() async { + app = Firebase.app(); + fdc = FirebaseDataConnect.instanceFor( + app: app, + connectorConfig: MoviesConnector.connectorConfig, + ); + }); - testWidgets('can instantiate', (WidgetTester tester) async { - expect(fdc, isNotNull); - }); + testWidgets('can instantiate', (WidgetTester tester) async { + expect(fdc, isNotNull); + }); - testWidgets('can access app', (WidgetTester tester) async { - expect(fdc.app == app, isTrue); - }); - }, - ); + testWidgets('can access app', (WidgetTester tester) async { + expect(fdc.app == app, isTrue); + }); + }); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/integration_test/listen_e2e.dart b/packages/firebase_data_connect/firebase_data_connect/example/integration_test/listen_e2e.dart index 3fd398768311..05d7a48a783c 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/integration_test/listen_e2e.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/integration_test/listen_e2e.dart @@ -24,185 +24,204 @@ const _wasmSkipReason = const _listenTimeout = Duration(seconds: 30); void runListenTests() { - group( - '$FirebaseDataConnect.instance listen', - () { - setUp(() async { - await deleteAllMovies(); - }); - - testWidgets('should be able to listen to the list of movies', - (WidgetTester tester) async { - final initialValue = - await MoviesConnector.instance.listMovies().ref().execute(); - expect(initialValue.data.movies.length, 0, - reason: 'Initial movie list should be empty'); - - final initialMovies = Completer>(); - final updatedMovies = Completer>(); - - final listener = MoviesConnector.instance - .listMovies() + group('$FirebaseDataConnect.instance listen', () { + setUp(() async { + await deleteAllMovies(); + }); + + testWidgets('should be able to listen to the list of movies', ( + WidgetTester tester, + ) async { + final initialValue = await MoviesConnector.instance + .listMovies() + .ref() + .execute(); + expect( + initialValue.data.movies.length, + 0, + reason: 'Initial movie list should be empty', + ); + + final initialMovies = Completer>(); + final updatedMovies = Completer>(); + + final listener = MoviesConnector.instance + .listMovies() + .ref() + .subscribe() + .listen((value) { + final movies = value.data.movies; + + if (!initialMovies.isCompleted && movies.isEmpty) { + initialMovies.complete(movies); + } else if (!updatedMovies.isCompleted && + movies.length == 1 && + movies.single.title == 'The Matrix') { + updatedMovies.complete(movies); + } + }); + + try { + // Wait for the listener to be ready + final initial = await initialMovies.future.timeout(_listenTimeout); + expect( + initial, + isEmpty, + reason: 'First emission should contain an empty list', + ); + + // Create the movie + await MoviesConnector.instance + .createMovie( + genre: 'Action', + title: 'The Matrix', + releaseYear: 1999, + ) + .rating(4.5) .ref() - .subscribe() - .listen((value) { - final movies = value.data.movies; - - if (!initialMovies.isCompleted && movies.isEmpty) { - initialMovies.complete(movies); - } else if (!updatedMovies.isCompleted && - movies.length == 1 && - movies.single.title == 'The Matrix') { - updatedMovies.complete(movies); - } - }); - - try { - // Wait for the listener to be ready - final initial = await initialMovies.future.timeout(_listenTimeout); - expect(initial, isEmpty, - reason: 'First emission should contain an empty list'); - - // Create the movie - await MoviesConnector.instance - .createMovie( - genre: 'Action', - title: 'The Matrix', - releaseYear: 1999, - ) - .rating(4.5) - .ref() - .execute(); - - await MoviesConnector.instance - .listMovies() - .ref() - .execute(fetchPolicy: QueryFetchPolicy.serverOnly); - - // Wait for the listener to receive the movie update - final movies = await updatedMovies.future.timeout(_listenTimeout); - - expect(movies, hasLength(1), - reason: 'Second emission should contain one movie'); - expect(movies.single.title, 'The Matrix', - reason: 'The movie should be The Matrix'); - } finally { - // Cancel the listener and wait for it to finish - await listener.cancel(); - } - }); - testWidgets('should be able to gracefully cancel', - (WidgetTester tester) async { - final initialValue = - await MoviesConnector.instance.listMovies().ref().execute(); - expect(initialValue.data.movies.length, 0, - reason: 'Initial movie list should be empty'); - - final listener1Ready = Completer(); - final listener2Ready = Completer(); - final listener1ReceivedFirstMovie = Completer(); - final listener2ReceivedFirstMovie = Completer(); - final listener2ReceivedSecondMovie = Completer(); - - int count1 = 0; - - final listener1 = MoviesConnector.instance - .listMovies() + .execute(); + + await MoviesConnector.instance.listMovies().ref().execute( + fetchPolicy: QueryFetchPolicy.serverOnly, + ); + + // Wait for the listener to receive the movie update + final movies = await updatedMovies.future.timeout(_listenTimeout); + + expect( + movies, + hasLength(1), + reason: 'Second emission should contain one movie', + ); + expect( + movies.single.title, + 'The Matrix', + reason: 'The movie should be The Matrix', + ); + } finally { + // Cancel the listener and wait for it to finish + await listener.cancel(); + } + }); + testWidgets('should be able to gracefully cancel', ( + WidgetTester tester, + ) async { + final initialValue = await MoviesConnector.instance + .listMovies() + .ref() + .execute(); + expect( + initialValue.data.movies.length, + 0, + reason: 'Initial movie list should be empty', + ); + + final listener1Ready = Completer(); + final listener2Ready = Completer(); + final listener1ReceivedFirstMovie = Completer(); + final listener2ReceivedFirstMovie = Completer(); + final listener2ReceivedSecondMovie = Completer(); + + int count1 = 0; + + final listener1 = MoviesConnector.instance + .listMovies() + .ref() + .subscribe() + .listen((value) { + count1++; + final movies = value.data.movies; + if (movies.isEmpty && !listener1Ready.isCompleted) { + listener1Ready.complete(); + } else if (movies.length == 1 && + movies.single.title == 'The Matrix' && + !listener1ReceivedFirstMovie.isCompleted) { + listener1ReceivedFirstMovie.complete(); + } + }); + + final listener2 = MoviesConnector.instance + .listMovies() + .ref() + .subscribe() + .listen((value) { + final movies = value.data.movies; + if (movies.isEmpty && !listener2Ready.isCompleted) { + listener2Ready.complete(); + } else if (movies.length == 1 && + movies.single.title == 'The Matrix' && + !listener2ReceivedFirstMovie.isCompleted) { + listener2ReceivedFirstMovie.complete(); + } else if (movies.length == 2 && + movies.any((movie) => movie.title == 'The Matrix') && + movies.any( + (movie) => movie.title == 'Raiders of the Lost Arc', + ) && + !listener2ReceivedSecondMovie.isCompleted) { + listener2ReceivedSecondMovie.complete(); + } + }); + + try { + // Wait for both listeners to be ready with initial emission + await Future.wait([ + listener1Ready.future, + listener2Ready.future, + ]).timeout(_listenTimeout); + + // Create first movie + await MoviesConnector.instance + .createMovie( + genre: 'Action', + title: 'The Matrix', + releaseYear: 1999, + ) + .rating(4.5) .ref() - .subscribe() - .listen((value) { - count1++; - final movies = value.data.movies; - if (movies.isEmpty && !listener1Ready.isCompleted) { - listener1Ready.complete(); - } else if (movies.length == 1 && - movies.single.title == 'The Matrix' && - !listener1ReceivedFirstMovie.isCompleted) { - listener1ReceivedFirstMovie.complete(); - } - }); - - final listener2 = MoviesConnector.instance - .listMovies() + .execute(); + + // Force a server result so the test does not depend on emulator push + // timing. This may duplicate an automatic WebSocket emission, so + // synchronize on result contents rather than event counts. + await MoviesConnector.instance.listMovies().ref().execute( + fetchPolicy: QueryFetchPolicy.serverOnly, + ); + + await Future.wait([ + listener1ReceivedFirstMovie.future, + listener2ReceivedFirstMovie.future, + ]).timeout(_listenTimeout); + + // Cancel listener1 + await listener1.cancel(); + final listener1CountAfterCancel = count1; + + // Create second movie + await MoviesConnector.instance + .createMovie( + genre: 'Adventure', + title: 'Raiders of the Lost Arc', + releaseYear: 1999, + ) + .rating(4.5) .ref() - .subscribe() - .listen((value) { - final movies = value.data.movies; - if (movies.isEmpty && !listener2Ready.isCompleted) { - listener2Ready.complete(); - } else if (movies.length == 1 && - movies.single.title == 'The Matrix' && - !listener2ReceivedFirstMovie.isCompleted) { - listener2ReceivedFirstMovie.complete(); - } else if (movies.length == 2 && - movies.any((movie) => movie.title == 'The Matrix') && - movies.any((movie) => movie.title == 'Raiders of the Lost Arc') && - !listener2ReceivedSecondMovie.isCompleted) { - listener2ReceivedSecondMovie.complete(); - } - }); - - try { - // Wait for both listeners to be ready with initial emission - await Future.wait([ - listener1Ready.future, - listener2Ready.future, - ]).timeout(_listenTimeout); - - // Create first movie - await MoviesConnector.instance - .createMovie( - genre: 'Action', - title: 'The Matrix', - releaseYear: 1999, - ) - .rating(4.5) - .ref() - .execute(); - - // Force a server result so the test does not depend on emulator push - // timing. This may duplicate an automatic WebSocket emission, so - // synchronize on result contents rather than event counts. - await MoviesConnector.instance - .listMovies() - .ref() - .execute(fetchPolicy: QueryFetchPolicy.serverOnly); - - await Future.wait([ - listener1ReceivedFirstMovie.future, - listener2ReceivedFirstMovie.future, - ]).timeout(_listenTimeout); - - // Cancel listener1 - await listener1.cancel(); - final listener1CountAfterCancel = count1; - - // Create second movie - await MoviesConnector.instance - .createMovie( - genre: 'Adventure', - title: 'Raiders of the Lost Arc', - releaseYear: 1999, - ) - .rating(4.5) - .ref() - .execute(); - - await MoviesConnector.instance - .listMovies() - .ref() - .execute(fetchPolicy: QueryFetchPolicy.serverOnly); - - await listener2ReceivedSecondMovie.future.timeout(_listenTimeout); - - expect(count1, equals(listener1CountAfterCancel), - reason: 'Canceled listener should not receive further updates'); - } finally { - await listener1.cancel(); - await listener2.cancel(); - } - }); - }, - skip: kIsWasm ? _wasmSkipReason : null, - ); + .execute(); + + await MoviesConnector.instance.listMovies().ref().execute( + fetchPolicy: QueryFetchPolicy.serverOnly, + ); + + await listener2ReceivedSecondMovie.future.timeout(_listenTimeout); + + expect( + count1, + equals(listener1CountAfterCancel), + reason: 'Canceled listener should not receive further updates', + ); + } finally { + await listener1.cancel(); + await listener2.cancel(); + } + }); + }, skip: kIsWasm ? _wasmSkipReason : null); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/integration_test/query_e2e.dart b/packages/firebase_data_connect/firebase_data_connect/example/integration_test/query_e2e.dart index 3843e29e7c80..70ed37b7eca0 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/integration_test/query_e2e.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/integration_test/query_e2e.dart @@ -19,120 +19,108 @@ Future deleteAllMovies() async { } Future> listMoviesFromServer() async { - final value = await MoviesConnector.instance - .listMovies() - .ref() - .execute(fetchPolicy: QueryFetchPolicy.serverOnly); + final value = await MoviesConnector.instance.listMovies().ref().execute( + fetchPolicy: QueryFetchPolicy.serverOnly, + ); return value.data.movies; } void runQueryTests() { - group( - '$FirebaseDataConnect.instance query', - () { - setUp(() async { - await deleteAllMovies(); - }); - - testWidgets('can query', (WidgetTester tester) async { - final movies = await listMoviesFromServer(); - expect(movies, isEmpty); - }); - - testWidgets('can add a movie', (WidgetTester tester) async { - MutationRef ref = MoviesConnector.instance - .createMovie( - genre: 'Action', - title: 'The Matrix', - releaseYear: 1999, - ) - .rating(4.5) - .ref(); - - await ref.execute(); - - final value = - await MoviesConnector.instance.listMovies().ref().execute(); - final result = value.data; - expect(result.movies.length, 1); - expect(result.movies[0].title, 'The Matrix'); - }); - - testWidgets('can add a director to a movie', (WidgetTester tester) async { - MutationRef ref = - MoviesConnector.instance.addPerson().name('Keanu Reeves').ref(); - - await ref.execute(); - - final personId = - (await MoviesConnector.instance.listPersons().ref().execute()) - .data - .people[0] - .id; - - final movies = await listMoviesFromServer(); - expect(movies, isEmpty); - - ref = MoviesConnector.instance - .createMovie( - genre: 'Action', - title: 'The Matrix', - releaseYear: 1999, - ) - .rating(4.5) - .ref(); - - await ref.execute(); - - final value2 = - await MoviesConnector.instance.listMovies().ref().execute(); - final result2 = value2.data; - expect(result2.movies.length, 1); - - final movieId = result2.movies[0].id; - - ref = MoviesConnector.instance - .addDirectorToMovie() - .movieId(movieId) - .personId(AddDirectorToMovieVariablesPersonId(id: personId)) - .ref(); - - await ref.execute(); - - final value3 = - await MoviesConnector.instance.listMovies().ref().execute(); - final result3 = value3.data; - expect(result3.movies.length, 1); - expect(result3.movies[0].directed_by.length, 1); - expect(result3.movies[0].directed_by[0].name, 'Keanu Reeves'); - }); - - testWidgets('can delete a movie', (WidgetTester tester) async { - MutationRef ref = MoviesConnector.instance - .createMovie( - genre: 'Action', - title: 'The Matrix', - releaseYear: 1999, - ) - .rating(4.5) - .ref(); - - await ref.execute(); - - final value = - await MoviesConnector.instance.listMovies().ref().execute(); - final result = value.data; - expect(result.movies.length, 1); - - final movieId = result.movies[0].id; - - ref = MoviesConnector.instance.deleteMovie(id: movieId).ref(); - - await ref.execute(); - - final movies = await listMoviesFromServer(); - expect(movies, isEmpty); - }); - }, - ); + group('$FirebaseDataConnect.instance query', () { + setUp(() async { + await deleteAllMovies(); + }); + + testWidgets('can query', (WidgetTester tester) async { + final movies = await listMoviesFromServer(); + expect(movies, isEmpty); + }); + + testWidgets('can add a movie', (WidgetTester tester) async { + MutationRef ref = MoviesConnector.instance + .createMovie(genre: 'Action', title: 'The Matrix', releaseYear: 1999) + .rating(4.5) + .ref(); + + await ref.execute(); + + final value = await MoviesConnector.instance.listMovies().ref().execute(); + final result = value.data; + expect(result.movies.length, 1); + expect(result.movies[0].title, 'The Matrix'); + }); + + testWidgets('can add a director to a movie', (WidgetTester tester) async { + MutationRef ref = MoviesConnector.instance + .addPerson() + .name('Keanu Reeves') + .ref(); + + await ref.execute(); + + final personId = + (await MoviesConnector.instance.listPersons().ref().execute()) + .data + .people[0] + .id; + + final movies = await listMoviesFromServer(); + expect(movies, isEmpty); + + ref = MoviesConnector.instance + .createMovie(genre: 'Action', title: 'The Matrix', releaseYear: 1999) + .rating(4.5) + .ref(); + + await ref.execute(); + + final value2 = await MoviesConnector.instance + .listMovies() + .ref() + .execute(); + final result2 = value2.data; + expect(result2.movies.length, 1); + + final movieId = result2.movies[0].id; + + ref = MoviesConnector.instance + .addDirectorToMovie() + .movieId(movieId) + .personId(AddDirectorToMovieVariablesPersonId(id: personId)) + .ref(); + + await ref.execute(); + + final value3 = await MoviesConnector.instance + .listMovies() + .ref() + .execute(); + final result3 = value3.data; + expect(result3.movies.length, 1); + expect(result3.movies[0].directed_by.length, 1); + expect(result3.movies[0].directed_by[0].name, 'Keanu Reeves'); + }); + + testWidgets('can delete a movie', (WidgetTester tester) async { + MutationRef ref = MoviesConnector.instance + .createMovie(genre: 'Action', title: 'The Matrix', releaseYear: 1999) + .rating(4.5) + .ref(); + + await ref.execute(); + + final value = await MoviesConnector.instance.listMovies().ref().execute(); + final result = value.data; + expect(result.movies.length, 1); + + final movieId = result.movies[0].id; + + ref = MoviesConnector.instance.deleteMovie(id: movieId).ref(); + + await ref.execute(); + + final movies = await listMoviesFromServer(); + expect(movies, isEmpty); + }); + }); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/integration_test/report_test_results.dart b/packages/firebase_data_connect/firebase_data_connect/example/integration_test/report_test_results.dart index f08ddf1af020..0e4467aeb106 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/integration_test/report_test_results.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/integration_test/report_test_results.dart @@ -26,8 +26,9 @@ void reportTestResultsToDriver(IntegrationTestWidgetsFlutterBinding binding) { for (final entry in binding.results.entries) if (entry.value is Failure) entry.key, ]; - bool didFail(String name) => failures - .any((failure) => name == failure || name.endsWith(' $failure')); + bool didFail(String name) => failures.any( + (failure) => name == failure || name.endsWith(' $failure'), + ); binding.reportData ??= {}; binding.reportData!['testResults'] = { diff --git a/packages/firebase_data_connect/firebase_data_connect/example/integration_test/websocket_e2e.dart b/packages/firebase_data_connect/firebase_data_connect/example/integration_test/websocket_e2e.dart index f195199ae882..48649b14be54 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/integration_test/websocket_e2e.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/integration_test/websocket_e2e.dart @@ -40,98 +40,93 @@ Future _waitForStreamEvent(Future future, String description) { } void runWebSocketTests() { - group( - '$FirebaseDataConnect WebSocketTransport', - () { - setUp(() async { - await deleteAllMovies(); - }); - - testWidgets('should support multiplexing multiple subscriptions', - (WidgetTester tester) async { - final Completer ready1 = Completer(); - final Completer ready2 = Completer(); - final Completer update1 = Completer(); - final Completer update2 = Completer(); - - int count1 = 0; - int count2 = 0; - - final sub1 = MoviesConnector.instance + group('$FirebaseDataConnect WebSocketTransport', () { + setUp(() async { + await deleteAllMovies(); + }); + + testWidgets('should support multiplexing multiple subscriptions', ( + WidgetTester tester, + ) async { + final Completer ready1 = Completer(); + final Completer ready2 = Completer(); + final Completer update1 = Completer(); + final Completer update2 = Completer(); + + int count1 = 0; + int count2 = 0; + + final sub1 = MoviesConnector.instance + .listMoviesByPartialTitle(input: 'Matrix') + .ref() + .subscribe() + .listen((value) { + if (count1 == 0) { + if (!ready1.isCompleted) ready1.complete(); + } else { + if (!update1.isCompleted) update1.complete(); + } + count1++; + }); + + final sub2 = MoviesConnector.instance + .listMoviesByPartialTitle(input: 'Titan') + .ref() + .subscribe() + .listen((value) { + if (count2 == 0) { + if (!ready2.isCompleted) ready2.complete(); + } else { + if (!update2.isCompleted) update2.complete(); + } + count2++; + }); + + try { + // Wait for both to be ready + await _waitForStreamEvent(ready1.future, 'Matrix subscription'); + await _waitForStreamEvent(ready2.future, 'Titan subscription'); + + // Create movies + await MoviesConnector.instance + .createMovie( + genre: 'Action', + title: 'The Matrix', + releaseYear: 1999, + ) + .rating(4.5) + .ref() + .execute(); + + await MoviesConnector.instance + .createMovie(genre: 'Drama', title: 'Titanic', releaseYear: 1997) + .rating(4.8) + .ref() + .execute(); + + // Explicitly resume each active query so this test does not depend on + // emulator-side push timing. + await MoviesConnector.instance .listMoviesByPartialTitle(input: 'Matrix') .ref() - .subscribe() - .listen((value) { - if (count1 == 0) { - if (!ready1.isCompleted) ready1.complete(); - } else { - if (!update1.isCompleted) update1.complete(); - } - count1++; - }); - - final sub2 = MoviesConnector.instance + .execute(fetchPolicy: QueryFetchPolicy.serverOnly); + await MoviesConnector.instance .listMoviesByPartialTitle(input: 'Titan') .ref() - .subscribe() - .listen((value) { - if (count2 == 0) { - if (!ready2.isCompleted) ready2.complete(); - } else { - if (!update2.isCompleted) update2.complete(); - } - count2++; - }); - - try { - // Wait for both to be ready - await _waitForStreamEvent(ready1.future, 'Matrix subscription'); - await _waitForStreamEvent(ready2.future, 'Titan subscription'); - - // Create movies - await MoviesConnector.instance - .createMovie( - genre: 'Action', - title: 'The Matrix', - releaseYear: 1999, - ) - .rating(4.5) - .ref() - .execute(); - - await MoviesConnector.instance - .createMovie( - genre: 'Drama', - title: 'Titanic', - releaseYear: 1997, - ) - .rating(4.8) - .ref() - .execute(); - - // Explicitly resume each active query so this test does not depend on - // emulator-side push timing. - await MoviesConnector.instance - .listMoviesByPartialTitle(input: 'Matrix') - .ref() - .execute(fetchPolicy: QueryFetchPolicy.serverOnly); - await MoviesConnector.instance - .listMoviesByPartialTitle(input: 'Titan') - .ref() - .execute(fetchPolicy: QueryFetchPolicy.serverOnly); - - // Wait for updates - await _waitForStreamEvent(update1.future, 'Matrix update'); - await _waitForStreamEvent(update2.future, 'Titan update'); - } finally { - await sub1.cancel(); - await sub2.cancel(); - } - }); - - testWidgets( - 'should support unary operations over WebSocket when connected', - (WidgetTester tester) async { + .execute(fetchPolicy: QueryFetchPolicy.serverOnly); + + // Wait for updates + await _waitForStreamEvent(update1.future, 'Matrix update'); + await _waitForStreamEvent(update2.future, 'Titan update'); + } finally { + await sub1.cancel(); + await sub2.cancel(); + } + }); + + testWidgets( + 'should support unary operations over WebSocket when connected', + (WidgetTester tester) async { final Completer isReady = Completer(); int count = 0; @@ -141,11 +136,11 @@ void runWebSocketTests() { .ref() .subscribe() .listen((value) { - if (count == 0) { - if (!isReady.isCompleted) isReady.complete(); - } - count++; - }); + if (count == 0) { + if (!isReady.isCompleted) isReady.complete(); + } + count++; + }); try { await _waitForStreamEvent(isReady.future, 'listMovies subscription'); @@ -166,68 +161,71 @@ void runWebSocketTests() { .execute(); // Verify update via query - final result2 = - await MoviesConnector.instance.listMovies().ref().execute(); + final result2 = await MoviesConnector.instance + .listMovies() + .ref() + .execute(); expect(result2.data.movies.length, 1); expect(result2.data.movies[0].title, 'Inception'); } finally { await sub.cancel(); } - }); - - testWidgets('should stop receiving events after cancel', - (WidgetTester tester) async { - final Completer isReady = Completer(); - final Completer receivedUpdate = Completer(); - int count = 0; - - final sub = MoviesConnector.instance - .listMovies() + }, + ); + + testWidgets('should stop receiving events after cancel', ( + WidgetTester tester, + ) async { + final Completer isReady = Completer(); + final Completer receivedUpdate = Completer(); + int count = 0; + + final sub = MoviesConnector.instance + .listMovies() + .ref() + .subscribe() + .listen((value) { + if (count == 0) { + if (!isReady.isCompleted) isReady.complete(); + } else { + if (!receivedUpdate.isCompleted) receivedUpdate.complete(); + } + count++; + }); + + try { + await _waitForStreamEvent(isReady.future, 'listMovies subscription'); + + // Cancel the subscription + await sub.cancel(); + + // Create a movie + await MoviesConnector.instance + .createMovie(genre: 'Action', title: 'Avatar', releaseYear: 2009) + .rating(4.7) .ref() - .subscribe() - .listen((value) { - if (count == 0) { - if (!isReady.isCompleted) isReady.complete(); - } else { - if (!receivedUpdate.isCompleted) receivedUpdate.complete(); - } - count++; - }); + .execute(); + // Wait a bit to ensure no event is received + bool received = true; try { - await _waitForStreamEvent(isReady.future, 'listMovies subscription'); - - // Cancel the subscription - await sub.cancel(); - - // Create a movie - await MoviesConnector.instance - .createMovie( - genre: 'Action', - title: 'Avatar', - releaseYear: 2009, - ) - .rating(4.7) - .ref() - .execute(); - - // Wait a bit to ensure no event is received - bool received = true; - try { - await receivedUpdate.future.timeout(const Duration(seconds: 2)); - } on TimeoutException { - received = false; - } - expect(received, isFalse, - reason: 'Should not receive events after cancel'); - } finally { - await sub.cancel(); + await receivedUpdate.future.timeout(const Duration(seconds: 2)); + } on TimeoutException { + received = false; } - }); - - testWidgets( - 'should disconnect the websocket channel when all subscriptions are closed', - (WidgetTester tester) async { + expect( + received, + isFalse, + reason: 'Should not receive events after cancel', + ); + } finally { + await sub.cancel(); + } + }); + + testWidgets( + 'should disconnect the websocket channel when all subscriptions are closed', + (WidgetTester tester) async { final Completer isReady = Completer(); int count = 0; @@ -236,11 +234,11 @@ void runWebSocketTests() { .ref() .subscribe() .listen((value) { - if (count == 0) { - if (!isReady.isCompleted) isReady.complete(); - } - count++; - }); + if (count == 0) { + if (!isReady.isCompleted) isReady.complete(); + } + count++; + }); try { await _waitForStreamEvent(isReady.future, 'listMovies subscription'); @@ -258,8 +256,7 @@ void runWebSocketTests() { } finally { await sub.cancel(); } - }); - }, - skip: kIsWasm ? _wasmSkipReason : null, - ); + }, + ); + }, skip: kIsWasm ? _wasmSkipReason : null); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/firebase_options.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/firebase_options.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_date_and_timestamp.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_date_and_timestamp.dart index 8f7680ea851e..e7339d3f5019 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_date_and_timestamp.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_date_and_timestamp.dart @@ -10,12 +10,12 @@ class AddDateAndTimestampVariablesBuilder { required this.date, required this.timestamp, }); - Deserializer dataDeserializer = - (dynamic json) => AddDateAndTimestampData.fromJson(jsonDecode(json)); + Deserializer dataDeserializer = (dynamic json) => + AddDateAndTimestampData.fromJson(jsonDecode(json)); Serializer varsSerializer = (AddDateAndTimestampVariables vars) => jsonEncode(vars.toJson()); Future> - execute() { + execute() { return ref().execute(); } @@ -25,7 +25,11 @@ class AddDateAndTimestampVariablesBuilder { timestamp: timestamp, ); return _dataConnect.mutation( - "addDateAndTimestamp", dataDeserializer, varsSerializer, vars); + "addDateAndTimestamp", + dataDeserializer, + varsSerializer, + vars, + ); } } @@ -33,7 +37,7 @@ class AddDateAndTimestampVariablesBuilder { class AddDateAndTimestampTimestampHolderInsert { final String id; AddDateAndTimestampTimestampHolderInsert.fromJson(dynamic json) - : id = nativeFromJson(json['id']); + : id = nativeFromJson(json['id']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -57,18 +61,17 @@ class AddDateAndTimestampTimestampHolderInsert { return json; } - AddDateAndTimestampTimestampHolderInsert({ - required this.id, - }); + AddDateAndTimestampTimestampHolderInsert({required this.id}); } @immutable class AddDateAndTimestampData { final AddDateAndTimestampTimestampHolderInsert timestampHolder_insert; AddDateAndTimestampData.fromJson(dynamic json) - : timestampHolder_insert = - AddDateAndTimestampTimestampHolderInsert.fromJson( - json['timestampHolder_insert']); + : timestampHolder_insert = + AddDateAndTimestampTimestampHolderInsert.fromJson( + json['timestampHolder_insert'], + ); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -91,9 +94,7 @@ class AddDateAndTimestampData { return json; } - AddDateAndTimestampData({ - required this.timestampHolder_insert, - }); + AddDateAndTimestampData({required this.timestampHolder_insert}); } @immutable @@ -101,10 +102,11 @@ class AddDateAndTimestampVariables { final DateTime date; final Timestamp timestamp; @Deprecated( - 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.', + ) AddDateAndTimestampVariables.fromJson(Map json) - : date = nativeFromJson(json['date']), - timestamp = Timestamp.fromJson(json['timestamp']); + : date = nativeFromJson(json['date']), + timestamp = Timestamp.fromJson(json['timestamp']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -129,8 +131,5 @@ class AddDateAndTimestampVariables { return json; } - AddDateAndTimestampVariables({ - required this.date, - required this.timestamp, - }); + AddDateAndTimestampVariables({required this.date, required this.timestamp}); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_director_to_movie.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_director_to_movie.dart index 235d4c31ae78..ea85e25de883 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_director_to_movie.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_director_to_movie.dart @@ -2,12 +2,15 @@ part of 'movies.dart'; class AddDirectorToMovieVariablesBuilder { Optional _personId = Optional.optional( - AddDirectorToMovieVariablesPersonId.fromJson, defaultSerializer); + AddDirectorToMovieVariablesPersonId.fromJson, + defaultSerializer, + ); Optional _movieId = Optional.optional(nativeFromJson, nativeToJson); final FirebaseDataConnect _dataConnect; AddDirectorToMovieVariablesBuilder personId( - AddDirectorToMovieVariablesPersonId? t) { + AddDirectorToMovieVariablesPersonId? t, + ) { _personId.value = t; return this; } @@ -17,15 +20,13 @@ class AddDirectorToMovieVariablesBuilder { return this; } - AddDirectorToMovieVariablesBuilder( - this._dataConnect, - ); - Deserializer dataDeserializer = - (dynamic json) => AddDirectorToMovieData.fromJson(jsonDecode(json)); + AddDirectorToMovieVariablesBuilder(this._dataConnect); + Deserializer dataDeserializer = (dynamic json) => + AddDirectorToMovieData.fromJson(jsonDecode(json)); Serializer varsSerializer = (AddDirectorToMovieVariables vars) => jsonEncode(vars.toJson()); Future> - execute() { + execute() { return ref().execute(); } @@ -35,7 +36,11 @@ class AddDirectorToMovieVariablesBuilder { movieId: _movieId, ); return _dataConnect.mutation( - "addDirectorToMovie", dataDeserializer, varsSerializer, vars); + "addDirectorToMovie", + dataDeserializer, + varsSerializer, + vars, + ); } } @@ -44,8 +49,8 @@ class AddDirectorToMovieDirectedByInsert { final String directedbyId; final String movieId; AddDirectorToMovieDirectedByInsert.fromJson(dynamic json) - : directedbyId = nativeFromJson(json['directedbyId']), - movieId = nativeFromJson(json['movieId']); + : directedbyId = nativeFromJson(json['directedbyId']), + movieId = nativeFromJson(json['movieId']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -81,8 +86,9 @@ class AddDirectorToMovieDirectedByInsert { class AddDirectorToMovieData { final AddDirectorToMovieDirectedByInsert directedBy_insert; AddDirectorToMovieData.fromJson(dynamic json) - : directedBy_insert = AddDirectorToMovieDirectedByInsert.fromJson( - json['directedBy_insert']); + : directedBy_insert = AddDirectorToMovieDirectedByInsert.fromJson( + json['directedBy_insert'], + ); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -105,16 +111,14 @@ class AddDirectorToMovieData { return json; } - AddDirectorToMovieData({ - required this.directedBy_insert, - }); + AddDirectorToMovieData({required this.directedBy_insert}); } @immutable class AddDirectorToMovieVariablesPersonId { final String id; AddDirectorToMovieVariablesPersonId.fromJson(dynamic json) - : id = nativeFromJson(json['id']); + : id = nativeFromJson(json['id']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -138,9 +142,7 @@ class AddDirectorToMovieVariablesPersonId { return json; } - AddDirectorToMovieVariablesPersonId({ - required this.id, - }); + AddDirectorToMovieVariablesPersonId({required this.id}); } @immutable @@ -148,10 +150,13 @@ class AddDirectorToMovieVariables { late final Optional personId; late final Optional movieId; @Deprecated( - 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.', + ) AddDirectorToMovieVariables.fromJson(Map json) { personId = Optional.optional( - AddDirectorToMovieVariablesPersonId.fromJson, defaultSerializer); + AddDirectorToMovieVariablesPersonId.fromJson, + defaultSerializer, + ); personId.value = json['personId'] == null ? null : AddDirectorToMovieVariablesPersonId.fromJson(json['personId']); @@ -189,8 +194,5 @@ class AddDirectorToMovieVariables { return json; } - AddDirectorToMovieVariables({ - required this.personId, - required this.movieId, - }); + AddDirectorToMovieVariables({required this.personId, required this.movieId}); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_person.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_person.dart index 359cfb32768c..8dd199c68e28 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_person.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_person.dart @@ -9,23 +9,23 @@ class AddPersonVariablesBuilder { return this; } - AddPersonVariablesBuilder( - this._dataConnect, - ); - Deserializer dataDeserializer = - (dynamic json) => AddPersonData.fromJson(jsonDecode(json)); - Serializer varsSerializer = - (AddPersonVariables vars) => jsonEncode(vars.toJson()); + AddPersonVariablesBuilder(this._dataConnect); + Deserializer dataDeserializer = (dynamic json) => + AddPersonData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (AddPersonVariables vars) => + jsonEncode(vars.toJson()); Future> execute() { return ref().execute(); } MutationRef ref() { - AddPersonVariables vars = AddPersonVariables( - name: _name, - ); + AddPersonVariables vars = AddPersonVariables(name: _name); return _dataConnect.mutation( - "addPerson", dataDeserializer, varsSerializer, vars); + "addPerson", + dataDeserializer, + varsSerializer, + vars, + ); } } @@ -33,7 +33,7 @@ class AddPersonVariablesBuilder { class AddPersonPersonInsert { final String id; AddPersonPersonInsert.fromJson(dynamic json) - : id = nativeFromJson(json['id']); + : id = nativeFromJson(json['id']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -56,16 +56,14 @@ class AddPersonPersonInsert { return json; } - AddPersonPersonInsert({ - required this.id, - }); + AddPersonPersonInsert({required this.id}); } @immutable class AddPersonData { final AddPersonPersonInsert person_insert; AddPersonData.fromJson(dynamic json) - : person_insert = AddPersonPersonInsert.fromJson(json['person_insert']); + : person_insert = AddPersonPersonInsert.fromJson(json['person_insert']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -88,20 +86,20 @@ class AddPersonData { return json; } - AddPersonData({ - required this.person_insert, - }); + AddPersonData({required this.person_insert}); } @immutable class AddPersonVariables { late final Optional name; @Deprecated( - 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.', + ) AddPersonVariables.fromJson(Map json) { name = Optional.optional(nativeFromJson, nativeToJson); - name.value = - json['name'] == null ? null : nativeFromJson(json['name']); + name.value = json['name'] == null + ? null + : nativeFromJson(json['name']); } @override bool operator ==(Object other) { @@ -127,7 +125,5 @@ class AddPersonVariables { return json; } - AddPersonVariables({ - required this.name, - }); + AddPersonVariables({required this.name}); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_timestamp.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_timestamp.dart index 19ce28607185..035a24c87261 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_timestamp.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_timestamp.dart @@ -4,12 +4,9 @@ class AddTimestampVariablesBuilder { Timestamp timestamp; final FirebaseDataConnect _dataConnect; - AddTimestampVariablesBuilder( - this._dataConnect, { - required this.timestamp, - }); - Deserializer dataDeserializer = - (dynamic json) => AddTimestampData.fromJson(jsonDecode(json)); + AddTimestampVariablesBuilder(this._dataConnect, {required this.timestamp}); + Deserializer dataDeserializer = (dynamic json) => + AddTimestampData.fromJson(jsonDecode(json)); Serializer varsSerializer = (AddTimestampVariables vars) => jsonEncode(vars.toJson()); Future> execute() { @@ -17,11 +14,13 @@ class AddTimestampVariablesBuilder { } MutationRef ref() { - AddTimestampVariables vars = AddTimestampVariables( - timestamp: timestamp, - ); + AddTimestampVariables vars = AddTimestampVariables(timestamp: timestamp); return _dataConnect.mutation( - "addTimestamp", dataDeserializer, varsSerializer, vars); + "addTimestamp", + dataDeserializer, + varsSerializer, + vars, + ); } } @@ -29,7 +28,7 @@ class AddTimestampVariablesBuilder { class AddTimestampTimestampHolderInsert { final String id; AddTimestampTimestampHolderInsert.fromJson(dynamic json) - : id = nativeFromJson(json['id']); + : id = nativeFromJson(json['id']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -53,17 +52,16 @@ class AddTimestampTimestampHolderInsert { return json; } - AddTimestampTimestampHolderInsert({ - required this.id, - }); + AddTimestampTimestampHolderInsert({required this.id}); } @immutable class AddTimestampData { final AddTimestampTimestampHolderInsert timestampHolder_insert; AddTimestampData.fromJson(dynamic json) - : timestampHolder_insert = AddTimestampTimestampHolderInsert.fromJson( - json['timestampHolder_insert']); + : timestampHolder_insert = AddTimestampTimestampHolderInsert.fromJson( + json['timestampHolder_insert'], + ); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -86,18 +84,17 @@ class AddTimestampData { return json; } - AddTimestampData({ - required this.timestampHolder_insert, - }); + AddTimestampData({required this.timestampHolder_insert}); } @immutable class AddTimestampVariables { final Timestamp timestamp; @Deprecated( - 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.', + ) AddTimestampVariables.fromJson(Map json) - : timestamp = Timestamp.fromJson(json['timestamp']); + : timestamp = Timestamp.fromJson(json['timestamp']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -120,7 +117,5 @@ class AddTimestampVariables { return json; } - AddTimestampVariables({ - required this.timestamp, - }); + AddTimestampVariables({required this.timestamp}); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/create_movie.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/create_movie.dart index 14ba5ce8a7a0..b35535fa6d01 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/create_movie.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/create_movie.dart @@ -5,8 +5,10 @@ class CreateMovieVariablesBuilder { int releaseYear; String genre; Optional _rating = Optional.optional(nativeFromJson, nativeToJson); - Optional _description = - Optional.optional(nativeFromJson, nativeToJson); + Optional _description = Optional.optional( + nativeFromJson, + nativeToJson, + ); final FirebaseDataConnect _dataConnect; CreateMovieVariablesBuilder rating(double? t) { @@ -25,8 +27,8 @@ class CreateMovieVariablesBuilder { required this.releaseYear, required this.genre, }); - Deserializer dataDeserializer = - (dynamic json) => CreateMovieData.fromJson(jsonDecode(json)); + Deserializer dataDeserializer = (dynamic json) => + CreateMovieData.fromJson(jsonDecode(json)); Serializer varsSerializer = (CreateMovieVariables vars) => jsonEncode(vars.toJson()); Future> execute() { @@ -42,7 +44,11 @@ class CreateMovieVariablesBuilder { description: _description, ); return _dataConnect.mutation( - "createMovie", dataDeserializer, varsSerializer, vars); + "createMovie", + dataDeserializer, + varsSerializer, + vars, + ); } } @@ -50,7 +56,7 @@ class CreateMovieVariablesBuilder { class CreateMovieMovieInsert { final String id; CreateMovieMovieInsert.fromJson(dynamic json) - : id = nativeFromJson(json['id']); + : id = nativeFromJson(json['id']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -73,16 +79,14 @@ class CreateMovieMovieInsert { return json; } - CreateMovieMovieInsert({ - required this.id, - }); + CreateMovieMovieInsert({required this.id}); } @immutable class CreateMovieData { final CreateMovieMovieInsert movie_insert; CreateMovieData.fromJson(dynamic json) - : movie_insert = CreateMovieMovieInsert.fromJson(json['movie_insert']); + : movie_insert = CreateMovieMovieInsert.fromJson(json['movie_insert']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -105,9 +109,7 @@ class CreateMovieData { return json; } - CreateMovieData({ - required this.movie_insert, - }); + CreateMovieData({required this.movie_insert}); } @immutable @@ -118,14 +120,16 @@ class CreateMovieVariables { late final Optional rating; late final Optional description; @Deprecated( - 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.', + ) CreateMovieVariables.fromJson(Map json) - : title = nativeFromJson(json['title']), - releaseYear = nativeFromJson(json['releaseYear']), - genre = nativeFromJson(json['genre']) { + : title = nativeFromJson(json['title']), + releaseYear = nativeFromJson(json['releaseYear']), + genre = nativeFromJson(json['genre']) { rating = Optional.optional(nativeFromJson, nativeToJson); - rating.value = - json['rating'] == null ? null : nativeFromJson(json['rating']); + rating.value = json['rating'] == null + ? null + : nativeFromJson(json['rating']); description = Optional.optional(nativeFromJson, nativeToJson); description.value = json['description'] == null @@ -151,12 +155,12 @@ class CreateMovieVariables { @override int get hashCode => Object.hashAll([ - title.hashCode, - releaseYear.hashCode, - genre.hashCode, - rating.hashCode, - description.hashCode - ]); + title.hashCode, + releaseYear.hashCode, + genre.hashCode, + rating.hashCode, + description.hashCode, + ]); Map toJson() { Map json = {}; diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/delete_all_movie_data.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/delete_all_movie_data.dart index 05d2a76d792b..718b8b429284 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/delete_all_movie_data.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/delete_all_movie_data.dart @@ -2,11 +2,9 @@ part of 'movies.dart'; class DeleteAllMovieDataVariablesBuilder { final FirebaseDataConnect _dataConnect; - DeleteAllMovieDataVariablesBuilder( - this._dataConnect, - ); - Deserializer dataDeserializer = - (dynamic json) => DeleteAllMovieDataData.fromJson(jsonDecode(json)); + DeleteAllMovieDataVariablesBuilder(this._dataConnect); + Deserializer dataDeserializer = (dynamic json) => + DeleteAllMovieDataData.fromJson(jsonDecode(json)); Future> execute() { return ref().execute(); @@ -14,7 +12,11 @@ class DeleteAllMovieDataVariablesBuilder { MutationRef ref() { return _dataConnect.mutation( - "deleteAllMovieData", dataDeserializer, emptySerializer, null); + "deleteAllMovieData", + dataDeserializer, + emptySerializer, + null, + ); } } @@ -24,10 +26,11 @@ class DeleteAllMovieDataData { final int movie_deleteMany; final int person_deleteMany; DeleteAllMovieDataData.fromJson(dynamic json) - : directedBy_deleteMany = - nativeFromJson(json['directedBy_deleteMany']), - movie_deleteMany = nativeFromJson(json['movie_deleteMany']), - person_deleteMany = nativeFromJson(json['person_deleteMany']); + : directedBy_deleteMany = nativeFromJson( + json['directedBy_deleteMany'], + ), + movie_deleteMany = nativeFromJson(json['movie_deleteMany']), + person_deleteMany = nativeFromJson(json['person_deleteMany']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -45,10 +48,10 @@ class DeleteAllMovieDataData { @override int get hashCode => Object.hashAll([ - directedBy_deleteMany.hashCode, - movie_deleteMany.hashCode, - person_deleteMany.hashCode - ]); + directedBy_deleteMany.hashCode, + movie_deleteMany.hashCode, + person_deleteMany.hashCode, + ]); Map toJson() { Map json = {}; diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/delete_movie.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/delete_movie.dart index 9050d5c5d707..744b6f8009d6 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/delete_movie.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/delete_movie.dart @@ -4,12 +4,9 @@ class DeleteMovieVariablesBuilder { String id; final FirebaseDataConnect _dataConnect; - DeleteMovieVariablesBuilder( - this._dataConnect, { - required this.id, - }); - Deserializer dataDeserializer = - (dynamic json) => DeleteMovieData.fromJson(jsonDecode(json)); + DeleteMovieVariablesBuilder(this._dataConnect, {required this.id}); + Deserializer dataDeserializer = (dynamic json) => + DeleteMovieData.fromJson(jsonDecode(json)); Serializer varsSerializer = (DeleteMovieVariables vars) => jsonEncode(vars.toJson()); Future> execute() { @@ -17,11 +14,13 @@ class DeleteMovieVariablesBuilder { } MutationRef ref() { - DeleteMovieVariables vars = DeleteMovieVariables( - id: id, - ); + DeleteMovieVariables vars = DeleteMovieVariables(id: id); return _dataConnect.mutation( - "deleteMovie", dataDeserializer, varsSerializer, vars); + "deleteMovie", + dataDeserializer, + varsSerializer, + vars, + ); } } @@ -29,7 +28,7 @@ class DeleteMovieVariablesBuilder { class DeleteMovieMovieDelete { final String id; DeleteMovieMovieDelete.fromJson(dynamic json) - : id = nativeFromJson(json['id']); + : id = nativeFromJson(json['id']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -52,18 +51,16 @@ class DeleteMovieMovieDelete { return json; } - DeleteMovieMovieDelete({ - required this.id, - }); + DeleteMovieMovieDelete({required this.id}); } @immutable class DeleteMovieData { final DeleteMovieMovieDelete? movie_delete; DeleteMovieData.fromJson(dynamic json) - : movie_delete = json['movie_delete'] == null - ? null - : DeleteMovieMovieDelete.fromJson(json['movie_delete']); + : movie_delete = json['movie_delete'] == null + ? null + : DeleteMovieMovieDelete.fromJson(json['movie_delete']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -88,18 +85,17 @@ class DeleteMovieData { return json; } - DeleteMovieData({ - this.movie_delete, - }); + DeleteMovieData({this.movie_delete}); } @immutable class DeleteMovieVariables { final String id; @Deprecated( - 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.', + ) DeleteMovieVariables.fromJson(Map json) - : id = nativeFromJson(json['id']); + : id = nativeFromJson(json['id']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -122,7 +118,5 @@ class DeleteMovieVariables { return json; } - DeleteMovieVariables({ - required this.id, - }); + DeleteMovieVariables({required this.id}); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/get_movie.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/get_movie.dart index 4fe64439c88a..f1ac9402dd76 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/get_movie.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/get_movie.dart @@ -4,24 +4,23 @@ class GetMovieVariablesBuilder { GetMovieVariablesKey key; final FirebaseDataConnect _dataConnect; - GetMovieVariablesBuilder( - this._dataConnect, { - required this.key, - }); - Deserializer dataDeserializer = - (dynamic json) => GetMovieData.fromJson(jsonDecode(json)); - Serializer varsSerializer = - (GetMovieVariables vars) => jsonEncode(vars.toJson()); + GetMovieVariablesBuilder(this._dataConnect, {required this.key}); + Deserializer dataDeserializer = (dynamic json) => + GetMovieData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (GetMovieVariables vars) => + jsonEncode(vars.toJson()); Future> execute() { return ref().execute(); } QueryRef ref() { - GetMovieVariables vars = GetMovieVariables( - key: key, - ); + GetMovieVariables vars = GetMovieVariables(key: key); return _dataConnect.query( - "GetMovie", dataDeserializer, varsSerializer, vars); + "GetMovie", + dataDeserializer, + varsSerializer, + vars, + ); } } @@ -30,8 +29,8 @@ class GetMovieMovie { final String id; final String title; GetMovieMovie.fromJson(dynamic json) - : id = nativeFromJson(json['id']), - title = nativeFromJson(json['title']); + : id = nativeFromJson(json['id']), + title = nativeFromJson(json['title']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -55,19 +54,16 @@ class GetMovieMovie { return json; } - GetMovieMovie({ - required this.id, - required this.title, - }); + GetMovieMovie({required this.id, required this.title}); } @immutable class GetMovieData { final GetMovieMovie? movie; GetMovieData.fromJson(dynamic json) - : movie = json['movie'] == null - ? null - : GetMovieMovie.fromJson(json['movie']); + : movie = json['movie'] == null + ? null + : GetMovieMovie.fromJson(json['movie']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -92,16 +88,14 @@ class GetMovieData { return json; } - GetMovieData({ - this.movie, - }); + GetMovieData({this.movie}); } @immutable class GetMovieVariablesKey { final String id; GetMovieVariablesKey.fromJson(dynamic json) - : id = nativeFromJson(json['id']); + : id = nativeFromJson(json['id']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -124,18 +118,17 @@ class GetMovieVariablesKey { return json; } - GetMovieVariablesKey({ - required this.id, - }); + GetMovieVariablesKey({required this.id}); } @immutable class GetMovieVariables { final GetMovieVariablesKey key; @Deprecated( - 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.', + ) GetMovieVariables.fromJson(Map json) - : key = GetMovieVariablesKey.fromJson(json['key']); + : key = GetMovieVariablesKey.fromJson(json['key']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -158,7 +151,5 @@ class GetMovieVariables { return json; } - GetMovieVariables({ - required this.key, - }); + GetMovieVariables({required this.key}); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_movies.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_movies.dart index 7b9faaeb08dd..ccb772aee936 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_movies.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_movies.dart @@ -2,11 +2,9 @@ part of 'movies.dart'; class ListMoviesVariablesBuilder { final FirebaseDataConnect _dataConnect; - ListMoviesVariablesBuilder( - this._dataConnect, - ); - Deserializer dataDeserializer = - (dynamic json) => ListMoviesData.fromJson(jsonDecode(json)); + ListMoviesVariablesBuilder(this._dataConnect); + Deserializer dataDeserializer = (dynamic json) => + ListMoviesData.fromJson(jsonDecode(json)); Future> execute() { return ref().execute(); @@ -14,7 +12,11 @@ class ListMoviesVariablesBuilder { QueryRef ref() { return _dataConnect.query( - "ListMovies", dataDeserializer, emptySerializer, null); + "ListMovies", + dataDeserializer, + emptySerializer, + null, + ); } } @@ -25,14 +27,14 @@ class ListMoviesMovies { final List directed_by; final double? rating; ListMoviesMovies.fromJson(dynamic json) - : id = nativeFromJson(json['id']), - title = nativeFromJson(json['title']), - directed_by = (json['directed_by'] as List) - .map((e) => ListMoviesMoviesDirectedBy.fromJson(e)) - .toList(), - rating = json['rating'] == null - ? null - : nativeFromJson(json['rating']); + : id = nativeFromJson(json['id']), + title = nativeFromJson(json['title']), + directed_by = (json['directed_by'] as List) + .map((e) => ListMoviesMoviesDirectedBy.fromJson(e)) + .toList(), + rating = json['rating'] == null + ? null + : nativeFromJson(json['rating']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -50,8 +52,12 @@ class ListMoviesMovies { } @override - int get hashCode => Object.hashAll( - [id.hashCode, title.hashCode, directed_by.hashCode, rating.hashCode]); + int get hashCode => Object.hashAll([ + id.hashCode, + title.hashCode, + directed_by.hashCode, + rating.hashCode, + ]); Map toJson() { Map json = {}; @@ -76,7 +82,7 @@ class ListMoviesMovies { class ListMoviesMoviesDirectedBy { final String name; ListMoviesMoviesDirectedBy.fromJson(dynamic json) - : name = nativeFromJson(json['name']); + : name = nativeFromJson(json['name']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -100,18 +106,16 @@ class ListMoviesMoviesDirectedBy { return json; } - ListMoviesMoviesDirectedBy({ - required this.name, - }); + ListMoviesMoviesDirectedBy({required this.name}); } @immutable class ListMoviesData { final List movies; ListMoviesData.fromJson(dynamic json) - : movies = (json['movies'] as List) - .map((e) => ListMoviesMovies.fromJson(e)) - .toList(); + : movies = (json['movies'] as List) + .map((e) => ListMoviesMovies.fromJson(e)) + .toList(); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -134,7 +138,5 @@ class ListMoviesData { return json; } - ListMoviesData({ - required this.movies, - }); + ListMoviesData({required this.movies}); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_movies_by_partial_title.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_movies_by_partial_title.dart index bc895bf95238..07f15f21679e 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_movies_by_partial_title.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_movies_by_partial_title.dart @@ -13,18 +13,23 @@ class ListMoviesByPartialTitleVariablesBuilder { Serializer varsSerializer = (ListMoviesByPartialTitleVariables vars) => jsonEncode(vars.toJson()); Future< - QueryResult> execute() { + QueryResult + > + execute() { return ref().execute(); } QueryRef - ref() { + ref() { ListMoviesByPartialTitleVariables vars = ListMoviesByPartialTitleVariables( input: input, ); return _dataConnect.query( - "ListMoviesByPartialTitle", dataDeserializer, varsSerializer, vars); + "ListMoviesByPartialTitle", + dataDeserializer, + varsSerializer, + vars, + ); } } @@ -35,12 +40,12 @@ class ListMoviesByPartialTitleMovies { final String genre; final double? rating; ListMoviesByPartialTitleMovies.fromJson(dynamic json) - : id = nativeFromJson(json['id']), - title = nativeFromJson(json['title']), - genre = nativeFromJson(json['genre']), - rating = json['rating'] == null - ? null - : nativeFromJson(json['rating']); + : id = nativeFromJson(json['id']), + title = nativeFromJson(json['title']), + genre = nativeFromJson(json['genre']), + rating = json['rating'] == null + ? null + : nativeFromJson(json['rating']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -59,8 +64,12 @@ class ListMoviesByPartialTitleMovies { } @override - int get hashCode => Object.hashAll( - [id.hashCode, title.hashCode, genre.hashCode, rating.hashCode]); + int get hashCode => Object.hashAll([ + id.hashCode, + title.hashCode, + genre.hashCode, + rating.hashCode, + ]); Map toJson() { Map json = {}; @@ -85,9 +94,9 @@ class ListMoviesByPartialTitleMovies { class ListMoviesByPartialTitleData { final List movies; ListMoviesByPartialTitleData.fromJson(dynamic json) - : movies = (json['movies'] as List) - .map((e) => ListMoviesByPartialTitleMovies.fromJson(e)) - .toList(); + : movies = (json['movies'] as List) + .map((e) => ListMoviesByPartialTitleMovies.fromJson(e)) + .toList(); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -111,18 +120,17 @@ class ListMoviesByPartialTitleData { return json; } - ListMoviesByPartialTitleData({ - required this.movies, - }); + ListMoviesByPartialTitleData({required this.movies}); } @immutable class ListMoviesByPartialTitleVariables { final String input; @Deprecated( - 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.', + ) ListMoviesByPartialTitleVariables.fromJson(Map json) - : input = nativeFromJson(json['input']); + : input = nativeFromJson(json['input']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -146,7 +154,5 @@ class ListMoviesByPartialTitleVariables { return json; } - ListMoviesByPartialTitleVariables({ - required this.input, - }); + ListMoviesByPartialTitleVariables({required this.input}); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_persons.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_persons.dart index a8629c79585a..531587142616 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_persons.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_persons.dart @@ -2,11 +2,9 @@ part of 'movies.dart'; class ListPersonsVariablesBuilder { final FirebaseDataConnect _dataConnect; - ListPersonsVariablesBuilder( - this._dataConnect, - ); - Deserializer dataDeserializer = - (dynamic json) => ListPersonsData.fromJson(jsonDecode(json)); + ListPersonsVariablesBuilder(this._dataConnect); + Deserializer dataDeserializer = (dynamic json) => + ListPersonsData.fromJson(jsonDecode(json)); Future> execute() { return ref().execute(); @@ -14,7 +12,11 @@ class ListPersonsVariablesBuilder { QueryRef ref() { return _dataConnect.query( - "ListPersons", dataDeserializer, emptySerializer, null); + "ListPersons", + dataDeserializer, + emptySerializer, + null, + ); } } @@ -23,8 +25,8 @@ class ListPersonsPeople { final String id; final String name; ListPersonsPeople.fromJson(dynamic json) - : id = nativeFromJson(json['id']), - name = nativeFromJson(json['name']); + : id = nativeFromJson(json['id']), + name = nativeFromJson(json['name']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -48,19 +50,16 @@ class ListPersonsPeople { return json; } - ListPersonsPeople({ - required this.id, - required this.name, - }); + ListPersonsPeople({required this.id, required this.name}); } @immutable class ListPersonsData { final List people; ListPersonsData.fromJson(dynamic json) - : people = (json['people'] as List) - .map((e) => ListPersonsPeople.fromJson(e)) - .toList(); + : people = (json['people'] as List) + .map((e) => ListPersonsPeople.fromJson(e)) + .toList(); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -83,7 +82,5 @@ class ListPersonsData { return json; } - ListPersonsData({ - required this.people, - }); + ListPersonsData({required this.people}); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_thing.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_thing.dart index 3f63233fae95..9da768b81e21 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_thing.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_thing.dart @@ -1,8 +1,10 @@ part of 'movies.dart'; class ListThingVariablesBuilder { - Optional _data = - Optional.optional(AnyValue.fromJson, defaultSerializer); + Optional _data = Optional.optional( + AnyValue.fromJson, + defaultSerializer, + ); final FirebaseDataConnect _dataConnect; ListThingVariablesBuilder data(AnyValue? t) { @@ -10,23 +12,23 @@ class ListThingVariablesBuilder { return this; } - ListThingVariablesBuilder( - this._dataConnect, - ); - Deserializer dataDeserializer = - (dynamic json) => ListThingData.fromJson(jsonDecode(json)); - Serializer varsSerializer = - (ListThingVariables vars) => jsonEncode(vars.toJson()); + ListThingVariablesBuilder(this._dataConnect); + Deserializer dataDeserializer = (dynamic json) => + ListThingData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (ListThingVariables vars) => + jsonEncode(vars.toJson()); Future> execute() { return ref().execute(); } QueryRef ref() { - ListThingVariables vars = ListThingVariables( - data: _data, - ); + ListThingVariables vars = ListThingVariables(data: _data); return _dataConnect.query( - "ListThing", dataDeserializer, varsSerializer, vars); + "ListThing", + dataDeserializer, + varsSerializer, + vars, + ); } } @@ -34,7 +36,7 @@ class ListThingVariablesBuilder { class ListThingThings { final AnyValue title; ListThingThings.fromJson(dynamic json) - : title = AnyValue.fromJson(json['title']); + : title = AnyValue.fromJson(json['title']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -57,18 +59,16 @@ class ListThingThings { return json; } - ListThingThings({ - required this.title, - }); + ListThingThings({required this.title}); } @immutable class ListThingData { final List things; ListThingData.fromJson(dynamic json) - : things = (json['things'] as List) - .map((e) => ListThingThings.fromJson(e)) - .toList(); + : things = (json['things'] as List) + .map((e) => ListThingThings.fromJson(e)) + .toList(); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -91,16 +91,15 @@ class ListThingData { return json; } - ListThingData({ - required this.things, - }); + ListThingData({required this.things}); } @immutable class ListThingVariables { late final Optional data; @Deprecated( - 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.', + ) ListThingVariables.fromJson(Map json) { data = Optional.optional(AnyValue.fromJson, defaultSerializer); data.value = json['data'] == null ? null : AnyValue.fromJson(json['data']); @@ -129,7 +128,5 @@ class ListThingVariables { return json; } - ListThingVariables({ - required this.data, - }); + ListThingVariables({required this.data}); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_timestamps.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_timestamps.dart index f2b6b64ade80..ad706a7505f3 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_timestamps.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_timestamps.dart @@ -2,11 +2,9 @@ part of 'movies.dart'; class ListTimestampsVariablesBuilder { final FirebaseDataConnect _dataConnect; - ListTimestampsVariablesBuilder( - this._dataConnect, - ); - Deserializer dataDeserializer = - (dynamic json) => ListTimestampsData.fromJson(jsonDecode(json)); + ListTimestampsVariablesBuilder(this._dataConnect); + Deserializer dataDeserializer = (dynamic json) => + ListTimestampsData.fromJson(jsonDecode(json)); Future> execute() { return ref().execute(); @@ -14,7 +12,11 @@ class ListTimestampsVariablesBuilder { QueryRef ref() { return _dataConnect.query( - "ListTimestamps", dataDeserializer, emptySerializer, null); + "ListTimestamps", + dataDeserializer, + emptySerializer, + null, + ); } } @@ -23,10 +25,10 @@ class ListTimestampsTimestampHolders { final Timestamp timestamp; final DateTime? date; ListTimestampsTimestampHolders.fromJson(dynamic json) - : timestamp = Timestamp.fromJson(json['timestamp']), - date = json['date'] == null - ? null - : nativeFromJson(json['date']); + : timestamp = Timestamp.fromJson(json['timestamp']), + date = json['date'] == null + ? null + : nativeFromJson(json['date']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -53,19 +55,16 @@ class ListTimestampsTimestampHolders { return json; } - ListTimestampsTimestampHolders({ - required this.timestamp, - this.date, - }); + ListTimestampsTimestampHolders({required this.timestamp, this.date}); } @immutable class ListTimestampsData { final List timestampHolders; ListTimestampsData.fromJson(dynamic json) - : timestampHolders = (json['timestampHolders'] as List) - .map((e) => ListTimestampsTimestampHolders.fromJson(e)) - .toList(); + : timestampHolders = (json['timestampHolders'] as List) + .map((e) => ListTimestampsTimestampHolders.fromJson(e)) + .toList(); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -88,7 +87,5 @@ class ListTimestampsData { return json; } - ListTimestampsData({ - required this.timestampHolders, - }); + ListTimestampsData({required this.timestampHolders}); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/movies.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/movies.dart index a6ca68e5e0f3..b3b84fb3cd09 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/movies.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/movies.dart @@ -38,24 +38,15 @@ part 'list_timestamps.dart'; class MoviesConnector { AddPersonVariablesBuilder addPerson() { - return AddPersonVariablesBuilder( - dataConnect, - ); + return AddPersonVariablesBuilder(dataConnect); } AddDirectorToMovieVariablesBuilder addDirectorToMovie() { - return AddDirectorToMovieVariablesBuilder( - dataConnect, - ); + return AddDirectorToMovieVariablesBuilder(dataConnect); } - AddTimestampVariablesBuilder addTimestamp({ - required Timestamp timestamp, - }) { - return AddTimestampVariablesBuilder( - dataConnect, - timestamp: timestamp, - ); + AddTimestampVariablesBuilder addTimestamp({required Timestamp timestamp}) { + return AddTimestampVariablesBuilder(dataConnect, timestamp: timestamp); } AddDateAndTimestampVariablesBuilder addDateAndTimestamp({ @@ -70,9 +61,7 @@ class MoviesConnector { } SeedMoviesVariablesBuilder seedMovies() { - return SeedMoviesVariablesBuilder( - dataConnect, - ); + return SeedMoviesVariablesBuilder(dataConnect); } CreateMovieVariablesBuilder createMovie({ @@ -88,73 +77,46 @@ class MoviesConnector { ); } - DeleteMovieVariablesBuilder deleteMovie({ - required String id, - }) { - return DeleteMovieVariablesBuilder( - dataConnect, - id: id, - ); + DeleteMovieVariablesBuilder deleteMovie({required String id}) { + return DeleteMovieVariablesBuilder(dataConnect, id: id); } DeleteAllMovieDataVariablesBuilder deleteAllMovieData() { - return DeleteAllMovieDataVariablesBuilder( - dataConnect, - ); + return DeleteAllMovieDataVariablesBuilder(dataConnect); } ThingVariablesBuilder thing() { - return ThingVariablesBuilder( - dataConnect, - ); + return ThingVariablesBuilder(dataConnect); } SeedDataVariablesBuilder seedData() { - return SeedDataVariablesBuilder( - dataConnect, - ); + return SeedDataVariablesBuilder(dataConnect); } ListMoviesVariablesBuilder listMovies() { - return ListMoviesVariablesBuilder( - dataConnect, - ); + return ListMoviesVariablesBuilder(dataConnect); } - GetMovieVariablesBuilder getMovie({ - required GetMovieVariablesKey key, - }) { - return GetMovieVariablesBuilder( - dataConnect, - key: key, - ); + GetMovieVariablesBuilder getMovie({required GetMovieVariablesKey key}) { + return GetMovieVariablesBuilder(dataConnect, key: key); } ListMoviesByPartialTitleVariablesBuilder listMoviesByPartialTitle({ required String input, }) { - return ListMoviesByPartialTitleVariablesBuilder( - dataConnect, - input: input, - ); + return ListMoviesByPartialTitleVariablesBuilder(dataConnect, input: input); } ListPersonsVariablesBuilder listPersons() { - return ListPersonsVariablesBuilder( - dataConnect, - ); + return ListPersonsVariablesBuilder(dataConnect); } ListThingVariablesBuilder listThing() { - return ListThingVariablesBuilder( - dataConnect, - ); + return ListThingVariablesBuilder(dataConnect); } ListTimestampsVariablesBuilder listTimestamps() { - return ListTimestampsVariablesBuilder( - dataConnect, - ); + return ListTimestampsVariablesBuilder(dataConnect); } static ConnectorConfig connectorConfig = ConnectorConfig( @@ -166,9 +128,11 @@ class MoviesConnector { MoviesConnector({required this.dataConnect}); static MoviesConnector get instance { return MoviesConnector( - dataConnect: FirebaseDataConnect.instanceFor( - connectorConfig: connectorConfig, - sdkType: CallerSDKType.generated)); + dataConnect: FirebaseDataConnect.instanceFor( + connectorConfig: connectorConfig, + sdkType: CallerSDKType.generated, + ), + ); } FirebaseDataConnect dataConnect; diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/seed_data.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/seed_data.dart index ac4ade4472e2..a70401c10b57 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/seed_data.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/seed_data.dart @@ -2,11 +2,9 @@ part of 'movies.dart'; class SeedDataVariablesBuilder { final FirebaseDataConnect _dataConnect; - SeedDataVariablesBuilder( - this._dataConnect, - ); - Deserializer dataDeserializer = - (dynamic json) => SeedDataData.fromJson(jsonDecode(json)); + SeedDataVariablesBuilder(this._dataConnect); + Deserializer dataDeserializer = (dynamic json) => + SeedDataData.fromJson(jsonDecode(json)); Future> execute() { return ref().execute(); @@ -14,7 +12,11 @@ class SeedDataVariablesBuilder { MutationRef ref() { return _dataConnect.mutation( - "seedData", dataDeserializer, emptySerializer, null); + "seedData", + dataDeserializer, + emptySerializer, + null, + ); } } @@ -22,7 +24,7 @@ class SeedDataVariablesBuilder { class SeedDataTheMatrix { final String id; SeedDataTheMatrix.fromJson(dynamic json) - : id = nativeFromJson(json['id']); + : id = nativeFromJson(json['id']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -45,16 +47,14 @@ class SeedDataTheMatrix { return json; } - SeedDataTheMatrix({ - required this.id, - }); + SeedDataTheMatrix({required this.id}); } @immutable class SeedDataData { final SeedDataTheMatrix the_matrix; SeedDataData.fromJson(dynamic json) - : the_matrix = SeedDataTheMatrix.fromJson(json['the_matrix']); + : the_matrix = SeedDataTheMatrix.fromJson(json['the_matrix']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -77,7 +77,5 @@ class SeedDataData { return json; } - SeedDataData({ - required this.the_matrix, - }); + SeedDataData({required this.the_matrix}); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/seed_movies.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/seed_movies.dart index 2805c05d308e..f129582af068 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/seed_movies.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/seed_movies.dart @@ -2,11 +2,9 @@ part of 'movies.dart'; class SeedMoviesVariablesBuilder { final FirebaseDataConnect _dataConnect; - SeedMoviesVariablesBuilder( - this._dataConnect, - ); - Deserializer dataDeserializer = - (dynamic json) => SeedMoviesData.fromJson(jsonDecode(json)); + SeedMoviesVariablesBuilder(this._dataConnect); + Deserializer dataDeserializer = (dynamic json) => + SeedMoviesData.fromJson(jsonDecode(json)); Future> execute() { return ref().execute(); @@ -14,7 +12,11 @@ class SeedMoviesVariablesBuilder { MutationRef ref() { return _dataConnect.mutation( - "seedMovies", dataDeserializer, emptySerializer, null); + "seedMovies", + dataDeserializer, + emptySerializer, + null, + ); } } @@ -22,7 +24,7 @@ class SeedMoviesVariablesBuilder { class SeedMoviesTheMatrix { final String id; SeedMoviesTheMatrix.fromJson(dynamic json) - : id = nativeFromJson(json['id']); + : id = nativeFromJson(json['id']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -45,16 +47,14 @@ class SeedMoviesTheMatrix { return json; } - SeedMoviesTheMatrix({ - required this.id, - }); + SeedMoviesTheMatrix({required this.id}); } @immutable class SeedMoviesJurassicPark { final String id; SeedMoviesJurassicPark.fromJson(dynamic json) - : id = nativeFromJson(json['id']); + : id = nativeFromJson(json['id']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -77,9 +77,7 @@ class SeedMoviesJurassicPark { return json; } - SeedMoviesJurassicPark({ - required this.id, - }); + SeedMoviesJurassicPark({required this.id}); } @immutable @@ -87,8 +85,8 @@ class SeedMoviesData { final SeedMoviesTheMatrix the_matrix; final SeedMoviesJurassicPark jurassic_park; SeedMoviesData.fromJson(dynamic json) - : the_matrix = SeedMoviesTheMatrix.fromJson(json['the_matrix']), - jurassic_park = SeedMoviesJurassicPark.fromJson(json['jurassic_park']); + : the_matrix = SeedMoviesTheMatrix.fromJson(json['the_matrix']), + jurassic_park = SeedMoviesJurassicPark.fromJson(json['jurassic_park']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -114,8 +112,5 @@ class SeedMoviesData { return json; } - SeedMoviesData({ - required this.the_matrix, - required this.jurassic_park, - }); + SeedMoviesData({required this.the_matrix, required this.jurassic_park}); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/thing.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/thing.dart index 167d997a25e5..651dfa60f0ee 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/thing.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/thing.dart @@ -1,8 +1,10 @@ part of 'movies.dart'; class ThingVariablesBuilder { - Optional _title = - Optional.optional(AnyValue.fromJson, defaultSerializer); + Optional _title = Optional.optional( + AnyValue.fromJson, + defaultSerializer, + ); final FirebaseDataConnect _dataConnect; ThingVariablesBuilder title(AnyValue t) { @@ -10,23 +12,23 @@ class ThingVariablesBuilder { return this; } - ThingVariablesBuilder( - this._dataConnect, - ); - Deserializer dataDeserializer = - (dynamic json) => ThingData.fromJson(jsonDecode(json)); - Serializer varsSerializer = - (ThingVariables vars) => jsonEncode(vars.toJson()); + ThingVariablesBuilder(this._dataConnect); + Deserializer dataDeserializer = (dynamic json) => + ThingData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (ThingVariables vars) => + jsonEncode(vars.toJson()); Future> execute() { return ref().execute(); } MutationRef ref() { - ThingVariables vars = ThingVariables( - title: _title, - ); + ThingVariables vars = ThingVariables(title: _title); return _dataConnect.mutation( - "thing", dataDeserializer, varsSerializer, vars); + "thing", + dataDeserializer, + varsSerializer, + vars, + ); } } @@ -56,9 +58,7 @@ class ThingAbc { return json; } - ThingAbc({ - required this.id, - }); + ThingAbc({required this.id}); } @immutable @@ -87,9 +87,7 @@ class ThingDef { return json; } - ThingDef({ - required this.id, - }); + ThingDef({required this.id}); } @immutable @@ -97,8 +95,8 @@ class ThingData { final ThingAbc abc; final ThingDef def; ThingData.fromJson(dynamic json) - : abc = ThingAbc.fromJson(json['abc']), - def = ThingDef.fromJson(json['def']); + : abc = ThingAbc.fromJson(json['abc']), + def = ThingDef.fromJson(json['def']); @override bool operator ==(Object other) { if (identical(this, other)) { @@ -122,21 +120,20 @@ class ThingData { return json; } - ThingData({ - required this.abc, - required this.def, - }); + ThingData({required this.abc, required this.def}); } @immutable class ThingVariables { late final Optional title; @Deprecated( - 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + 'fromJson is deprecated for Variable classes as they are no longer required for deserialization.', + ) ThingVariables.fromJson(Map json) { title = Optional.optional(AnyValue.fromJson, defaultSerializer); - title.value = - json['title'] == null ? null : AnyValue.fromJson(json['title']); + title.value = json['title'] == null + ? null + : AnyValue.fromJson(json['title']); } @override bool operator ==(Object other) { @@ -162,7 +159,5 @@ class ThingVariables { return json; } - ThingVariables({ - required this.title, - }); + ThingVariables({required this.title}); } diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/login.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/login.dart index ab3b51825827..6032e8e094a0 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/login.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/login.dart @@ -28,7 +28,9 @@ class Login extends StatefulWidget { class _LoginState extends State { Future signInWithGoogle() async { await FirebaseAuth.instance.createUserWithEmailAndPassword( - email: '${Random().nextInt(100000)}@mail.com', password: 'password'); + email: '${Random().nextInt(100000)}@mail.com', + password: 'password', + ); } void logIn() async { @@ -37,9 +39,8 @@ class _LoginState extends State { navigator.push( MaterialPageRoute( - builder: (context) => const MyHomePage( - title: "Data Connect Home Page", - )), + builder: (context) => const MyHomePage(title: "Data Connect Home Page"), + ), ); } @@ -55,15 +56,10 @@ class _LoginState extends State { height: 150.0, width: 190.0, padding: const EdgeInsets.only(top: 40), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(200), - ), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(200)), child: Padding( padding: const EdgeInsets.all(10), - child: TextButton( - onPressed: logIn, - child: const Text("Log in"), - ), + child: TextButton(onPressed: logIn, child: const Text("Log in")), ), ), ), diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/main.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/main.dart index 98f684749ffa..ecac0babc528 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/lib/main.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/main.dart @@ -52,12 +52,11 @@ void main() async { ); } if (configureEmulator) { - MoviesConnector.instance.dataConnect - .useDataConnectEmulator('127.0.0.1', 9399); - FirebaseAuth.instance.useAuthEmulator( - 'localhost', - 9099, + MoviesConnector.instance.dataConnect.useDataConnectEmulator( + '127.0.0.1', + 9399, ); + FirebaseAuth.instance.useAuthEmulator('localhost', 9099); } runApp(const MyApp()); @@ -90,9 +89,7 @@ class MyHomePage extends StatelessWidget { backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text(title), ), - body: const Center( - child: DataConnectWidget(), - ), + body: const Center(child: DataConnectWidget()), ); } } @@ -119,23 +116,29 @@ class _DataConnectWidgetState extends State { void initState() { super.initState(); - QueryRef ref = - MoviesConnector.instance.listMovies().ref(); + QueryRef ref = MoviesConnector.instance + .listMovies() + .ref(); - ref.subscribe().listen((event) { - setState(() { - _movies = event.data.movies; - }); - }).onError((e) { - _showError("Got an error: $e"); - }); + ref + .subscribe() + .listen((event) { + setState(() { + _movies = event.data.movies; + }); + }) + .onError((e) { + _showError("Got an error: $e"); + }); } @override Widget build(BuildContext context) { return Padding( - padding: const EdgeInsets.all(10.0), - child: Flex(direction: Axis.vertical, children: [ + padding: const EdgeInsets.all(10.0), + child: Flex( + direction: Axis.vertical, + children: [ Flexible( flex: 1, child: TextFormField( @@ -147,43 +150,44 @@ class _DataConnectWidgetState extends State { ), ), Flexible( - flex: 1, - child: TextFormField( - decoration: const InputDecoration( - border: UnderlineInputBorder(), - labelText: 'Genre', - ), - controller: _genreController, - )), + flex: 1, + child: TextFormField( + decoration: const InputDecoration( + border: UnderlineInputBorder(), + labelText: 'Genre', + ), + controller: _genreController, + ), + ), Flexible( - flex: 1, - child: RatingBar.builder( - initialRating: 3, - minRating: 1, - direction: Axis.horizontal, - allowHalfRating: true, - itemCount: 5, - itemPadding: const EdgeInsets.symmetric(horizontal: 4.0), - itemBuilder: (context, _) => const Icon( - Icons.star, - color: Colors.amber, - ), - onRatingUpdate: (rating) { - _rating = rating; - }, - )), + flex: 1, + child: RatingBar.builder( + initialRating: 3, + minRating: 1, + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemPadding: const EdgeInsets.symmetric(horizontal: 4.0), + itemBuilder: (context, _) => + const Icon(Icons.star, color: Colors.amber), + onRatingUpdate: (rating) { + _rating = rating; + }, + ), + ), Flexible( - flex: 1, - child: YearPicker( - firstDate: DateTime(1990), - lastDate: DateTime.now(), - selectedDate: _releaseYearDate, - onChanged: (value) { - setState(() { - _releaseYearDate = value; - }); - }, - )), + flex: 1, + child: YearPicker( + firstDate: DateTime(1990), + lastDate: DateTime.now(), + selectedDate: _releaseYearDate, + onChanged: (value) { + setState(() { + _releaseYearDate = value; + }); + }, + ), + ), TextButton( style: ButtonStyle( foregroundColor: WidgetStateProperty.all(Colors.blue), @@ -213,23 +217,19 @@ class _DataConnectWidgetState extends State { }, child: const Text('Add Movie'), ), - const Center( - child: Text( - "Movies", - style: TextStyle(fontSize: 35.0), - ), - ), + const Center(child: Text("Movies", style: TextStyle(fontSize: 35.0))), Expanded( - child: Column( - children: [ - Expanded( - child: RefreshIndicator( - onRefresh: () => triggerReload(), - child: ListView( + child: Column( + children: [ + Expanded( + child: RefreshIndicator( + onRefresh: () => triggerReload(), + child: ListView( scrollDirection: Axis.vertical, children: _movies - .map((movie) => Card( - child: Padding( + .map( + (movie) => Card( + child: Padding( padding: const EdgeInsets.all(10), child: Center( child: Text( @@ -239,13 +239,19 @@ class _DataConnectWidgetState extends State { ), ), ), - ))) - .toList()), + ), + ), + ) + .toList(), + ), + ), ), - ) - ], - )) - ])); + ], + ), + ), + ], + ), + ); } void _showError(String message) { @@ -254,9 +260,7 @@ class _DataConnectWidgetState extends State { builder: (context) { return AlertDialog( title: const Text('Something went wrong'), - content: SingleChildScrollView( - child: SelectableText(message), - ), + content: SingleChildScrollView(child: SelectableText(message)), actions: [ TextButton( onPressed: () { diff --git a/packages/firebase_data_connect/firebase_data_connect/example/pubspec.yaml b/packages/firebase_data_connect/firebase_data_connect/example/pubspec.yaml index b3cf0add18e1..9e658164af2e 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/pubspec.yaml +++ b/packages/firebase_data_connect/firebase_data_connect/example/pubspec.yaml @@ -7,8 +7,8 @@ version: 1.0.0+1 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: flutter: diff --git a/packages/firebase_data_connect/firebase_data_connect/example/test_driver/integration_test.dart b/packages/firebase_data_connect/firebase_data_connect/example/test_driver/integration_test.dart index 691723cbbfe1..9ccbcc26ab97 100644 --- a/packages/firebase_data_connect/firebase_data_connect/example/test_driver/integration_test.dart +++ b/packages/firebase_data_connect/firebase_data_connect/example/test_driver/integration_test.dart @@ -7,28 +7,32 @@ import 'dart:io'; import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver( - writeResponseOnFailure: true, - responseDataCallback: (Map? data) async { - final results = - (data?['testResults'] as Map?)?.cast() ?? - const {}; - var passed = 0; - var failed = 0; - for (final entry in results.entries) { - final ok = entry.value == 'success'; - ok ? passed++ : failed++; - // ignore: avoid_print - print('${ok ? '✅' : '❌'} ${entry.key}'); - } - // ignore: avoid_print - print('Web e2e summary: $passed passed, $failed failed, ' - '${results.length} total'); - if (results.isEmpty) { - // ignore: avoid_print - print('[E] No tests reported by the app - treating as ' - 'infrastructure failure.'); - exit(1); - } - await writeResponseData(data); - }, + writeResponseOnFailure: true, + responseDataCallback: (Map? data) async { + final results = + (data?['testResults'] as Map?)?.cast() ?? + const {}; + var passed = 0; + var failed = 0; + for (final entry in results.entries) { + final ok = entry.value == 'success'; + ok ? passed++ : failed++; + // ignore: avoid_print + print('${ok ? '✅' : '❌'} ${entry.key}'); + } + // ignore: avoid_print + print( + 'Web e2e summary: $passed passed, $failed failed, ' + '${results.length} total', ); + if (results.isEmpty) { + // ignore: avoid_print + print( + '[E] No tests reported by the app - treating as ' + 'infrastructure failure.', + ); + exit(1); + } + await writeResponseData(data); + }, +); diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/cache.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/cache.dart index 087d69744e9a..ee742f58f3a4 100644 --- a/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/cache.dart +++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/cache.dart @@ -95,24 +95,28 @@ class Cache { bool memory = _settings.storage == CacheStorage.memory; _localCacheProvider = cacheImplementation(identifier, memory); - _localProviderInitialization = - _localCacheProvider!.initialize().then((success) { - if (!success) { - _localInitFailed = true; - } - return success; - }).catchError((e) { - _localInitFailed = true; - return false; - }); + _localProviderInitialization = _localCacheProvider! + .initialize() + .then((success) { + if (!success) { + _localInitFailed = true; + } + return success; + }) + .catchError((e) { + _localInitFailed = true; + return false; + }); } void _startIsolate() async { _toIsolatePortCompleter = Completer(); _fromIsolatePort = ReceivePort(); try { - _isolate = - await Isolate.spawn(_cacheIsolateEntry, _fromIsolatePort!.sendPort); + _isolate = await Isolate.spawn( + _cacheIsolateEntry, + _fromIsolatePort!.sendPort, + ); _fromIsolatePort!.listen((message) { if (_toIsolatePort == null) { @@ -128,9 +132,10 @@ class Cache { }); } catch (e, stackTrace) { developer.log( - 'Failed to spawn background cache Isolate: $e. Falling back to local mode.', - error: e, - stackTrace: stackTrace); + 'Failed to spawn background cache Isolate: $e. Falling back to local mode.', + error: e, + stackTrace: stackTrace, + ); // Fallback to local mode on failure _isolateFallbackMode = true; _toIsolatePortCompleter!.completeError(e); @@ -170,7 +175,8 @@ class Cache { dbPath = appDir.path; } catch (e) { developer.log( - 'Failed to get application documents directory for background cache: $e'); + 'Failed to get application documents directory for background cache: $e', + ); } } @@ -193,7 +199,8 @@ class Cache { void _listenForAuthChanges() { if (dataConnect.auth == null) { developer.log( - 'Not listening for auth changes since no auth instance in data connect'); + 'Not listening for auth changes since no auth instance in data connect', + ); return; } @@ -223,8 +230,11 @@ class Cache { completer.complete(); } else { _lastInitFailed = true; - completer.completeError(StateError( - 'CacheProvider failed to initialize in background isolate.')); + completer.completeError( + StateError( + 'CacheProvider failed to initialize in background isolate.', + ), + ); } } } else if (op == 'updateResponse') { @@ -303,7 +313,9 @@ class Cache { /// Fetches a cached result. Future?> resultTree( - String queryId, bool allowStale) async { + String queryId, + bool allowStale, + ) async { if (kIsWeb || _isolateFallbackMode) { _initializeLocalProvider(); if (_localCacheProvider == null) { @@ -393,8 +405,11 @@ void _cacheIsolateEntry(SendPort mainSendPort) async { await provider.dispose(); } - cacheProvider = - cacheImplementation(identifier, isMemory, customDbPath: dbPath); + cacheProvider = cacheImplementation( + identifier, + isMemory, + customDbPath: dbPath, + ); providerInitialization = cacheProvider.initialize(); final success = await providerInitialization; @@ -530,22 +545,28 @@ Future> dehydrateAndUpdateCache({ ? ExtensionResponse.fromJson(extensions).flattenPathMetadata() : {}; - final dehydrationResult = - await processor.dehydrateResults(queryId, data, provider, paths); + final dehydrationResult = await processor.dehydrateResults( + queryId, + data, + provider, + paths, + ); EntityNode rootNode = dehydrationResult.dehydratedTree; - Map dehydratedMap = - rootNode.toJson(mode: EncodingMode.dehydrated); + Map dehydratedMap = rootNode.toJson( + mode: EncodingMode.dehydrated, + ); Duration ttl = extensions != null && extensions['ttl'] != null ? Duration(seconds: extensions['ttl'] as int) : maxAge; final resultTree = ResultTree( - data: dehydratedMap, - ttl: ttl, - cachedAt: DateTime.now(), - lastAccessed: DateTime.now()); + data: dehydratedMap, + ttl: ttl, + cachedAt: DateTime.now(), + lastAccessed: DateTime.now(), + ); provider.setResultTree(queryId, resultTree); @@ -575,8 +596,10 @@ Future?> fetchAndHydrateCache({ EntityNode rootNode = EntityNode.fromJson(resultTree.data, provider); - Map hydratedJson = - await processor.hydrateResults(rootNode, provider); + Map hydratedJson = await processor.hydrateResults( + rootNode, + provider, + ); return hydratedJson; } diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/cache_data_types.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/cache_data_types.dart index 9b991a946a79..0b071e54c3f1 100644 --- a/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/cache_data_types.dart +++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/cache_data_types.dart @@ -29,7 +29,7 @@ class DataConnectPath { final List components; DataConnectPath([List? components]) - : components = components ?? []; + : components = components ?? []; DataConnectPath appending(DataConnectPathSegment segment) { return DataConnectPath([...components, segment]); @@ -98,11 +98,14 @@ class ExtensionResponse { factory ExtensionResponse.fromJson(Map json) { return ExtensionResponse( - maxAge: - json['ttl'] != null ? Duration(seconds: json['ttl'] as int) : null, - dataConnect: (json['dataConnect'] as List?) - ?.map((e) => - PathMetadataResponse.fromJson(e as Map)) + maxAge: json['ttl'] != null + ? Duration(seconds: json['ttl'] as int) + : null, + dataConnect: + (json['dataConnect'] as List?) + ?.map( + (e) => PathMetadataResponse.fromJson(e as Map), + ) .toList() ?? [], ); @@ -113,15 +116,18 @@ class ExtensionResponse { for (final pmr in dataConnect) { if (pmr.entityId != null) { final pm = PathMetadata( - path: DataConnectPath(pmr.path), entityId: pmr.entityId); + path: DataConnectPath(pmr.path), + entityId: pmr.entityId, + ); result[pm.path] = pm; } if (pmr.entityIds != null) { for (var i = 0; i < pmr.entityIds!.length; i++) { final entityId = pmr.entityIds![i]; - final indexPath = DataConnectPath(pmr.path) - .appending(DataConnectListIndexPathSegment(i)); + final indexPath = DataConnectPath( + pmr.path, + ).appending(DataConnectListIndexPathSegment(i)); final pm = PathMetadata(path: indexPath, entityId: entityId); result[pm.path] = pm; } @@ -140,10 +146,7 @@ class CacheSettings { final Duration maxAge; // Internal const constructor - const CacheSettings._internal({ - required this.storage, - required this.maxAge, - }); + const CacheSettings._internal({required this.storage, required this.maxAge}); // Factory constructor to handle the logic factory CacheSettings({ @@ -189,25 +192,26 @@ class ResultTree { return DateTime.now().difference(cachedAt) > ttl; } - ResultTree( - {required this.data, - required this.ttl, - required this.cachedAt, - required this.lastAccessed}); + ResultTree({ + required this.data, + required this.ttl, + required this.cachedAt, + required this.lastAccessed, + }); factory ResultTree.fromJson(Map json) => ResultTree( - data: Map.from(json['data'] as Map), - ttl: Duration(microseconds: json['ttl'] as int), - cachedAt: DateTime.parse(json['cachedAt'] as String), - lastAccessed: DateTime.parse(json['lastAccessed'] as String), - ); + data: Map.from(json['data'] as Map), + ttl: Duration(microseconds: json['ttl'] as int), + cachedAt: DateTime.parse(json['cachedAt'] as String), + lastAccessed: DateTime.parse(json['lastAccessed'] as String), + ); Map toJson() => { - 'data': data, - 'ttl': ttl.inMicroseconds, - 'cachedAt': cachedAt.toIso8601String(), - 'lastAccessed': lastAccessed.toIso8601String(), - }; + 'data': data, + 'ttl': ttl.inMicroseconds, + 'cachedAt': cachedAt.toIso8601String(), + 'lastAccessed': lastAccessed.toIso8601String(), + }; factory ResultTree.fromRawJson(String source) => ResultTree.fromJson(json.decode(source) as Map); @@ -258,17 +262,17 @@ class EntityDataObject { String toRawJson() => json.encode(toJson()); Map toJson() => { - kGlobalIDKey: guid, - '_serverValues': _serverValues, - 'referencedFrom': referencedFrom.toList(), - }; + kGlobalIDKey: guid, + '_serverValues': _serverValues, + 'referencedFrom': referencedFrom.toList(), + }; factory EntityDataObject.fromJson(Map json) { - EntityDataObject edo = EntityDataObject( - guid: json[kGlobalIDKey] as String, - ); + EntityDataObject edo = EntityDataObject(guid: json[kGlobalIDKey] as String); edo.setServerValues( - Map.from(json['_serverValues'] as Map), null); + Map.from(json['_serverValues'] as Map), + null, + ); List? rf = json['referencedFrom']; if (rf != null) { @@ -296,14 +300,17 @@ class EntityNode { final Map>? nestedObjectLists; static const String listsKey = 'lists'; - EntityNode( - {this.entity, - this.scalarValues, - this.nestedObjects, - this.nestedObjectLists}); + EntityNode({ + this.entity, + this.scalarValues, + this.nestedObjects, + this.nestedObjectLists, + }); factory EntityNode.fromJson( - Map json, CacheProvider cacheProvider) { + Map json, + CacheProvider cacheProvider, + ) { EntityDataObject? entity; if (json[kGlobalIDKey] != null) { entity = cacheProvider.getEntityData(json[kGlobalIDKey]); @@ -341,10 +348,11 @@ class EntityNode { }); } return EntityNode( - entity: entity, - scalarValues: scalars, - nestedObjects: objects, - nestedObjectLists: objLists); + entity: entity, + scalarValues: scalars, + nestedObjects: objects, + nestedObjectLists: objLists, + ); } Map toJson({EncodingMode mode = EncodingMode.hydrated}) { diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/in_memory_cache_provider.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/in_memory_cache_provider.dart index 1d554e600c0d..1a6eaf5b7979 100644 --- a/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/in_memory_cache_provider.dart +++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/in_memory_cache_provider.dart @@ -72,6 +72,8 @@ class InMemoryCacheProvider implements CacheProvider { Future dispose() async {} } -CacheProvider cacheImplementation(String identifier, bool memory, - {String? customDbPath}) => - InMemoryCacheProvider(identifier); +CacheProvider cacheImplementation( + String identifier, + bool memory, { + String? customDbPath, +}) => InMemoryCacheProvider(identifier); diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/result_tree_processor.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/result_tree_processor.dart index ce4bf1bad24a..2c5cc052cc1d 100644 --- a/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/result_tree_processor.dart +++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/result_tree_processor.dart @@ -30,29 +30,37 @@ class ResultTreeProcessor { /// Takes a server response, traverses the data, creates or updates `EntityDataObject`s, /// and builds a dehydrated `EntityNode` tree. Future dehydrateResults( - String queryId, - Map serverResponse, - CacheProvider cacheProvider, - Map paths) async { + String queryId, + Map serverResponse, + CacheProvider cacheProvider, + Map paths, + ) async { final impactedQueryIds = {}; Map jsonData = serverResponse; if (serverResponse.containsKey('data')) { jsonData = serverResponse['data']; } - final rootNode = _dehydrateNode(queryId, jsonData, cacheProvider, - impactedQueryIds, DataConnectPath(), paths); + final rootNode = _dehydrateNode( + queryId, + jsonData, + cacheProvider, + impactedQueryIds, + DataConnectPath(), + paths, + ); return DehydrationResult(rootNode, impactedQueryIds); } EntityNode _dehydrateNode( - String queryId, - dynamic data, - CacheProvider cacheProvider, - Set impactedQueryIds, - DataConnectPath path, - Map paths) { + String queryId, + dynamic data, + CacheProvider cacheProvider, + Set impactedQueryIds, + DataConnectPath path, + Map paths, + ) { if (data is Map) { // Look up entityId for current path String? guid; @@ -70,12 +78,13 @@ class ResultTreeProcessor { if (value is Map) { //developer.log('detected Map for $key'); EntityNode en = _dehydrateNode( - queryId, - value, - cacheProvider, - impactedQueryIds, - path.appending(DataConnectFieldPathSegment(key)), - paths); + queryId, + value, + cacheProvider, + impactedQueryIds, + path.appending(DataConnectFieldPathSegment(key)), + paths, + ); nestedObjects[key] = en; } else if (value is List) { //developer.log('detected List for $key'); @@ -84,7 +93,8 @@ class ResultTreeProcessor { for (var i = 0; i < value.length; i++) { final item = value[i]; if (item is Map) { - nodeList.add(_dehydrateNode( + nodeList.add( + _dehydrateNode( queryId, item, cacheProvider, @@ -92,7 +102,9 @@ class ResultTreeProcessor { path .appending(DataConnectFieldPathSegment(key)) .appending(DataConnectListIndexPathSegment(i)), - paths)); + paths, + ), + ); } else { // assuming scalar - we don't handle array of arrays scalarValueList.add(item); @@ -102,8 +114,9 @@ class ResultTreeProcessor { // we don't normalize mixed lists. We store them as-is for reconstruction from cache. if (nodeList.isNotEmpty && scalarValueList.isNotEmpty) { // mixed type array - we directly store the json as-is - developer - .log('detected mixed type array for key $key. storing as-is'); + developer.log( + 'detected mixed type array for key $key. storing as-is', + ); scalarValues[key] = value; } else if (nodeList.isNotEmpty) { nestedObjectLists[key] = nodeList; @@ -126,25 +139,31 @@ class ResultTreeProcessor { cacheProvider.updateEntityData(existingEdo); impactedQueryIds.addAll(existingEdo.referencedFrom); return EntityNode( - entity: existingEdo, - nestedObjects: nestedObjects, - nestedObjectLists: nestedObjectLists); + entity: existingEdo, + nestedObjects: nestedObjects, + nestedObjectLists: nestedObjectLists, + ); } else { return EntityNode( - scalarValues: scalarValues, - nestedObjects: nestedObjects, - nestedObjectLists: nestedObjectLists); + scalarValues: scalarValues, + nestedObjects: nestedObjects, + nestedObjectLists: nestedObjectLists, + ); } } else { - throw DataConnectError(DataConnectErrorCode.codecFailed, - 'Unexpected object type while caching'); + throw DataConnectError( + DataConnectErrorCode.codecFailed, + 'Unexpected object type while caching', + ); } } /// Takes a dehydrated `EntityNode` tree, fetches the corresponding `EntityDataObject`s /// from the `CacheProvider`, and reconstructs the original data structure. Future> hydrateResults( - EntityNode dehydratedTree, CacheProvider cacheProvider) async { + EntityNode dehydratedTree, + CacheProvider cacheProvider, + ) async { return dehydratedTree.toJson(); //default mode for toJson is hydrate } } diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/sqlite_cache_provider.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/sqlite_cache_provider.dart index c2643ed177f8..a81e560cabe6 100644 --- a/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/sqlite_cache_provider.dart +++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/cache/sqlite_cache_provider.dart @@ -56,8 +56,11 @@ class SQLite3CacheProvider implements CacheProvider { final String entityDataTable = 'entity_data'; final String resultTreeTable = 'query_results'; - SQLite3CacheProvider(this._identifier, - {this.memory = false, this.customDbPath}); + SQLite3CacheProvider( + this._identifier, { + this.memory = false, + this.customDbPath, + }); @override Future initialize() async { @@ -83,28 +86,33 @@ class SQLite3CacheProvider implements CacheProvider { int major = curVersion ~/ 1000000; if (major != 1) { developer.log( - 'Unsupported schema major version $major detected. Expected 1'); + 'Unsupported schema major version $major detected. Expected 1', + ); return false; } } - final selectEntityStmt = _db - .prepare('SELECT data FROM $entityDataTable WHERE entity_guid = ?'); + final selectEntityStmt = _db.prepare( + 'SELECT data FROM $entityDataTable WHERE entity_guid = ?', + ); _openedStatements.add(selectEntityStmt); _selectEntityStmt = selectEntityStmt; final insertEntityStmt = _db.prepare( - 'INSERT OR REPLACE INTO $entityDataTable (entity_guid, data) VALUES (?, ?)'); + 'INSERT OR REPLACE INTO $entityDataTable (entity_guid, data) VALUES (?, ?)', + ); _openedStatements.add(insertEntityStmt); _insertEntityStmt = insertEntityStmt; - final selectResultStmt = - _db.prepare('SELECT data FROM $resultTreeTable WHERE query_id = ?'); + final selectResultStmt = _db.prepare( + 'SELECT data FROM $resultTreeTable WHERE query_id = ?', + ); _openedStatements.add(selectResultStmt); _selectResultStmt = selectResultStmt; final insertResultStmt = _db.prepare( - 'INSERT OR REPLACE INTO $resultTreeTable (query_id, last_accessed, data) VALUES (?, ?, ?)'); + 'INSERT OR REPLACE INTO $resultTreeTable (query_id, last_accessed, data) VALUES (?, ?, ?)', + ); _openedStatements.add(insertResultStmt); _insertResultStmt = insertResultStmt; @@ -224,7 +232,7 @@ class SQLite3CacheProvider implements CacheProvider { _insertResultStmt.execute([ queryId, DateTime.now().millisecondsSinceEpoch / 1000.0, - resultTree.toRawJson() + resultTree.toRawJson(), ]); if (needsTransaction) { _db.execute('COMMIT'); @@ -258,7 +266,12 @@ class SQLite3CacheProvider implements CacheProvider { } } -CacheProvider cacheImplementation(String identifier, bool memory, - {String? customDbPath}) => - SQLite3CacheProvider(identifier, - memory: memory, customDbPath: customDbPath); +CacheProvider cacheImplementation( + String identifier, + bool memory, { + String? customDbPath, +}) => SQLite3CacheProvider( + identifier, + memory: memory, + customDbPath: customDbPath, +); diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/common/dataconnect_error.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/common/dataconnect_error.dart index 32641baafa85..a2aca0919bec 100644 --- a/packages/firebase_data_connect/firebase_data_connect/lib/src/common/dataconnect_error.dart +++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/common/dataconnect_error.dart @@ -20,17 +20,17 @@ enum DataConnectErrorCode { unauthorized, cacheMiss, codecFailed, - other + other, } /// Error thrown when DataConnect encounters an error. class DataConnectError extends FirebaseException { DataConnectError(this.dataConnectErrorCode, String? message) - : super( - plugin: 'Data Connect', - code: dataConnectErrorCode.toString(), - message: message, - ); + : super( + plugin: 'Data Connect', + code: dataConnectErrorCode.toString(), + message: message, + ); final DataConnectErrorCode dataConnectErrorCode; } diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/core/ref.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/core/ref.dart index adad9227d44b..9aef1cae63e8 100644 --- a/packages/firebase_data_connect/firebase_data_connect/lib/src/core/ref.dart +++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/core/ref.dart @@ -22,7 +22,7 @@ import '../common/common_library.dart'; /// Result data source enum DataSource { cache, // results come from cache - server // results come from server + server, // results come from server } /// Result of an Operation Request (query/mutation). @@ -60,8 +60,11 @@ abstract class OperationRef { final FirebaseDataConnect dataConnect; - late final String operationId = - createOperationId(operationName, variables, serializer); + late final String operationId = createOperationId( + operationName, + variables, + serializer, + ); static dynamic _sortKeys(dynamic value) { if (value is Map) { @@ -77,8 +80,11 @@ abstract class OperationRef { return value; } - static String createOperationId(String operationName, - Variables? vars, Serializer? serializer) { + static String createOperationId( + String operationName, + Variables? vars, + Serializer? serializer, + ) { if (vars != null && serializer != null) { try { final decoded = jsonDecode(serializer(vars)); @@ -115,24 +121,34 @@ abstract class OperationRef { List errors = bodyJson['errors'] ?? []; final data = bodyJson['data'] ?? bodyJson; List suberrors = errors - .map((e) => switch (e) { - {'path': List? path, 'message': String? message} => - DataConnectOperationFailureResponseErrorInfo( - (path ?? []) - .map((val) => switch (val) { - String() => DataConnectFieldPathSegment(val), - int() => DataConnectListIndexPathSegment(val), - _ => throw DataConnectError( - DataConnectErrorCode.other, - 'Incorrect type for $val') - }) - .toList(), - message ?? - (throw DataConnectError( - DataConnectErrorCode.other, 'Missing message'))), - _ => throw DataConnectError( - DataConnectErrorCode.other, 'Unable to parse JSON: $e') - }) + .map( + (e) => switch (e) { + {'path': List? path, 'message': String? message} => + DataConnectOperationFailureResponseErrorInfo( + (path ?? []) + .map( + (val) => switch (val) { + String() => DataConnectFieldPathSegment(val), + int() => DataConnectListIndexPathSegment(val), + _ => throw DataConnectError( + DataConnectErrorCode.other, + 'Incorrect type for $val', + ), + }, + ) + .toList(), + message ?? + (throw DataConnectError( + DataConnectErrorCode.other, + 'Missing message', + )), + ), + _ => throw DataConnectError( + DataConnectErrorCode.other, + 'Unable to parse JSON: $e', + ), + }, + ) .toList(); Data? decodedData; Object? decodeError; @@ -145,15 +161,23 @@ abstract class OperationRef { decodeError = e; } if (suberrors.isNotEmpty) { - final response = - DataConnectOperationFailureResponse(suberrors, data, decodedData); + final response = DataConnectOperationFailureResponse( + suberrors, + data, + decodedData, + ); throw DataConnectOperationError( - DataConnectErrorCode.other, 'Failed to invoke operation: ', response); + DataConnectErrorCode.other, + 'Failed to invoke operation: ', + response, + ); } else { if (decodeError != null) { throw DataConnectError( - DataConnectErrorCode.other, 'Unable to decode data: $decodeError'); + DataConnectErrorCode.other, + 'Unable to decode data: $decodeError', + ); } if (decodedData is! Data) { throw DataConnectError( @@ -180,17 +204,19 @@ class QueryManager { if (dataConnect.cacheManager != null) { _impactedQueriesSubscription = dataConnect.cacheManager!.impactedQueries .listen((impactedQueryIds) async { - for (final queryId in impactedQueryIds) { - final queryRef = trackedQueries[queryId]; - if (queryRef != null) { - try { - await queryRef.execute(fetchPolicy: QueryFetchPolicy.cacheOnly); - } catch (e) { - log('Error executing impacted query $queryId $e'); + for (final queryId in impactedQueryIds) { + final queryRef = trackedQueries[queryId]; + if (queryRef != null) { + try { + await queryRef.execute( + fetchPolicy: QueryFetchPolicy.cacheOnly, + ); + } catch (e) { + log('Error executing impacted query $queryId $e'); + } + } } - } - } - }); + }); } } @@ -214,11 +240,11 @@ class QueryManager { final streamController = StreamController>.broadcast( - onCancel: () { - trackedQueries.remove(queryId); - ref._onAllSubscribersCancelled(); - }, - ); + onCancel: () { + trackedQueries.remove(queryId); + ref._onAllSubscribersCancelled(); + }, + ); return streamController; } @@ -238,19 +264,20 @@ class QueryRef extends OperationRef { Serializer serializer, Variables? variables, ) : super( - dataConnect, - operationName, - transport, - deserializer, - serializer, - variables, - ); + dataConnect, + operationName, + transport, + deserializer, + serializer, + variables, + ); final QueryManager _queryManager; @override - Future> execute( - {QueryFetchPolicy fetchPolicy = QueryFetchPolicy.preferCache}) async { + Future> execute({ + QueryFetchPolicy fetchPolicy = QueryFetchPolicy.preferCache, + }) async { if (dataConnect.cacheManager != null) { switch (fetchPolicy) { case QueryFetchPolicy.cacheOnly: @@ -270,23 +297,28 @@ class QueryRef extends OperationRef { } Future> _executeFromCache( - QueryFetchPolicy fetchPolicy) async { + QueryFetchPolicy fetchPolicy, + ) async { if (dataConnect.cacheManager == null) { throw DataConnectError( - DataConnectErrorCode.cacheMiss, 'Cache miss. No configured cache'); + DataConnectErrorCode.cacheMiss, + 'Cache miss. No configured cache', + ); } final cacheManager = dataConnect.cacheManager!; - bool allowStale = fetchPolicy == + bool allowStale = + fetchPolicy == QueryFetchPolicy.cacheOnly; //if its cache only, we always allow stale final cachedData = await cacheManager.resultTree(operationId, allowStale); if (cachedData != null) { try { final result = QueryResult( - dataConnect, - deserializer(jsonEncode(cachedData['data'] ?? cachedData)), - DataSource.cache, - this); + dataConnect, + deserializer(jsonEncode(cachedData['data'] ?? cachedData)), + DataSource.cache, + this, + ); publishResultToStream(result); return result; } catch (e) { @@ -297,7 +329,9 @@ class QueryRef extends OperationRef { throw DataConnectError(DataConnectErrorCode.cacheMiss, 'Cache miss'); } else { throw DataConnectError( - DataConnectErrorCode.cacheMiss, 'Possible stale cache miss'); + DataConnectErrorCode.cacheMiss, + 'Possible stale cache miss', + ); } } } @@ -305,23 +339,27 @@ class QueryRef extends OperationRef { Future> _executeFromServer() async { bool shouldRetry = await _shouldRetry(); try { - ServerResponse serverResponse = - await _transport.invokeQuery( - operationId, - operationName, - deserializer, - serializer, - variables, - _lastToken, - ); + ServerResponse serverResponse = await _transport + .invokeQuery( + operationId, + operationName, + deserializer, + serializer, + variables, + _lastToken, + ); if (dataConnect.cacheManager != null) { await dataConnect.cacheManager!.update(operationId, serverResponse); } Data typedData = _convertBodyJsonToData(serverResponse.data); - QueryResult res = - QueryResult(dataConnect, typedData, DataSource.server, this); + QueryResult res = QueryResult( + dataConnect, + typedData, + DataSource.server, + this, + ); publishResultToStream(res); return res; } on DataConnectError catch (e) { @@ -372,8 +410,8 @@ class QueryRef extends OperationRef { // server stream for one logical subscription. _queryManager.trackedQueries[operationId] = this; - final stream = - _streamController!.stream.cast>(); + final stream = _streamController!.stream + .cast>(); // Return the stream to the caller, then execute fetches Future.microtask(() async { @@ -428,16 +466,24 @@ class QueryRef extends OperationRef { (serverResponse) async { if (dataConnect.cacheManager != null) { try { - await dataConnect.cacheManager! - .update(operationId, serverResponse); + await dataConnect.cacheManager!.update( + operationId, + serverResponse, + ); } catch (e) { - log("QueryRef $operationId _streamFromServer loop cache update failed: $e"); + log( + "QueryRef $operationId _streamFromServer loop cache update failed: $e", + ); } } Data typedData = _convertBodyJsonToData(serverResponse.data); - QueryResult res = - QueryResult(dataConnect, typedData, DataSource.server, this); + QueryResult res = QueryResult( + dataConnect, + typedData, + DataSource.server, + this, + ); publishResultToStream(res); }, onError: (e) { @@ -463,7 +509,9 @@ class QueryRef extends OperationRef { _serverStreamSubscription?.cancel(); _serverStreamSubscription = null; _serverStream = null; - log("QueryRef $operationId _streamFromServer loop Unknown loop failure: $e"); + log( + "QueryRef $operationId _streamFromServer loop Unknown loop failure: $e", + ); publishErrorToStream(e); } finally { _serverStreamStarting = false; @@ -514,15 +562,15 @@ class MutationRef extends OperationRef { Future> _executeOperation( String? token, ) async { - ServerResponse serverResponse = - await _transport.invokeMutation( - operationId, - operationName, - deserializer, - serializer, - variables, - token, - ); + ServerResponse serverResponse = await _transport + .invokeMutation( + operationId, + operationName, + deserializer, + serializer, + variables, + token, + ); Data typedData = _convertBodyJsonToData(serverResponse.data); diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/firebase_data_connect.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/firebase_data_connect.dart index 165b6f5d62fb..d8a1317df851 100644 --- a/packages/firebase_data_connect/firebase_data_connect/lib/src/firebase_data_connect.dart +++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/firebase_data_connect.dart @@ -30,24 +30,26 @@ import 'cache/cache.dart'; class FirebaseDataConnect extends FirebasePlugin { /// Constructor for initializing Data Connect @visibleForTesting - FirebaseDataConnect( - {required this.app, - required this.connectorConfig, - @Deprecated( - 'Passing an explicit instance is deprecated, internal handling is now automatic.') - this.auth, - @Deprecated( - 'Passing an explicit instance is deprecated, internal handling is now automatic.') - this.appCheck, - CallerSDKType? sdkType, - this.cacheSettings}) - : options = DataConnectOptions( - app.options.projectId, - connectorConfig.location, - connectorConfig.connector, - connectorConfig.serviceId, - ), - super(app.name, 'plugins.flutter.io/firebase_data_connect') { + FirebaseDataConnect({ + required this.app, + required this.connectorConfig, + @Deprecated( + 'Passing an explicit instance is deprecated, internal handling is now automatic.', + ) + this.auth, + @Deprecated( + 'Passing an explicit instance is deprecated, internal handling is now automatic.', + ) + this.appCheck, + CallerSDKType? sdkType, + this.cacheSettings, + }) : options = DataConnectOptions( + app.options.projectId, + connectorConfig.location, + connectorConfig.connector, + connectorConfig.serviceId, + ), + super(app.name, 'plugins.flutter.io/firebase_data_connect') { _queryManager = QueryManager(this); if (sdkType != null) { _sdkType = sdkType; @@ -96,8 +98,11 @@ class FirebaseDataConnect extends FirebasePlugin { if (transport != null) { return; } - transportOptions ??= - TransportOptions('firebasedataconnect.googleapis.com', null, true); + transportOptions ??= TransportOptions( + 'firebasedataconnect.googleapis.com', + null, + true, + ); auth ??= app.getService(); appCheck ??= app.getService(); @@ -136,8 +141,11 @@ class FirebaseDataConnect extends FirebasePlugin { ) { checkTransport(); checkAndInitializeCache(); - String queryId = - OperationRef.createOperationId(operationName, vars, varsSerializer); + String queryId = OperationRef.createOperationId( + operationName, + vars, + varsSerializer, + ); QueryRef? ref = _queryManager.trackedQueries[queryId] as QueryRef?; @@ -203,17 +211,20 @@ class FirebaseDataConnect extends FirebasePlugin { /// /// If [app] is not provided, the default Firebase app will be used. /// If pass in [appCheck], request session will get protected from abusing. - static FirebaseDataConnect instanceFor( - {FirebaseApp? app, - @Deprecated( - 'Passing an explicit instance is deprecated, internal handling is now automatic.') - FirebaseAuth? auth, - @Deprecated( - 'Passing an explicit instance is deprecated, internal handling is now automatic.') - FirebaseAppCheck? appCheck, - CallerSDKType? sdkType, - required ConnectorConfig connectorConfig, - CacheSettings? cacheSettings}) { + static FirebaseDataConnect instanceFor({ + FirebaseApp? app, + @Deprecated( + 'Passing an explicit instance is deprecated, internal handling is now automatic.', + ) + FirebaseAuth? auth, + @Deprecated( + 'Passing an explicit instance is deprecated, internal handling is now automatic.', + ) + FirebaseAppCheck? appCheck, + CallerSDKType? sdkType, + required ConnectorConfig connectorConfig, + CacheSettings? cacheSettings, + }) { app ??= Firebase.app(); auth ??= FirebaseAuth.instanceFor(app: app); appCheck ??= FirebaseAppCheck.instanceFor(app: app); @@ -296,10 +307,22 @@ class _RoutingTransport implements DataConnectTransport { ) { if (websocket.isConnected) { return websocket.invokeMutation( - operationId, queryName, deserializer, serializer, vars, token); + operationId, + queryName, + deserializer, + serializer, + vars, + token, + ); } return rest.invokeMutation( - operationId, queryName, deserializer, serializer, vars, token); + operationId, + queryName, + deserializer, + serializer, + vars, + token, + ); } @override @@ -313,10 +336,22 @@ class _RoutingTransport implements DataConnectTransport { ) { if (websocket.isConnected) { return websocket.invokeQuery( - operationId, queryName, deserializer, serialize, vars, token); + operationId, + queryName, + deserializer, + serialize, + vars, + token, + ); } return rest.invokeQuery( - operationId, queryName, deserializer, serialize, vars, token); + operationId, + queryName, + deserializer, + serialize, + vars, + token, + ); } @override @@ -329,6 +364,12 @@ class _RoutingTransport implements DataConnectTransport { String? token, ) { return websocket.invokeStreamQuery( - operationId, queryName, deserializer, serializer, vars, token); + operationId, + queryName, + deserializer, + serializer, + vars, + token, + ); } } diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/network/rest_transport.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/network/rest_transport.dart index a2f1b021a97c..260943fb22ad 100644 --- a/packages/firebase_data_connect/firebase_data_connect/lib/src/network/rest_transport.dart +++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/network/rest_transport.dart @@ -199,7 +199,8 @@ class RestTransport implements DataConnectTransport { String? token, ) { throw UnsupportedError( - 'Streaming should be routed through WebSocketTransport'); + 'Streaming should be routed through WebSocketTransport', + ); } } @@ -210,5 +211,4 @@ DataConnectTransport getTransport( String appId, CallerSDKType sdkType, FirebaseAppCheck? appCheck, -) => - RestTransport(transportOptions, options, appId, sdkType, appCheck); +) => RestTransport(transportOptions, options, appId, sdkType, appCheck); diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/network/stream_protocol.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/network/stream_protocol.dart index a0478e6e1e0c..9b8561df1d0f 100644 --- a/packages/firebase_data_connect/firebase_data_connect/lib/src/network/stream_protocol.dart +++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/network/stream_protocol.dart @@ -13,12 +13,7 @@ // limitations under the License. /// The kind of streaming request. -enum RequestKind { - subscribe, - execute, - resume, - cancel, -} +enum RequestKind { subscribe, execute, resume, cancel } /// Request to execute or subscribe to a Data Connect query or mutation. class ExecuteRequest { @@ -134,8 +129,8 @@ class StreamResponse { final errObj = json['error'] as Map; json = { 'errors': [ - {'message': errObj['message']} - ] + {'message': errObj['message']}, + ], }; } diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/network/transport_stub.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/network/transport_stub.dart index 87b8445f3abe..f25dd4b2a689 100644 --- a/packages/firebase_data_connect/firebase_data_connect/lib/src/network/transport_stub.dart +++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/network/transport_stub.dart @@ -27,7 +27,6 @@ class TransportStub implements DataConnectTransport { /// FirebaseAuth @override - /// FirebaseAppCheck @override FirebaseAppCheck? appCheck; @@ -96,5 +95,4 @@ DataConnectTransport getTransport( String appId, CallerSDKType sdkType, FirebaseAppCheck? appCheck, -) => - TransportStub(transportOptions, options, appId, sdkType, appCheck); +) => TransportStub(transportOptions, options, appId, sdkType, appCheck); diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/network/websocket_transport.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/network/websocket_transport.dart index 9daf48cbcb08..93a1980656ab 100644 --- a/packages/firebase_data_connect/firebase_data_connect/lib/src/network/websocket_transport.dart +++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/network/websocket_transport.dart @@ -24,7 +24,11 @@ class _PendingUnary { final bool isMutation; _PendingUnary( - this.completer, this.operationName, this.variables, this.isMutation); + this.completer, + this.operationName, + this.variables, + this.isMutation, + ); } class _PendingSubscription { @@ -66,7 +70,8 @@ class WebSocketTransport implements DataConnectTransport { scheme: protocol, host: host, port: port, - path: '/ws/google.firebase.dataconnect.v1.ConnectorStreamService.Connect/' + path: + '/ws/google.firebase.dataconnect.v1.ConnectorStreamService.Connect/' '$projectId/locations/$location/services/$serviceId', ).toString(); @@ -269,8 +274,12 @@ class WebSocketTransport implements DataConnectTransport { static const String _chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; String _generateRequestId(String operationName) { - final randStr = String.fromCharCodes(Iterable.generate( - 15, (_) => _chars.codeUnitAt(_random.nextInt(_chars.length)))); + final randStr = String.fromCharCodes( + Iterable.generate( + 15, + (_) => _chars.codeUnitAt(_random.nextInt(_chars.length)), + ), + ); return '${operationName}_$randStr'; } @@ -354,7 +363,9 @@ class WebSocketTransport implements DataConnectTransport { } _releaseWebSocketTransport(); throw DataConnectError( - DataConnectErrorCode.other, 'WebSocket connection failed: $e'); + DataConnectErrorCode.other, + 'WebSocket connection failed: $e', + ); } if (!identical(_channel, channel)) { @@ -442,9 +453,12 @@ class WebSocketTransport implements DataConnectTransport { } void _clearState([DataConnectError? error]) { - final e = error ?? + final e = + error ?? DataConnectError( - DataConnectErrorCode.other, 'WebSocket connection closed.'); + DataConnectErrorCode.other, + 'WebSocket connection closed.', + ); for (final pendings in _unaryListeners.values) { for (final p in pendings) { if (!p.completer.isCompleted) { @@ -478,14 +492,19 @@ class WebSocketTransport implements DataConnectTransport { _isReconnecting = true; if (_reconnectAttempts >= _maxReconnectAttempts) { - _clearState(DataConnectError(DataConnectErrorCode.other, - 'Network disconnected after max attempts.')); + _clearState( + DataConnectError( + DataConnectErrorCode.other, + 'Network disconnected after max attempts.', + ), + ); return; } final delay = min( - _initialReconnectDelayMs * pow(2, _reconnectAttempts).toInt(), - _maxReconnectDelayMs); + _initialReconnectDelayMs * pow(2, _reconnectAttempts).toInt(), + _maxReconnectDelayMs, + ); _reconnectTimer?.cancel(); _reconnectTimer = Timer(Duration(milliseconds: delay), () async { @@ -520,15 +539,21 @@ class WebSocketTransport implements DataConnectTransport { } void _replayQueriesAndFailMutations( - String? authToken, String? appCheckToken) { + String? authToken, + String? appCheckToken, + ) { final unariesToReplay = >{}; for (final entry in _unaryListeners.entries) { final reqId = entry.key; final kept = <_PendingUnary>[]; for (final p in entry.value) { if (p.isMutation) { - p.completer.completeError(DataConnectError(DataConnectErrorCode.other, - 'Network reconnected; mutations cannot be safely retried.')); + p.completer.completeError( + DataConnectError( + DataConnectErrorCode.other, + 'Network reconnected; mutations cannot be safely retried.', + ), + ); } else { kept.add(p); final headers = _buildHeaders(authToken, appCheckToken); @@ -644,8 +669,16 @@ class WebSocketTransport implements DataConnectTransport { Variables? vars, String? authToken, ) async { - return _invokeUnary(operationId, queryName, deserializer, serializer, vars, - authToken, RequestKind.execute, false); + return _invokeUnary( + operationId, + queryName, + deserializer, + serializer, + vars, + authToken, + RequestKind.execute, + false, + ); } @override @@ -657,8 +690,16 @@ class WebSocketTransport implements DataConnectTransport { Variables? vars, String? authToken, ) async { - return _invokeUnary(operationId, queryName, deserializer, serializer, vars, - authToken, RequestKind.execute, true); + return _invokeUnary( + operationId, + queryName, + deserializer, + serializer, + vars, + authToken, + RequestKind.execute, + true, + ); } Future _invokeUnary( @@ -678,8 +719,15 @@ class WebSocketTransport implements DataConnectTransport { _pendingOperationSetups++; Completer completer; try { - completer = await _sendUnary(operationId, operationName, serializer, vars, - authToken, requestKind, isMutation); + completer = await _sendUnary( + operationId, + operationName, + serializer, + vars, + authToken, + requestKind, + isMutation, + ); } finally { _pendingOperationSetups--; } @@ -712,9 +760,11 @@ class WebSocketTransport implements DataConnectTransport { // completer — the caller's `execute()` future — would hang forever. // `_liveSubscriptionRequestId` also purges the mapping if it is stale. final liveRequestId = _liveSubscriptionRequestId(operationId); - final liveSubscription = - liveRequestId == null ? null : _pendingSubscriptions[liveRequestId]; - final canResume = liveRequestId != null && + final liveSubscription = liveRequestId == null + ? null + : _pendingSubscriptions[liveRequestId]; + final canResume = + liveRequestId != null && liveSubscription!.sentOnGeneration == _connectionGeneration; if (canResume) { @@ -723,8 +773,11 @@ class WebSocketTransport implements DataConnectTransport { if (vars != null && serializer != null) { variablesMap = jsonDecode(serializer(vars)); } - _unaryListeners.putIfAbsent(existingRequestId, () => []).add( - _PendingUnary(completer, operationName, variablesMap, isMutation)); + _unaryListeners + .putIfAbsent(existingRequestId, () => []) + .add( + _PendingUnary(completer, operationName, variablesMap, isMutation), + ); String? appCheckToken; try { @@ -833,8 +886,11 @@ class WebSocketTransport implements DataConnectTransport { if (isNewSubscription) { _activeSubscriptions[operationId] = requestId; - _pendingSubscriptions[requestId] = - _PendingSubscription(operationId, queryName, variables); + _pendingSubscriptions[requestId] = _PendingSubscription( + operationId, + queryName, + variables, + ); } _streamListeners.putIfAbsent(requestId, () => []).add(controller); diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/timestamp.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/timestamp.dart index 2b6d6ac782e8..00645ff3948b 100644 --- a/packages/firebase_data_connect/firebase_data_connect/lib/src/timestamp.dart +++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/timestamp.dart @@ -45,9 +45,10 @@ class Timestamp { } String toJson() { - String secondsStr = - DateTime.fromMillisecondsSinceEpoch(seconds * 1000, isUtc: true) - .toIso8601String(); + String secondsStr = DateTime.fromMillisecondsSinceEpoch( + seconds * 1000, + isUtc: true, + ).toIso8601String(); if (nanoseconds == 0) { return secondsStr; } diff --git a/packages/firebase_data_connect/firebase_data_connect/pubspec.yaml b/packages/firebase_data_connect/firebase_data_connect/pubspec.yaml index e6e472cdccca..0cafeb93f637 100644 --- a/packages/firebase_data_connect/firebase_data_connect/pubspec.yaml +++ b/packages/firebase_data_connect/firebase_data_connect/pubspec.yaml @@ -8,8 +8,8 @@ false_secrets: - dartpad/** environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: crypto: ^3.0.6 diff --git a/packages/firebase_data_connect/firebase_data_connect/test/src/cache/cache_manager_test.dart b/packages/firebase_data_connect/firebase_data_connect/test/src/cache/cache_manager_test.dart index 69f43f9c853f..fa799e8d0081 100644 --- a/packages/firebase_data_connect/firebase_data_connect/test/src/cache/cache_manager_test.dart +++ b/packages/firebase_data_connect/firebase_data_connect/test/src/cache/cache_manager_test.dart @@ -64,9 +64,9 @@ void main() { 'dataConnect': [ { 'path': ['items'], - 'entityIds': ['123', '345'] - } - ] + 'entityIds': ['123', '345'], + }, + ], }; // query that updates the price for cacheId 123 to 11 @@ -90,9 +90,9 @@ void main() { 'dataConnect': [ { 'path': ['item'], - 'entityId': '123' - } - ] + 'entityId': '123', + }, + ], }; group('Cache Provider Tests', () { @@ -129,10 +129,13 @@ void main() { transport.setHttp(mockHttpClient); dataConnect = FirebaseDataConnect( - app: mockApp, - connectorConfig: mockConnectorConfig, - cacheSettings: CacheSettings( - storage: CacheStorage.memory, maxAge: maxAgeSeconds)); + app: mockApp, + connectorConfig: mockConnectorConfig, + cacheSettings: CacheSettings( + storage: CacheStorage.memory, + maxAge: maxAgeSeconds, + ), + ); dataConnect.transport = transport; dataConnect.checkTransport(); dataConnect.checkAndInitializeCache(); @@ -147,11 +150,15 @@ void main() { Map jsonData = jsonDecode(simpleQueryResponse) as Map; - await cache.update('itemsSimple', - ServerResponse(jsonData, extensions: simpleQueryExtensions)); + await cache.update( + 'itemsSimple', + ServerResponse(jsonData, extensions: simpleQueryExtensions), + ); - Map? cachedData = - await cache.resultTree('itemsSimple', true); + Map? cachedData = await cache.resultTree( + 'itemsSimple', + true, + ); expect(jsonData['data'], cachedData); }); // test set get @@ -185,24 +192,32 @@ void main() { Map jsonDataOne = jsonDecode(simpleQueryResponse) as Map; - await cache.update(queryOneId, - ServerResponse(jsonDataOne, extensions: simpleQueryExtensions)); + await cache.update( + queryOneId, + ServerResponse(jsonDataOne, extensions: simpleQueryExtensions), + ); Map jsonDataTwo = jsonDecode(simpleQueryTwoResponse) as Map; - await cache.update(queryTwoId, - ServerResponse(jsonDataTwo, extensions: simpleQueryTwoExtensions)); + await cache.update( + queryTwoId, + ServerResponse(jsonDataTwo, extensions: simpleQueryTwoExtensions), + ); Map jsonDataOneUpdate = jsonDecode(simpleQueryResponseUpdate) as Map; - await cache.update(queryOneId, - ServerResponse(jsonDataOneUpdate, extensions: simpleQueryExtensions)); + await cache.update( + queryOneId, + ServerResponse(jsonDataOneUpdate, extensions: simpleQueryExtensions), + ); // shared object should be updated. // now reload query two from cache and check object value. // it should be updated - Map? jsonDataTwoUpdated = - await cache.resultTree(queryTwoId, true); + Map? jsonDataTwoUpdated = await cache.resultTree( + queryTwoId, + true, + ); if (jsonDataTwoUpdated == null) { fail('No query two found in cache'); } @@ -247,8 +262,10 @@ void main() { Map jsonData = jsonDecode(simpleQueryResponse) as Map; - await cache.update('itemsSimple', - ServerResponse(jsonData, extensions: simpleQueryExtensions)); + await cache.update( + 'itemsSimple', + ServerResponse(jsonData, extensions: simpleQueryExtensions), + ); QueryRef ref = QueryRef( dataConnect, @@ -276,10 +293,12 @@ void main() { // now lets add delay beyond maxAge and result source should be server await Future.delayed( - Duration(milliseconds: maxAgeSeconds.inMilliseconds + 100), () async { - QueryResult resultDelayed = await ref.execute(); - expect(resultDelayed.source, DataSource.server); - }); + Duration(milliseconds: maxAgeSeconds.inMilliseconds + 100), + () async { + QueryResult resultDelayed = await ref.execute(); + expect(resultDelayed.source, DataSource.server); + }, + ); }); test('Test AnyValue Caching', () async { @@ -301,19 +320,23 @@ void main() { 'dataConnect': [ { 'path': ['anyValueItem'], - 'entityId': 'AnyValueItemSingle_ID' - } - ] + 'entityId': 'AnyValueItemSingle_ID', + }, + ], }; Map jsonData = jsonDecode(anyValueSingleData) as Map; - await cache.update('queryAnyValue', - ServerResponse(jsonData, extensions: anyValueSingleExt)); + await cache.update( + 'queryAnyValue', + ServerResponse(jsonData, extensions: anyValueSingleExt), + ); - Map? cachedData = - await cache.resultTree('queryAnyValue', true); + Map? cachedData = await cache.resultTree( + 'queryAnyValue', + true, + ); expect(cachedData?['anyValueItem']?['name'], 'AnyItem B'); List values = cachedData?['anyValueItem']?['blob']?['values']; @@ -326,8 +349,9 @@ void main() { test('Test Large Result Tree Normalization Performance', () async { final fileTree = File('test/src/cache/resources/large_result_tree.json'); - final fileExt = - File('test/src/cache/resources/large_result_tree_ext.json'); + final fileExt = File( + 'test/src/cache/resources/large_result_tree_ext.json', + ); final String treeStr = await fileTree.readAsString(); final String extStr = await fileExt.readAsString(); @@ -344,12 +368,15 @@ void main() { final stopwatch = Stopwatch()..start(); - await cache.update('largePerformanceQuery', - ServerResponse(treeJson, extensions: extJson)); + await cache.update( + 'largePerformanceQuery', + ServerResponse(treeJson, extensions: extJson), + ); stopwatch.stop(); developer.log( - 'Large Result Tree Normalization took: ${stopwatch.elapsedMilliseconds}ms'); + 'Large Result Tree Normalization took: ${stopwatch.elapsedMilliseconds}ms', + ); final cached = await cache.resultTree('largePerformanceQuery', true); expect(cached, isNotNull); @@ -358,8 +385,9 @@ void main() { test('Test Normalization does not block main thread', () async { final fileTree = File('test/src/cache/resources/large_result_tree.json'); - final fileExt = - File('test/src/cache/resources/large_result_tree_ext.json'); + final fileExt = File( + 'test/src/cache/resources/large_result_tree_ext.json', + ); final String treeStr = await fileTree.readAsString(); final String extStr = await fileExt.readAsString(); @@ -379,15 +407,21 @@ void main() { timerTicks++; }); - await cache.update('largePerformanceQueryNonBlocking', - ServerResponse(treeJson, extensions: extJson)); + await cache.update( + 'largePerformanceQueryNonBlocking', + ServerResponse(treeJson, extensions: extJson), + ); timer.cancel(); - developer - .log('Main thread timer ticks during normalization: $timerTicks'); - expect(timerTicks, greaterThan(5), - reason: 'Main thread was blocked during normalization'); + developer.log( + 'Main thread timer ticks during normalization: $timerTicks', + ); + expect( + timerTicks, + greaterThan(5), + reason: 'Main thread was blocked during normalization', + ); }); }); // test group } //main diff --git a/packages/firebase_data_connect/firebase_data_connect/test/src/cache/cache_manager_test.mocks.dart b/packages/firebase_data_connect/firebase_data_connect/test/src/cache/cache_manager_test.mocks.dart index 05a303db4353..fbf4cec8cc0d 100644 --- a/packages/firebase_data_connect/firebase_data_connect/test/src/cache/cache_manager_test.mocks.dart +++ b/packages/firebase_data_connect/firebase_data_connect/test/src/cache/cache_manager_test.mocks.dart @@ -43,13 +43,8 @@ import 'package:mockito/src/dummies.dart' as _i4; class _FakeFirebaseOptions_0 extends _i1.SmartFake implements _i2.FirebaseOptions { - _FakeFirebaseOptions_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeFirebaseOptions_0(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } /// A class which mocks [FirebaseApp]. @@ -57,83 +52,78 @@ class _FakeFirebaseOptions_0 extends _i1.SmartFake /// See the documentation for Mockito's code generation for more information. class MockFirebaseApp extends _i1.Mock implements _i3.FirebaseApp { @override - String get name => (super.noSuchMethod( - Invocation.getter(#name), - returnValue: _i4.dummyValue( - this, - Invocation.getter(#name), - ), - returnValueForMissingStub: _i4.dummyValue( - this, - Invocation.getter(#name), - ), - ) as String); + String get name => + (super.noSuchMethod( + Invocation.getter(#name), + returnValue: _i4.dummyValue(this, Invocation.getter(#name)), + returnValueForMissingStub: _i4.dummyValue( + this, + Invocation.getter(#name), + ), + ) + as String); @override - _i2.FirebaseOptions get options => (super.noSuchMethod( - Invocation.getter(#options), - returnValue: _FakeFirebaseOptions_0( - this, - Invocation.getter(#options), - ), - returnValueForMissingStub: _FakeFirebaseOptions_0( - this, - Invocation.getter(#options), - ), - ) as _i2.FirebaseOptions); + _i2.FirebaseOptions get options => + (super.noSuchMethod( + Invocation.getter(#options), + returnValue: _FakeFirebaseOptions_0( + this, + Invocation.getter(#options), + ), + returnValueForMissingStub: _FakeFirebaseOptions_0( + this, + Invocation.getter(#options), + ), + ) + as _i2.FirebaseOptions); @override - bool get isAutomaticDataCollectionEnabled => (super.noSuchMethod( - Invocation.getter(#isAutomaticDataCollectionEnabled), - returnValue: false, - returnValueForMissingStub: false, - ) as bool); + bool get isAutomaticDataCollectionEnabled => + (super.noSuchMethod( + Invocation.getter(#isAutomaticDataCollectionEnabled), + returnValue: false, + returnValueForMissingStub: false, + ) + as bool); @override - _i5.Future delete() => (super.noSuchMethod( - Invocation.method( - #delete, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + _i5.Future delete() => + (super.noSuchMethod( + Invocation.method(#delete, []), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future setAutomaticDataCollectionEnabled(bool? enabled) => (super.noSuchMethod( - Invocation.method( - #setAutomaticDataCollectionEnabled, - [enabled], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#setAutomaticDataCollectionEnabled, [enabled]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future setAutomaticResourceManagementEnabled(bool? enabled) => (super.noSuchMethod( - Invocation.method( - #setAutomaticResourceManagementEnabled, - [enabled], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#setAutomaticResourceManagementEnabled, [ + enabled, + ]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override void registerService( T service, { _i5.Future Function(T)? dispose, - }) => - super.noSuchMethod( - Invocation.method( - #registerService, - [service], - {#dispose: dispose}, - ), - returnValueForMissingStub: null, - ); + }) => super.noSuchMethod( + Invocation.method(#registerService, [service], {#dispose: dispose}), + returnValueForMissingStub: null, + ); } /// A class which mocks [ConnectorConfig]. @@ -141,90 +131,80 @@ class MockFirebaseApp extends _i1.Mock implements _i3.FirebaseApp { /// See the documentation for Mockito's code generation for more information. class MockConnectorConfig extends _i1.Mock implements _i6.ConnectorConfig { @override - String get location => (super.noSuchMethod( - Invocation.getter(#location), - returnValue: _i4.dummyValue( - this, - Invocation.getter(#location), - ), - returnValueForMissingStub: _i4.dummyValue( - this, - Invocation.getter(#location), - ), - ) as String); + String get location => + (super.noSuchMethod( + Invocation.getter(#location), + returnValue: _i4.dummyValue( + this, + Invocation.getter(#location), + ), + returnValueForMissingStub: _i4.dummyValue( + this, + Invocation.getter(#location), + ), + ) + as String); @override - String get connector => (super.noSuchMethod( - Invocation.getter(#connector), - returnValue: _i4.dummyValue( - this, - Invocation.getter(#connector), - ), - returnValueForMissingStub: _i4.dummyValue( - this, - Invocation.getter(#connector), - ), - ) as String); + String get connector => + (super.noSuchMethod( + Invocation.getter(#connector), + returnValue: _i4.dummyValue( + this, + Invocation.getter(#connector), + ), + returnValueForMissingStub: _i4.dummyValue( + this, + Invocation.getter(#connector), + ), + ) + as String); @override - String get serviceId => (super.noSuchMethod( - Invocation.getter(#serviceId), - returnValue: _i4.dummyValue( - this, - Invocation.getter(#serviceId), - ), - returnValueForMissingStub: _i4.dummyValue( - this, - Invocation.getter(#serviceId), - ), - ) as String); + String get serviceId => + (super.noSuchMethod( + Invocation.getter(#serviceId), + returnValue: _i4.dummyValue( + this, + Invocation.getter(#serviceId), + ), + returnValueForMissingStub: _i4.dummyValue( + this, + Invocation.getter(#serviceId), + ), + ) + as String); @override set location(String? value) => super.noSuchMethod( - Invocation.setter( - #location, - value, - ), - returnValueForMissingStub: null, - ); + Invocation.setter(#location, value), + returnValueForMissingStub: null, + ); @override set connector(String? value) => super.noSuchMethod( - Invocation.setter( - #connector, - value, - ), - returnValueForMissingStub: null, - ); + Invocation.setter(#connector, value), + returnValueForMissingStub: null, + ); @override set serviceId(String? value) => super.noSuchMethod( - Invocation.setter( - #serviceId, - value, - ), - returnValueForMissingStub: null, - ); + Invocation.setter(#serviceId, value), + returnValueForMissingStub: null, + ); @override - String toJson() => (super.noSuchMethod( - Invocation.method( - #toJson, - [], - ), - returnValue: _i4.dummyValue( - this, - Invocation.method( - #toJson, - [], - ), - ), - returnValueForMissingStub: _i4.dummyValue( - this, - Invocation.method( - #toJson, - [], - ), - ), - ) as String); + String toJson() => + (super.noSuchMethod( + Invocation.method(#toJson, []), + returnValue: _i4.dummyValue( + this, + Invocation.method(#toJson, []), + ), + returnValueForMissingStub: _i4.dummyValue( + this, + Invocation.method(#toJson, []), + ), + ) + as String); } diff --git a/packages/firebase_data_connect/firebase_data_connect/test/src/cache/result_tree_processor_test.dart b/packages/firebase_data_connect/firebase_data_connect/test/src/cache/result_tree_processor_test.dart index 9b347425c7dc..594fba5a0d8d 100644 --- a/packages/firebase_data_connect/firebase_data_connect/test/src/cache/result_tree_processor_test.dart +++ b/packages/firebase_data_connect/firebase_data_connect/test/src/cache/result_tree_processor_test.dart @@ -34,22 +34,24 @@ void main() { final Map simpleQueryPaths = { DataConnectPath([ DataConnectFieldPathSegment('items'), - DataConnectListIndexPathSegment(0) + DataConnectListIndexPathSegment(0), ]): PathMetadata( - path: DataConnectPath([ - DataConnectFieldPathSegment('items'), - DataConnectListIndexPathSegment(0) - ]), - entityId: '123'), + path: DataConnectPath([ + DataConnectFieldPathSegment('items'), + DataConnectListIndexPathSegment(0), + ]), + entityId: '123', + ), DataConnectPath([ DataConnectFieldPathSegment('items'), - DataConnectListIndexPathSegment(1) + DataConnectListIndexPathSegment(1), ]): PathMetadata( - path: DataConnectPath([ - DataConnectFieldPathSegment('items'), - DataConnectListIndexPathSegment(1) - ]), - entityId: '345'), + path: DataConnectPath([ + DataConnectFieldPathSegment('items'), + DataConnectListIndexPathSegment(1), + ]), + entityId: '345', + ), }; // query two has same object as query one so should refer to same Entity. @@ -61,8 +63,9 @@ void main() { final Map simpleQueryTwoPaths = { DataConnectPath([DataConnectFieldPathSegment('item')]): PathMetadata( - path: DataConnectPath([DataConnectFieldPathSegment('item')]), - entityId: '123'), + path: DataConnectPath([DataConnectFieldPathSegment('item')]), + entityId: '123', + ), }; group('CacheProviderTests', () { @@ -75,16 +78,26 @@ void main() { Map jsonData = jsonDecode(simpleQueryResponse) as Map; DehydrationResult result = await rp.dehydrateResults( - 'itemsSimple', jsonData['data'], cp, simpleQueryPaths); + 'itemsSimple', + jsonData['data'], + cp, + simpleQueryPaths, + ); expect(result.dehydratedTree.nestedObjectLists?.length, 1); expect(result.dehydratedTree.nestedObjectLists?['items']?.length, 2); - expect(result.dehydratedTree.nestedObjectLists?['items']?.first.entity, - isNotNull); + expect( + result.dehydratedTree.nestedObjectLists?['items']?.first.entity, + isNotNull, + ); Map jsonDataTwo = jsonDecode(simpleQueryResponseTwo) as Map; DehydrationResult resultTwo = await rp.dehydrateResults( - 'itemsSimpleTwo', jsonDataTwo['data'], cp, simpleQueryTwoPaths); + 'itemsSimpleTwo', + jsonDataTwo['data'], + cp, + simpleQueryTwoPaths, + ); List? guids = result.dehydratedTree.nestedObjectLists?['items'] ?.map((item) => item.entity?.guid) diff --git a/packages/firebase_data_connect/firebase_data_connect/test/src/common/dataconnect_options_test.dart b/packages/firebase_data_connect/firebase_data_connect/test/src/common/dataconnect_options_test.dart index 3f8201858454..d34b62e21811 100644 --- a/packages/firebase_data_connect/firebase_data_connect/test/src/common/dataconnect_options_test.dart +++ b/packages/firebase_data_connect/firebase_data_connect/test/src/common/dataconnect_options_test.dart @@ -56,43 +56,45 @@ void main() { group('DataConnectOptions', () { test( - 'should initialize with correct parameters and inherit from ConnectorConfig', - () { - final options = DataConnectOptions( - 'project-abc', - 'us-central1', - 'cloud-sql', - 'service-123', - ); - - // Test inherited fields from ConnectorConfig - expect(options.location, 'us-central1'); - expect(options.connector, 'cloud-sql'); - expect(options.serviceId, 'service-123'); - - // Test new field specific to DataConnectOptions - expect(options.projectId, 'project-abc'); - }); + 'should initialize with correct parameters and inherit from ConnectorConfig', + () { + final options = DataConnectOptions( + 'project-abc', + 'us-central1', + 'cloud-sql', + 'service-123', + ); + + // Test inherited fields from ConnectorConfig + expect(options.location, 'us-central1'); + expect(options.connector, 'cloud-sql'); + expect(options.serviceId, 'service-123'); + + // Test new field specific to DataConnectOptions + expect(options.projectId, 'project-abc'); + }, + ); test( - 'should return correct JSON representation for DataConnectOptions via ConnectorConfig toJson', - () { - final options = DataConnectOptions( - 'project-abc', - 'us-central1', - 'cloud-sql', - 'service-123', - ); - - final jsonResult = options.toJson(); - final expectedJson = jsonEncode({ - 'location': 'us-central1', - 'connector': 'cloud-sql', - 'serviceId': 'service-123', - }); - - // Even though DataConnectOptions has a new field, toJson only reflects fields in ConnectorConfig - expect(jsonResult, expectedJson); - }); + 'should return correct JSON representation for DataConnectOptions via ConnectorConfig toJson', + () { + final options = DataConnectOptions( + 'project-abc', + 'us-central1', + 'cloud-sql', + 'service-123', + ); + + final jsonResult = options.toJson(); + final expectedJson = jsonEncode({ + 'location': 'us-central1', + 'connector': 'cloud-sql', + 'serviceId': 'service-123', + }); + + // Even though DataConnectOptions has a new field, toJson only reflects fields in ConnectorConfig + expect(jsonResult, expectedJson); + }, + ); }); } diff --git a/packages/firebase_data_connect/firebase_data_connect/test/src/core/ref_resubscribe_test.dart b/packages/firebase_data_connect/firebase_data_connect/test/src/core/ref_resubscribe_test.dart index 414ef27fb3db..d3b993bea801 100644 --- a/packages/firebase_data_connect/firebase_data_connect/test/src/core/ref_resubscribe_test.dart +++ b/packages/firebase_data_connect/firebase_data_connect/test/src/core/ref_resubscribe_test.dart @@ -26,8 +26,13 @@ class MockFirebaseDataConnect extends Mock implements FirebaseDataConnect {} /// Minimal in-memory transport that records subscribe/cancel and lets a test /// push events into whichever stream is currently listened to. class FakeStreamTransport implements DataConnectTransport { - FakeStreamTransport(this.transportOptions, this.options, this.appId, - this.sdkType, this.appCheck); + FakeStreamTransport( + this.transportOptions, + this.options, + this.appId, + this.sdkType, + this.appCheck, + ); @override FirebaseAppCheck? appCheck; @@ -90,8 +95,7 @@ class FakeStreamTransport implements DataConnectTransport { Serializer? serialize, Variables? vars, String? token, - ) async => - ServerResponse({}); + ) async => ServerResponse({}); @override Future invokeMutation( @@ -101,8 +105,7 @@ class FakeStreamTransport implements DataConnectTransport { Serializer? serializer, Variables? vars, String? token, - ) async => - ServerResponse({}); + ) async => ServerResponse({}); } void main() { @@ -132,14 +135,14 @@ void main() { }); QueryRef buildRef() => QueryRef( - dataConnect, - 'listMovies', - transport, - deserializer, - queryManager, - emptySerializer, - null, - ); + dataConnect, + 'listMovies', + transport, + deserializer, + queryManager, + emptySerializer, + null, + ); /// Waits for a first event on [stream], returning false if it never arrives. Future firstEventArrives( @@ -164,78 +167,98 @@ void main() { } group('QueryRef double subscribe', () { - test('two subscribe() calls on the same ref open exactly one server stream', - () async { - final ref = buildRef(); - - // Exactly the shape of the `should be able to gracefully cancel` e2e - // test: two listeners for the same query, back to back, which - // `FirebaseDataConnect.query()` resolves to the *same* cached QueryRef. - final a = ref.subscribe().listen((_) {}); - final b = ref.subscribe().listen((_) {}); - - await Future.delayed(const Duration(milliseconds: 50)); - - expect(transport.subscribeCount, 1, - reason: 'the second subscriber must multiplex onto the existing ' - 'server stream, not open a second one that nothing can cancel'); - - await a.cancel(); - await b.cancel(); - - // Everything the ref opened must be cancelled once all subscribers go. - expect(transport.liveSubscriptions, 0, - reason: 'no server stream may outlive its last subscriber'); - }); + test( + 'two subscribe() calls on the same ref open exactly one server stream', + () async { + final ref = buildRef(); + + // Exactly the shape of the `should be able to gracefully cancel` e2e + // test: two listeners for the same query, back to back, which + // `FirebaseDataConnect.query()` resolves to the *same* cached QueryRef. + final a = ref.subscribe().listen((_) {}); + final b = ref.subscribe().listen((_) {}); + + await Future.delayed(const Duration(milliseconds: 50)); + + expect( + transport.subscribeCount, + 1, + reason: + 'the second subscriber must multiplex onto the existing ' + 'server stream, not open a second one that nothing can cancel', + ); + + await a.cancel(); + await b.cancel(); + + // Everything the ref opened must be cancelled once all subscribers go. + expect( + transport.liveSubscriptions, + 0, + reason: 'no server stream may outlive its last subscriber', + ); + }, + ); }); group('QueryRef re-subscribe after cancel', () { - test('a query is re-subscribable after a double-subscribe generation', - () async { - final ref = buildRef(); - - // Generation 1: two listeners, then both cancelled. - final a = ref.subscribe().listen((_) {}); - final b = ref.subscribe().listen((_) {}); - await Future.delayed(const Duration(milliseconds: 50)); - transport.emit({'movies': []}); - await a.cancel(); - await b.cancel(); - await Future.delayed(const Duration(milliseconds: 20)); - - // Generation 2: a fresh ref, exactly as `query()` hands out once - // trackedQueries has been cleaned. - expect( - await firstEventArrives( - buildRef().subscribe(), () => transport.emit({'movies': []})), - isTrue, - reason: 'a later subscription to the same query must still receive ' - 'a first event', - ); - }); - - test('re-subscribing the same ref after a plain cancel gets a first event', - () async { - final ref = buildRef(); - - expect( - await firstEventArrives( - ref.subscribe(), () => transport.emit({'movies': []})), - isTrue, - reason: 'first subscription should receive an event', - ); - - expect( - await firstEventArrives( - ref.subscribe(), () => transport.emit({'movies': []})), - isTrue, - reason: 're-subscribing the same QueryRef must restart the ' - 'server stream and deliver a first event', - ); - }); + test( + 'a query is re-subscribable after a double-subscribe generation', + () async { + final ref = buildRef(); + + // Generation 1: two listeners, then both cancelled. + final a = ref.subscribe().listen((_) {}); + final b = ref.subscribe().listen((_) {}); + await Future.delayed(const Duration(milliseconds: 50)); + transport.emit({'movies': []}); + await a.cancel(); + await b.cancel(); + await Future.delayed(const Duration(milliseconds: 20)); + + // Generation 2: a fresh ref, exactly as `query()` hands out once + // trackedQueries has been cleaned. + expect( + await firstEventArrives( + buildRef().subscribe(), + () => transport.emit({'movies': []}), + ), + isTrue, + reason: + 'a later subscription to the same query must still receive ' + 'a first event', + ); + }, + ); test( - 'a listener attached while the previous cancel is still pending is not ' + 're-subscribing the same ref after a plain cancel gets a first event', + () async { + final ref = buildRef(); + + expect( + await firstEventArrives( + ref.subscribe(), + () => transport.emit({'movies': []}), + ), + isTrue, + reason: 'first subscription should receive an event', + ); + + expect( + await firstEventArrives( + ref.subscribe(), + () => transport.emit({'movies': []}), + ), + isTrue, + reason: + 're-subscribing the same QueryRef must restart the ' + 'server stream and deliver a first event', + ); + }, + ); + + test('a listener attached while the previous cancel is still pending is not ' 'stranded', () async { final ref = buildRef(); @@ -270,34 +293,43 @@ void main() { } await second.cancel(); - expect(gotEvent, isTrue, - reason: 'the second subscriber must not be stranded on a ' - 'controller whose server stream was torn down'); - }); - - test('cancelling from inside the event handler still allows re-subscribe', - () async { - final ref = buildRef(); - - // Cancelling from within delivery makes the broadcast controller defer - // onCancel until the firing loop finishes. - late StreamSubscription> first; - final delivered = Completer(); - first = ref.subscribe().listen((_) { - unawaited(first.cancel()); - if (!delivered.isCompleted) delivered.complete(); - }); - await Future.delayed(const Duration(milliseconds: 20)); - transport.emit({'movies': []}); - await delivered.future.timeout(const Duration(seconds: 1)); - expect( - await firstEventArrives( - ref.subscribe(), () => transport.emit({'movies': []})), + gotEvent, isTrue, - reason: 're-subscribing after a deferred cancel must restart the ' - 'server stream', + reason: + 'the second subscriber must not be stranded on a ' + 'controller whose server stream was torn down', ); }); + + test( + 'cancelling from inside the event handler still allows re-subscribe', + () async { + final ref = buildRef(); + + // Cancelling from within delivery makes the broadcast controller defer + // onCancel until the firing loop finishes. + late StreamSubscription> first; + final delivered = Completer(); + first = ref.subscribe().listen((_) { + unawaited(first.cancel()); + if (!delivered.isCompleted) delivered.complete(); + }); + await Future.delayed(const Duration(milliseconds: 20)); + transport.emit({'movies': []}); + await delivered.future.timeout(const Duration(seconds: 1)); + + expect( + await firstEventArrives( + ref.subscribe(), + () => transport.emit({'movies': []}), + ), + isTrue, + reason: + 're-subscribing after a deferred cancel must restart the ' + 'server stream', + ); + }, + ); }); } diff --git a/packages/firebase_data_connect/firebase_data_connect/test/src/core/ref_test.dart b/packages/firebase_data_connect/firebase_data_connect/test/src/core/ref_test.dart index b057f4aeb71f..0547799fa5a6 100644 --- a/packages/firebase_data_connect/firebase_data_connect/test/src/core/ref_test.dart +++ b/packages/firebase_data_connect/firebase_data_connect/test/src/core/ref_test.dart @@ -47,7 +47,11 @@ void main() { final mockFirebaseDataConnect = MockFirebaseDataConnect(); final result = OperationResult( - mockFirebaseDataConnect, mockData, DataSource.server, mockRef); + mockFirebaseDataConnect, + mockData, + DataSource.server, + mockRef, + ); expect(result.data, mockData); expect(result.ref, mockRef); @@ -62,7 +66,11 @@ void main() { final mockFirebaseDataConnect = MockFirebaseDataConnect(); final queryResult = QueryResult( - mockFirebaseDataConnect, mockData, DataSource.server, mockRef); + mockFirebaseDataConnect, + mockData, + DataSource.server, + mockRef, + ); expect(queryResult.data, mockData); expect(queryResult.ref, mockRef); @@ -80,27 +88,28 @@ void main() { }); test( - 'addQuery should create a new StreamController if query does not exist', - () { - String deserializer(String data) => 'Deserialized Data'; - String varSerializer(Object? _) { - return 'varsAsStr'; - } - - QueryRef ref = QueryRef( - mockDataConnect, - 'testQuery', - MockDataConnectTransport(), - deserializer, - QueryManager(mockDataConnect), - varSerializer, - 'variables', - ); - final stream = queryManager.addQuery(ref); + 'addQuery should create a new StreamController if query does not exist', + () { + String deserializer(String data) => 'Deserialized Data'; + String varSerializer(Object? _) { + return 'varsAsStr'; + } - expect(queryManager.trackedQueries.values.contains(ref), isTrue); - expect(stream, isA()); - }); + QueryRef ref = QueryRef( + mockDataConnect, + 'testQuery', + MockDataConnectTransport(), + deserializer, + QueryManager(mockDataConnect), + varSerializer, + 'variables', + ); + final stream = queryManager.addQuery(ref); + + expect(queryManager.trackedQueries.values.contains(ref), isTrue); + expect(stream, isA()); + }, + ); }); group('MutationRef', () { @@ -170,57 +179,57 @@ void main() { await ref.execute(); }); test( - 'query should forceRefresh on ID token if the first request is unauthorized', - () async { - final mockResponse = http.Response('{"error": "Unauthorized"}', 401); - final mockResponseSuccess = http.Response('{"success": true}', 200); - String deserializer(String data) => 'Deserialized Data'; - int count = 0; - int idTokenCount = 0; - QueryRef ref = QueryRef( - mockDataConnect, - 'operation', - transport, - deserializer, - QueryManager(mockDataConnect), - emptySerializer, - null, - ); - when(mockUser.getIdToken()).thenAnswer( - (invocation) => [ - Future.value('invalid-token'), - Future.value('valid-token'), - ][idTokenCount++], - ); - - when( - mockHttpClient.post( - any, - headers: anyNamed('headers'), - body: anyNamed('body'), - ), - ).thenAnswer( - (invocation) => [ - Future.value(mockResponse), - Future.value(mockResponseSuccess), - ][count++], - ); - final result = await ref.execute(); - - expect(result.data, 'Deserialized Data'); - verify( - mockHttpClient.post( - any, - headers: anyNamed('headers'), - body: anyNamed('body'), - ), - ).called(2); - }); + 'query should forceRefresh on ID token if the first request is unauthorized', + () async { + final mockResponse = http.Response('{"error": "Unauthorized"}', 401); + final mockResponseSuccess = http.Response('{"success": true}', 200); + String deserializer(String data) => 'Deserialized Data'; + int count = 0; + int idTokenCount = 0; + QueryRef ref = QueryRef( + mockDataConnect, + 'operation', + transport, + deserializer, + QueryManager(mockDataConnect), + emptySerializer, + null, + ); + when(mockUser.getIdToken()).thenAnswer( + (invocation) => [ + Future.value('invalid-token'), + Future.value('valid-token'), + ][idTokenCount++], + ); + + when( + mockHttpClient.post( + any, + headers: anyNamed('headers'), + body: anyNamed('body'), + ), + ).thenAnswer( + (invocation) => [ + Future.value(mockResponse), + Future.value(mockResponseSuccess), + ][count++], + ); + final result = await ref.execute(); + + expect(result.data, 'Deserialized Data'); + verify( + mockHttpClient.post( + any, + headers: anyNamed('headers'), + body: anyNamed('body'), + ), + ).called(2); + }, + ); test('throw Error if server throws one', () { String deserializer(String data) => 'Deserialized Data'; - final mockResponse = http.Response( - ''' + final mockResponse = http.Response(''' { "data": {}, "errors": [ @@ -233,9 +242,7 @@ void main() { "extensions": null } ] -}''', - 200, - ); // mockResponse +}''', 200); // mockResponse QueryRef ref = QueryRef( mockDataConnect, @@ -259,8 +266,7 @@ void main() { }); // throwServerError test('should decode partial error if available', () async { - final mockResponse = http.Response( - ''' + final mockResponse = http.Response(''' { "data": {"abc": "def"}, "errors": [ @@ -273,9 +279,7 @@ void main() { "extensions": null } ] - }''', - 200, - ); + }''', 200); when( mockHttpClient.post( any, @@ -301,22 +305,25 @@ void main() { expect( () async => ref.execute(), - throwsA(predicate((e) => - e is DataConnectOperationError && - e.response.rawData!['abc'] == 'def' && - e.response.errors.first.message == - 'SQL query error: pq: duplicate key value violates unique constraint movie_pkey' && - (e.response.errors.first.path[0] as DataConnectFieldPathSegment) - .field == - 'the_matrix' && - e.response.data is AbcHolder && - (e.response.data as AbcHolder).abc == 'def')), + throwsA( + predicate( + (e) => + e is DataConnectOperationError && + e.response.rawData!['abc'] == 'def' && + e.response.errors.first.message == + 'SQL query error: pq: duplicate key value violates unique constraint movie_pkey' && + (e.response.errors.first.path[0] as DataConnectFieldPathSegment) + .field == + 'the_matrix' && + e.response.data is AbcHolder && + (e.response.data as AbcHolder).abc == 'def', + ), + ), ); }); // decodePartialError test('should decode partial error if error has no path', () { - final mockResponse = http.Response( - ''' + final mockResponse = http.Response(''' { "data": {"abc": "def"}, "errors": [ @@ -327,9 +334,7 @@ void main() { "extensions": null } ] - }''', - 200, - ); + }''', 200); when( mockHttpClient.post( any, @@ -355,19 +360,22 @@ void main() { expect( () async => ref.execute(), - throwsA(predicate((e) => - e is DataConnectOperationError && - e.response.rawData!['abc'] == 'def' && - e.response.errors.first.message == 'invalid pkey' && - e.response.errors.first.path.isEmpty && - e.response.data is AbcHolder && - (e.response.data as AbcHolder).abc == 'def')), + throwsA( + predicate( + (e) => + e is DataConnectOperationError && + e.response.rawData!['abc'] == 'def' && + e.response.errors.first.message == 'invalid pkey' && + e.response.errors.first.path.isEmpty && + e.response.data is AbcHolder && + (e.response.data as AbcHolder).abc == 'def', + ), + ), ); }); // testPartialErrorWithoutPath test('should decode partial error if path is specified', () async { - final mockResponse = http.Response( - ''' + final mockResponse = http.Response(''' { "data": {"abc": "def"}, "errors": [ @@ -378,9 +386,7 @@ void main() { "extensions": null } ] - }''', - 200, - ); + }''', 200); when( mockHttpClient.post( any, @@ -404,16 +410,21 @@ void main() { null, ); - expect(() async => ref.execute(), throwsA(predicate((e) { - return e is DataConnectOperationError && - e.response.rawData!['abc'] == 'def' && - e.response.errors.first.message == 'invalid pkey' && - e.response.errors.first.path.length == 3 && - e.response.errors.first.path.first - is DataConnectListIndexPathSegment && - e.response.data is AbcHolder && - (e.response.data as AbcHolder).abc == 'def'; - }))); + expect( + () async => ref.execute(), + throwsA( + predicate((e) { + return e is DataConnectOperationError && + e.response.rawData!['abc'] == 'def' && + e.response.errors.first.message == 'invalid pkey' && + e.response.errors.first.path.length == 3 && + e.response.errors.first.path.first + is DataConnectListIndexPathSegment && + e.response.data is AbcHolder && + (e.response.data as AbcHolder).abc == 'def'; + }), + ), + ); }); // testPartialErrorWithPath }); // group(QueryRef) } diff --git a/packages/firebase_data_connect/firebase_data_connect/test/src/firebase_data_connect_test.dart b/packages/firebase_data_connect/firebase_data_connect/test/src/firebase_data_connect_test.dart index eabf82393de8..72b75cc76e9d 100644 --- a/packages/firebase_data_connect/firebase_data_connect/test/src/firebase_data_connect_test.dart +++ b/packages/firebase_data_connect/firebase_data_connect/test/src/firebase_data_connect_test.dart @@ -29,10 +29,11 @@ class MockFirebaseAuth extends Mock implements FirebaseAuth { @override Stream idTokenChanges() { return super.noSuchMethod( - Invocation.method(#idTokenChanges, []), - returnValue: const Stream.empty(), - returnValueForMissingStub: const Stream.empty(), - ) as Stream; + Invocation.method(#idTokenChanges, []), + returnValue: const Stream.empty(), + returnValueForMissingStub: const Stream.empty(), + ) + as Stream; } } @@ -226,33 +227,34 @@ void main() { }); test( - 'checkTransport resolves dynamic service instances from registry just-in-time', - () { - FirebaseDataConnect.cachedInstances.clear(); - - final dynamicApp = DynamicMockFirebaseApp( - name: 'transportAppName', - options: const FirebaseOptions( - apiKey: 'fake_api_key', - appId: 'fake_app_id', - messagingSenderId: 'fake_messaging_sender_id', - projectId: 'fake_project_id', - ), - mockAuth: mockAuth, - mockAppCheck: mockAppCheck, - ); - - final instance = FirebaseDataConnect( - app: dynamicApp, - connectorConfig: mockConnectorConfig, - ); - - instance.checkTransport(); - - final dynamic routingTransport = instance.transport; - expect(routingTransport.rest.appCheck, equals(mockAppCheck)); - expect(routingTransport.websocket.auth, equals(mockAuth)); - expect(routingTransport.websocket.appCheck, equals(mockAppCheck)); - }); + 'checkTransport resolves dynamic service instances from registry just-in-time', + () { + FirebaseDataConnect.cachedInstances.clear(); + + final dynamicApp = DynamicMockFirebaseApp( + name: 'transportAppName', + options: const FirebaseOptions( + apiKey: 'fake_api_key', + appId: 'fake_app_id', + messagingSenderId: 'fake_messaging_sender_id', + projectId: 'fake_project_id', + ), + mockAuth: mockAuth, + mockAppCheck: mockAppCheck, + ); + + final instance = FirebaseDataConnect( + app: dynamicApp, + connectorConfig: mockConnectorConfig, + ); + + instance.checkTransport(); + + final dynamic routingTransport = instance.transport; + expect(routingTransport.rest.appCheck, equals(mockAppCheck)); + expect(routingTransport.websocket.auth, equals(mockAuth)); + expect(routingTransport.websocket.appCheck, equals(mockAppCheck)); + }, + ); }); } diff --git a/packages/firebase_data_connect/firebase_data_connect/test/src/firebase_data_connect_test.mocks.dart b/packages/firebase_data_connect/firebase_data_connect/test/src/firebase_data_connect_test.mocks.dart index b4e1b1ed8a00..be9ea7c3ee61 100644 --- a/packages/firebase_data_connect/firebase_data_connect/test/src/firebase_data_connect_test.mocks.dart +++ b/packages/firebase_data_connect/firebase_data_connect/test/src/firebase_data_connect_test.mocks.dart @@ -43,13 +43,8 @@ import 'package:mockito/src/dummies.dart' as _i4; class _FakeFirebaseOptions_0 extends _i1.SmartFake implements _i2.FirebaseOptions { - _FakeFirebaseOptions_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeFirebaseOptions_0(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } /// A class which mocks [FirebaseApp]. @@ -57,83 +52,78 @@ class _FakeFirebaseOptions_0 extends _i1.SmartFake /// See the documentation for Mockito's code generation for more information. class MockFirebaseApp extends _i1.Mock implements _i3.FirebaseApp { @override - String get name => (super.noSuchMethod( - Invocation.getter(#name), - returnValue: _i4.dummyValue( - this, - Invocation.getter(#name), - ), - returnValueForMissingStub: _i4.dummyValue( - this, - Invocation.getter(#name), - ), - ) as String); + String get name => + (super.noSuchMethod( + Invocation.getter(#name), + returnValue: _i4.dummyValue(this, Invocation.getter(#name)), + returnValueForMissingStub: _i4.dummyValue( + this, + Invocation.getter(#name), + ), + ) + as String); @override - _i2.FirebaseOptions get options => (super.noSuchMethod( - Invocation.getter(#options), - returnValue: _FakeFirebaseOptions_0( - this, - Invocation.getter(#options), - ), - returnValueForMissingStub: _FakeFirebaseOptions_0( - this, - Invocation.getter(#options), - ), - ) as _i2.FirebaseOptions); + _i2.FirebaseOptions get options => + (super.noSuchMethod( + Invocation.getter(#options), + returnValue: _FakeFirebaseOptions_0( + this, + Invocation.getter(#options), + ), + returnValueForMissingStub: _FakeFirebaseOptions_0( + this, + Invocation.getter(#options), + ), + ) + as _i2.FirebaseOptions); @override - bool get isAutomaticDataCollectionEnabled => (super.noSuchMethod( - Invocation.getter(#isAutomaticDataCollectionEnabled), - returnValue: false, - returnValueForMissingStub: false, - ) as bool); + bool get isAutomaticDataCollectionEnabled => + (super.noSuchMethod( + Invocation.getter(#isAutomaticDataCollectionEnabled), + returnValue: false, + returnValueForMissingStub: false, + ) + as bool); @override - _i5.Future delete() => (super.noSuchMethod( - Invocation.method( - #delete, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + _i5.Future delete() => + (super.noSuchMethod( + Invocation.method(#delete, []), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future setAutomaticDataCollectionEnabled(bool? enabled) => (super.noSuchMethod( - Invocation.method( - #setAutomaticDataCollectionEnabled, - [enabled], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#setAutomaticDataCollectionEnabled, [enabled]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future setAutomaticResourceManagementEnabled(bool? enabled) => (super.noSuchMethod( - Invocation.method( - #setAutomaticResourceManagementEnabled, - [enabled], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#setAutomaticResourceManagementEnabled, [ + enabled, + ]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override void registerService( T service, { _i5.Future Function(T)? dispose, - }) => - super.noSuchMethod( - Invocation.method( - #registerService, - [service], - {#dispose: dispose}, - ), - returnValueForMissingStub: null, - ); + }) => super.noSuchMethod( + Invocation.method(#registerService, [service], {#dispose: dispose}), + returnValueForMissingStub: null, + ); } /// A class which mocks [ConnectorConfig]. @@ -141,90 +131,80 @@ class MockFirebaseApp extends _i1.Mock implements _i3.FirebaseApp { /// See the documentation for Mockito's code generation for more information. class MockConnectorConfig extends _i1.Mock implements _i6.ConnectorConfig { @override - String get location => (super.noSuchMethod( - Invocation.getter(#location), - returnValue: _i4.dummyValue( - this, - Invocation.getter(#location), - ), - returnValueForMissingStub: _i4.dummyValue( - this, - Invocation.getter(#location), - ), - ) as String); + String get location => + (super.noSuchMethod( + Invocation.getter(#location), + returnValue: _i4.dummyValue( + this, + Invocation.getter(#location), + ), + returnValueForMissingStub: _i4.dummyValue( + this, + Invocation.getter(#location), + ), + ) + as String); @override - String get connector => (super.noSuchMethod( - Invocation.getter(#connector), - returnValue: _i4.dummyValue( - this, - Invocation.getter(#connector), - ), - returnValueForMissingStub: _i4.dummyValue( - this, - Invocation.getter(#connector), - ), - ) as String); + String get connector => + (super.noSuchMethod( + Invocation.getter(#connector), + returnValue: _i4.dummyValue( + this, + Invocation.getter(#connector), + ), + returnValueForMissingStub: _i4.dummyValue( + this, + Invocation.getter(#connector), + ), + ) + as String); @override - String get serviceId => (super.noSuchMethod( - Invocation.getter(#serviceId), - returnValue: _i4.dummyValue( - this, - Invocation.getter(#serviceId), - ), - returnValueForMissingStub: _i4.dummyValue( - this, - Invocation.getter(#serviceId), - ), - ) as String); + String get serviceId => + (super.noSuchMethod( + Invocation.getter(#serviceId), + returnValue: _i4.dummyValue( + this, + Invocation.getter(#serviceId), + ), + returnValueForMissingStub: _i4.dummyValue( + this, + Invocation.getter(#serviceId), + ), + ) + as String); @override set location(String? value) => super.noSuchMethod( - Invocation.setter( - #location, - value, - ), - returnValueForMissingStub: null, - ); + Invocation.setter(#location, value), + returnValueForMissingStub: null, + ); @override set connector(String? value) => super.noSuchMethod( - Invocation.setter( - #connector, - value, - ), - returnValueForMissingStub: null, - ); + Invocation.setter(#connector, value), + returnValueForMissingStub: null, + ); @override set serviceId(String? value) => super.noSuchMethod( - Invocation.setter( - #serviceId, - value, - ), - returnValueForMissingStub: null, - ); + Invocation.setter(#serviceId, value), + returnValueForMissingStub: null, + ); @override - String toJson() => (super.noSuchMethod( - Invocation.method( - #toJson, - [], - ), - returnValue: _i4.dummyValue( - this, - Invocation.method( - #toJson, - [], - ), - ), - returnValueForMissingStub: _i4.dummyValue( - this, - Invocation.method( - #toJson, - [], - ), - ), - ) as String); + String toJson() => + (super.noSuchMethod( + Invocation.method(#toJson, []), + returnValue: _i4.dummyValue( + this, + Invocation.method(#toJson, []), + ), + returnValueForMissingStub: _i4.dummyValue( + this, + Invocation.method(#toJson, []), + ), + ) + as String); } diff --git a/packages/firebase_data_connect/firebase_data_connect/test/src/network/rest_transport_test.dart b/packages/firebase_data_connect/firebase_data_connect/test/src/network/rest_transport_test.dart index 37951f03b9cd..333b8470d3b3 100644 --- a/packages/firebase_data_connect/firebase_data_connect/test/src/network/rest_transport_test.dart +++ b/packages/firebase_data_connect/firebase_data_connect/test/src/network/rest_transport_test.dart @@ -87,158 +87,176 @@ void main() { ); }); - test('invokeOperation should throw unauthorized error on 401 response', - () async { - final mockResponse = http.Response('Unauthorized', 401); - when( - mockHttpClient.post( - any, - headers: anyNamed('headers'), - body: anyNamed('body'), - ), - ).thenAnswer((_) async => mockResponse); + test( + 'invokeOperation should throw unauthorized error on 401 response', + () async { + final mockResponse = http.Response('Unauthorized', 401); + when( + mockHttpClient.post( + any, + headers: anyNamed('headers'), + body: anyNamed('body'), + ), + ).thenAnswer((_) async => mockResponse); + + String deserializer(String data) => 'Deserialized Data'; + + expect( + () => transport.invokeOperation( + 'testQuery', + 'executeQuery', + deserializer, + null, + null, + null, + ), + throwsA(isA()), + ); + }, + ); - String deserializer(String data) => 'Deserialized Data'; + test( + 'invokeOperation should throw other errors on non-200 responses', + () async { + final mockResponse = http.Response('{"message": "Some error"}', 500); + when( + mockHttpClient.post( + any, + headers: anyNamed('headers'), + body: anyNamed('body'), + ), + ).thenAnswer((_) async => mockResponse); + + String deserializer(String data) => 'Deserialized Data'; + + expect( + () => transport.invokeOperation( + 'testQuery', + 'executeQuery', + deserializer, + null, + null, + null, + ), + throwsA(isA()), + ); + }, + ); - expect( - () => transport.invokeOperation( + test( + 'invokeQuery should call invokeOperation with correct endpoint', + () async { + final mockResponse = http.Response('{"data": {"key": "value"}}', 200); + when( + mockHttpClient.post( + any, + headers: anyNamed('headers'), + body: anyNamed('body'), + ), + ).thenAnswer((_) async => mockResponse); + + String deserializer(String data) => 'Deserialized Data'; + + await transport.invokeQuery( + 'testQueryId', 'testQuery', - 'executeQuery', deserializer, null, null, null, - ), - throwsA(isA()), - ); - }); + ); + + verify( + mockHttpClient.post( + any, + headers: anyNamed('headers'), + body: json.encode({ + 'name': + 'projects/testProject/locations/testLocation/services/testService/connectors/testConnector', + 'operationName': 'testQuery', + }), + ), + ).called(1); + }, + ); - test('invokeOperation should throw other errors on non-200 responses', - () async { - final mockResponse = http.Response('{"message": "Some error"}', 500); - when( - mockHttpClient.post( - any, - headers: anyNamed('headers'), - body: anyNamed('body'), - ), - ).thenAnswer((_) async => mockResponse); + test( + 'invokeMutation should call invokeOperation with correct endpoint', + () async { + final mockResponse = http.Response('{"data": {"key": "value"}}', 200); + when( + mockHttpClient.post( + any, + headers: anyNamed('headers'), + body: anyNamed('body'), + ), + ).thenAnswer((_) async => mockResponse); - String deserializer(String data) => 'Deserialized Data'; + String deserializer(String data) => 'Deserialized Mutation Data'; - expect( - () => transport.invokeOperation( - 'testQuery', - 'executeQuery', + await transport.invokeMutation( + 'testMutationId', + 'testMutation', deserializer, null, null, null, - ), - throwsA(isA()), - ); - }); - - test('invokeQuery should call invokeOperation with correct endpoint', - () async { - final mockResponse = http.Response('{"data": {"key": "value"}}', 200); - when( - mockHttpClient.post( - any, - headers: anyNamed('headers'), - body: anyNamed('body'), - ), - ).thenAnswer((_) async => mockResponse); - - String deserializer(String data) => 'Deserialized Data'; - - await transport.invokeQuery( - 'testQueryId', 'testQuery', deserializer, null, null, null); - - verify( - mockHttpClient.post( - any, - headers: anyNamed('headers'), - body: json.encode({ - 'name': - 'projects/testProject/locations/testLocation/services/testService/connectors/testConnector', - 'operationName': 'testQuery', - }), - ), - ).called(1); - }); - - test('invokeMutation should call invokeOperation with correct endpoint', - () async { - final mockResponse = http.Response('{"data": {"key": "value"}}', 200); - when( - mockHttpClient.post( - any, - headers: anyNamed('headers'), - body: anyNamed('body'), - ), - ).thenAnswer((_) async => mockResponse); - - String deserializer(String data) => 'Deserialized Mutation Data'; - - await transport.invokeMutation( - 'testMutationId', - 'testMutation', - deserializer, - null, - null, - null, - ); - - verify( - mockHttpClient.post( - any, - headers: anyNamed('headers'), - body: json.encode({ - 'name': - 'projects/testProject/locations/testLocation/services/testService/connectors/testConnector', - 'operationName': 'testMutation', - }), - ), - ).called(1); - }); - - test('invokeOperation should include auth and appCheck tokens in headers', - () async { - final mockResponse = http.Response('{"data": {"key": "value"}}', 200); - when( - mockHttpClient.post( - any, - headers: anyNamed('headers'), - body: anyNamed('body'), - ), - ).thenAnswer((_) async => mockResponse); + ); + + verify( + mockHttpClient.post( + any, + headers: anyNamed('headers'), + body: json.encode({ + 'name': + 'projects/testProject/locations/testLocation/services/testService/connectors/testConnector', + 'operationName': 'testMutation', + }), + ), + ).called(1); + }, + ); - when(mockUser.getIdToken()).thenAnswer((_) async => 'authToken123'); - when(mockAppCheck.getToken()).thenAnswer((_) async => 'appCheckToken123'); + test( + 'invokeOperation should include auth and appCheck tokens in headers', + () async { + final mockResponse = http.Response('{"data": {"key": "value"}}', 200); + when( + mockHttpClient.post( + any, + headers: anyNamed('headers'), + body: anyNamed('body'), + ), + ).thenAnswer((_) async => mockResponse); - String deserializer(String data) => 'Deserialized Data'; + when(mockUser.getIdToken()).thenAnswer((_) async => 'authToken123'); + when( + mockAppCheck.getToken(), + ).thenAnswer((_) async => 'appCheckToken123'); - await transport.invokeOperation( - 'testQuery', - 'executeQuery', - deserializer, - null, - null, - 'authToken123', - ); + String deserializer(String data) => 'Deserialized Data'; - verify( - mockHttpClient.post( - any, - headers: argThat( - containsPair('X-Firebase-Auth-Token', 'authToken123'), - named: 'headers', + await transport.invokeOperation( + 'testQuery', + 'executeQuery', + deserializer, + null, + null, + 'authToken123', + ); + + verify( + mockHttpClient.post( + any, + headers: argThat( + containsPair('X-Firebase-Auth-Token', 'authToken123'), + named: 'headers', + ), + body: anyNamed('body'), ), - body: anyNamed('body'), - ), - ).called(1); - }); + ).called(1); + }, + ); test('invokeOperation should include x-firebase-client headers', () async { final mockResponse = http.Response('{"data": {"key": "value"}}', 200); when( @@ -268,7 +286,9 @@ void main() { any, headers: argThat( containsPair( - 'x-firebase-client', getFirebaseClientVal(packageVersion)), + 'x-firebase-client', + getFirebaseClientVal(packageVersion), + ), named: 'headers', ), body: anyNamed('body'), @@ -301,9 +321,7 @@ void main() { mockHttpClient.post( any, headers: argThat( - allOf( - containsPair('x-client-version', 'flutter/$packageVersion'), - ), + allOf(containsPair('x-client-version', 'flutter/$packageVersion')), named: 'headers', ), body: anyNamed('body'), @@ -312,79 +330,83 @@ void main() { }); test( - 'regression #17290 - invokeOperation should correctly decode UTF-8 response with international characters', - () async { - // Simulate a server response with Korean characters, where the - // Content-Type header does NOT include charset=utf-8 (which is - // what the Firebase emulator sends). Without explicit UTF-8 - // decoding, the http package defaults to latin1, corrupting - // multi-byte characters. - const koreanJson = - '{"data": {"name": "\ud55c\uad6d\uc5b4 \ud14c\uc2a4\ud2b8"}}'; - final mockResponse = http.Response.bytes( - utf8.encode(koreanJson), - 200, - headers: {'content-type': 'application/json'}, - ); - when( - mockHttpClient.post( - any, - headers: anyNamed('headers'), - body: anyNamed('body'), - ), - ).thenAnswer((_) async => mockResponse); + 'regression #17290 - invokeOperation should correctly decode UTF-8 response with international characters', + () async { + // Simulate a server response with Korean characters, where the + // Content-Type header does NOT include charset=utf-8 (which is + // what the Firebase emulator sends). Without explicit UTF-8 + // decoding, the http package defaults to latin1, corrupting + // multi-byte characters. + const koreanJson = + '{"data": {"name": "\ud55c\uad6d\uc5b4 \ud14c\uc2a4\ud2b8"}}'; + final mockResponse = http.Response.bytes( + utf8.encode(koreanJson), + 200, + headers: {'content-type': 'application/json'}, + ); + when( + mockHttpClient.post( + any, + headers: anyNamed('headers'), + body: anyNamed('body'), + ), + ).thenAnswer((_) async => mockResponse); - String deserializer(String data) => 'Deserialized Data'; + String deserializer(String data) => 'Deserialized Data'; - final result = await transport.invokeOperation( - 'testQuery', - 'executeQuery', - deserializer, - null, - null, - null, - ); + final result = await transport.invokeOperation( + 'testQuery', + 'executeQuery', + deserializer, + null, + null, + null, + ); - expect(result.data['data']['name'], - equals('\ud55c\uad6d\uc5b4 \ud14c\uc2a4\ud2b8')); - }); + expect( + result.data['data']['name'], + equals('\ud55c\uad6d\uc5b4 \ud14c\uc2a4\ud2b8'), + ); + }, + ); test( - 'invokeOperation should handle missing auth and appCheck tokens gracefully', - () async { - final mockResponse = http.Response('{"data": {"key": "value"}}', 200); - when( - mockHttpClient.post( - any, - headers: anyNamed('headers'), - body: anyNamed('body'), - ), - ).thenAnswer((_) async => mockResponse); + 'invokeOperation should handle missing auth and appCheck tokens gracefully', + () async { + final mockResponse = http.Response('{"data": {"key": "value"}}', 200); + when( + mockHttpClient.post( + any, + headers: anyNamed('headers'), + body: anyNamed('body'), + ), + ).thenAnswer((_) async => mockResponse); - when(mockUser.getIdToken()).thenThrow(Exception('Auth error')); - when(mockAppCheck.getToken()).thenThrow(Exception('AppCheck error')); + when(mockUser.getIdToken()).thenThrow(Exception('Auth error')); + when(mockAppCheck.getToken()).thenThrow(Exception('AppCheck error')); - String deserializer(String data) => 'Deserialized Data'; + String deserializer(String data) => 'Deserialized Data'; - await transport.invokeOperation( - 'testQuery', - 'executeQuery', - deserializer, - null, - null, - null, - ); - - verify( - mockHttpClient.post( - any, - headers: argThat( - isNot(contains('X-Firebase-Auth-Token')), - named: 'headers', + await transport.invokeOperation( + 'testQuery', + 'executeQuery', + deserializer, + null, + null, + null, + ); + + verify( + mockHttpClient.post( + any, + headers: argThat( + isNot(contains('X-Firebase-Auth-Token')), + named: 'headers', + ), + body: anyNamed('body'), ), - body: anyNamed('body'), - ), - ).called(1); - }); + ).called(1); + }, + ); }); } diff --git a/packages/firebase_data_connect/firebase_data_connect/test/src/network/rest_transport_test.mocks.dart b/packages/firebase_data_connect/firebase_data_connect/test/src/network/rest_transport_test.mocks.dart index 828b48d4f7e7..bac4cdad9740 100644 --- a/packages/firebase_data_connect/firebase_data_connect/test/src/network/rest_transport_test.mocks.dart +++ b/packages/firebase_data_connect/firebase_data_connect/test/src/network/rest_transport_test.mocks.dart @@ -48,96 +48,51 @@ import 'package:mockito/src/dummies.dart' as _i8; // ignore_for_file: invalid_use_of_internal_member class _FakeResponse_0 extends _i1.SmartFake implements _i2.Response { - _FakeResponse_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeResponse_0(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeStreamedResponse_1 extends _i1.SmartFake implements _i2.StreamedResponse { - _FakeStreamedResponse_1( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeStreamedResponse_1(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeUserMetadata_2 extends _i1.SmartFake implements _i3.UserMetadata { - _FakeUserMetadata_2( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeUserMetadata_2(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeMultiFactor_3 extends _i1.SmartFake implements _i4.MultiFactor { - _FakeMultiFactor_3( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeMultiFactor_3(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeIdTokenResult_4 extends _i1.SmartFake implements _i3.IdTokenResult { - _FakeIdTokenResult_4( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeIdTokenResult_4(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeUserCredential_5 extends _i1.SmartFake implements _i4.UserCredential { - _FakeUserCredential_5( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeUserCredential_5(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeConfirmationResult_6 extends _i1.SmartFake implements _i4.ConfirmationResult { - _FakeConfirmationResult_6( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeConfirmationResult_6(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeUser_7 extends _i1.SmartFake implements _i4.User { - _FakeUser_7( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeUser_7(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeFirebaseApp_8 extends _i1.SmartFake implements _i5.FirebaseApp { - _FakeFirebaseApp_8( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeFirebaseApp_8(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } /// A class which mocks [Client]. @@ -149,46 +104,30 @@ class MockClient extends _i1.Mock implements _i2.Client { } @override - _i6.Future<_i2.Response> head( - Uri? url, { - Map? headers, - }) => + _i6.Future<_i2.Response> head(Uri? url, {Map? headers}) => (super.noSuchMethod( - Invocation.method( - #head, - [url], - {#headers: headers}, - ), - returnValue: _i6.Future<_i2.Response>.value(_FakeResponse_0( - this, - Invocation.method( - #head, - [url], - {#headers: headers}, - ), - )), - ) as _i6.Future<_i2.Response>); - - @override - _i6.Future<_i2.Response> get( - Uri? url, { - Map? headers, - }) => + Invocation.method(#head, [url], {#headers: headers}), + returnValue: _i6.Future<_i2.Response>.value( + _FakeResponse_0( + this, + Invocation.method(#head, [url], {#headers: headers}), + ), + ), + ) + as _i6.Future<_i2.Response>); + + @override + _i6.Future<_i2.Response> get(Uri? url, {Map? headers}) => (super.noSuchMethod( - Invocation.method( - #get, - [url], - {#headers: headers}, - ), - returnValue: _i6.Future<_i2.Response>.value(_FakeResponse_0( - this, - Invocation.method( - #get, - [url], - {#headers: headers}, - ), - )), - ) as _i6.Future<_i2.Response>); + Invocation.method(#get, [url], {#headers: headers}), + returnValue: _i6.Future<_i2.Response>.value( + _FakeResponse_0( + this, + Invocation.method(#get, [url], {#headers: headers}), + ), + ), + ) + as _i6.Future<_i2.Response>); @override _i6.Future<_i2.Response> post( @@ -198,28 +137,23 @@ class MockClient extends _i1.Mock implements _i2.Client { _i7.Encoding? encoding, }) => (super.noSuchMethod( - Invocation.method( - #post, - [url], - { - #headers: headers, - #body: body, - #encoding: encoding, - }, - ), - returnValue: _i6.Future<_i2.Response>.value(_FakeResponse_0( - this, - Invocation.method( - #post, - [url], - { - #headers: headers, - #body: body, - #encoding: encoding, - }, - ), - )), - ) as _i6.Future<_i2.Response>); + Invocation.method( + #post, + [url], + {#headers: headers, #body: body, #encoding: encoding}, + ), + returnValue: _i6.Future<_i2.Response>.value( + _FakeResponse_0( + this, + Invocation.method( + #post, + [url], + {#headers: headers, #body: body, #encoding: encoding}, + ), + ), + ), + ) + as _i6.Future<_i2.Response>); @override _i6.Future<_i2.Response> put( @@ -229,28 +163,23 @@ class MockClient extends _i1.Mock implements _i2.Client { _i7.Encoding? encoding, }) => (super.noSuchMethod( - Invocation.method( - #put, - [url], - { - #headers: headers, - #body: body, - #encoding: encoding, - }, - ), - returnValue: _i6.Future<_i2.Response>.value(_FakeResponse_0( - this, - Invocation.method( - #put, - [url], - { - #headers: headers, - #body: body, - #encoding: encoding, - }, - ), - )), - ) as _i6.Future<_i2.Response>); + Invocation.method( + #put, + [url], + {#headers: headers, #body: body, #encoding: encoding}, + ), + returnValue: _i6.Future<_i2.Response>.value( + _FakeResponse_0( + this, + Invocation.method( + #put, + [url], + {#headers: headers, #body: body, #encoding: encoding}, + ), + ), + ), + ) + as _i6.Future<_i2.Response>); @override _i6.Future<_i2.Response> patch( @@ -260,28 +189,23 @@ class MockClient extends _i1.Mock implements _i2.Client { _i7.Encoding? encoding, }) => (super.noSuchMethod( - Invocation.method( - #patch, - [url], - { - #headers: headers, - #body: body, - #encoding: encoding, - }, - ), - returnValue: _i6.Future<_i2.Response>.value(_FakeResponse_0( - this, - Invocation.method( - #patch, - [url], - { - #headers: headers, - #body: body, - #encoding: encoding, - }, - ), - )), - ) as _i6.Future<_i2.Response>); + Invocation.method( + #patch, + [url], + {#headers: headers, #body: body, #encoding: encoding}, + ), + returnValue: _i6.Future<_i2.Response>.value( + _FakeResponse_0( + this, + Invocation.method( + #patch, + [url], + {#headers: headers, #body: body, #encoding: encoding}, + ), + ), + ), + ) + as _i6.Future<_i2.Response>); @override _i6.Future<_i2.Response> delete( @@ -291,49 +215,36 @@ class MockClient extends _i1.Mock implements _i2.Client { _i7.Encoding? encoding, }) => (super.noSuchMethod( - Invocation.method( - #delete, - [url], - { - #headers: headers, - #body: body, - #encoding: encoding, - }, - ), - returnValue: _i6.Future<_i2.Response>.value(_FakeResponse_0( - this, - Invocation.method( - #delete, - [url], - { - #headers: headers, - #body: body, - #encoding: encoding, - }, - ), - )), - ) as _i6.Future<_i2.Response>); - - @override - _i6.Future read( - Uri? url, { - Map? headers, - }) => + Invocation.method( + #delete, + [url], + {#headers: headers, #body: body, #encoding: encoding}, + ), + returnValue: _i6.Future<_i2.Response>.value( + _FakeResponse_0( + this, + Invocation.method( + #delete, + [url], + {#headers: headers, #body: body, #encoding: encoding}, + ), + ), + ), + ) + as _i6.Future<_i2.Response>); + + @override + _i6.Future read(Uri? url, {Map? headers}) => (super.noSuchMethod( - Invocation.method( - #read, - [url], - {#headers: headers}, - ), - returnValue: _i6.Future.value(_i8.dummyValue( - this, - Invocation.method( - #read, - [url], - {#headers: headers}, - ), - )), - ) as _i6.Future); + Invocation.method(#read, [url], {#headers: headers}), + returnValue: _i6.Future.value( + _i8.dummyValue( + this, + Invocation.method(#read, [url], {#headers: headers}), + ), + ), + ) + as _i6.Future); @override _i6.Future<_i9.Uint8List> readBytes( @@ -341,39 +252,29 @@ class MockClient extends _i1.Mock implements _i2.Client { Map? headers, }) => (super.noSuchMethod( - Invocation.method( - #readBytes, - [url], - {#headers: headers}, - ), - returnValue: _i6.Future<_i9.Uint8List>.value(_i9.Uint8List(0)), - ) as _i6.Future<_i9.Uint8List>); + Invocation.method(#readBytes, [url], {#headers: headers}), + returnValue: _i6.Future<_i9.Uint8List>.value(_i9.Uint8List(0)), + ) + as _i6.Future<_i9.Uint8List>); @override _i6.Future<_i2.StreamedResponse> send(_i2.BaseRequest? request) => (super.noSuchMethod( - Invocation.method( - #send, - [request], - ), - returnValue: - _i6.Future<_i2.StreamedResponse>.value(_FakeStreamedResponse_1( - this, - Invocation.method( - #send, - [request], - ), - )), - ) as _i6.Future<_i2.StreamedResponse>); + Invocation.method(#send, [request]), + returnValue: _i6.Future<_i2.StreamedResponse>.value( + _FakeStreamedResponse_1( + this, + Invocation.method(#send, [request]), + ), + ), + ) + as _i6.Future<_i2.StreamedResponse>); @override void close() => super.noSuchMethod( - Invocation.method( - #close, - [], - ), - returnValueForMissingStub: null, - ); + Invocation.method(#close, []), + returnValueForMissingStub: null, + ); } /// A class which mocks [User]. @@ -385,191 +286,173 @@ class MockUser extends _i1.Mock implements _i4.User { } @override - bool get emailVerified => (super.noSuchMethod( - Invocation.getter(#emailVerified), - returnValue: false, - ) as bool); + bool get emailVerified => + (super.noSuchMethod(Invocation.getter(#emailVerified), returnValue: false) + as bool); @override - bool get isAnonymous => (super.noSuchMethod( - Invocation.getter(#isAnonymous), - returnValue: false, - ) as bool); + bool get isAnonymous => + (super.noSuchMethod(Invocation.getter(#isAnonymous), returnValue: false) + as bool); @override - _i3.UserMetadata get metadata => (super.noSuchMethod( - Invocation.getter(#metadata), - returnValue: _FakeUserMetadata_2( - this, - Invocation.getter(#metadata), - ), - ) as _i3.UserMetadata); + _i3.UserMetadata get metadata => + (super.noSuchMethod( + Invocation.getter(#metadata), + returnValue: _FakeUserMetadata_2( + this, + Invocation.getter(#metadata), + ), + ) + as _i3.UserMetadata); @override - List<_i3.UserInfo> get providerData => (super.noSuchMethod( - Invocation.getter(#providerData), - returnValue: <_i3.UserInfo>[], - ) as List<_i3.UserInfo>); + List<_i3.UserInfo> get providerData => + (super.noSuchMethod( + Invocation.getter(#providerData), + returnValue: <_i3.UserInfo>[], + ) + as List<_i3.UserInfo>); @override - String get uid => (super.noSuchMethod( - Invocation.getter(#uid), - returnValue: _i8.dummyValue( - this, - Invocation.getter(#uid), - ), - ) as String); + String get uid => + (super.noSuchMethod( + Invocation.getter(#uid), + returnValue: _i8.dummyValue(this, Invocation.getter(#uid)), + ) + as String); @override - _i4.MultiFactor get multiFactor => (super.noSuchMethod( - Invocation.getter(#multiFactor), - returnValue: _FakeMultiFactor_3( - this, - Invocation.getter(#multiFactor), - ), - ) as _i4.MultiFactor); + _i4.MultiFactor get multiFactor => + (super.noSuchMethod( + Invocation.getter(#multiFactor), + returnValue: _FakeMultiFactor_3( + this, + Invocation.getter(#multiFactor), + ), + ) + as _i4.MultiFactor); @override - _i6.Future delete() => (super.noSuchMethod( - Invocation.method( - #delete, - [], - ), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), - ) as _i6.Future); + _i6.Future delete() => + (super.noSuchMethod( + Invocation.method(#delete, []), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) + as _i6.Future); @override _i6.Future getIdToken([bool? forceRefresh = false]) => (super.noSuchMethod( - Invocation.method( - #getIdToken, - [forceRefresh], - ), - returnValue: _i6.Future.value(), - ) as _i6.Future); + Invocation.method(#getIdToken, [forceRefresh]), + returnValue: _i6.Future.value(), + ) + as _i6.Future); @override - _i6.Future<_i3.IdTokenResult> getIdTokenResult( - [bool? forceRefresh = false]) => + _i6.Future<_i3.IdTokenResult> getIdTokenResult([ + bool? forceRefresh = false, + ]) => (super.noSuchMethod( - Invocation.method( - #getIdTokenResult, - [forceRefresh], - ), - returnValue: _i6.Future<_i3.IdTokenResult>.value(_FakeIdTokenResult_4( - this, - Invocation.method( - #getIdTokenResult, - [forceRefresh], - ), - )), - ) as _i6.Future<_i3.IdTokenResult>); + Invocation.method(#getIdTokenResult, [forceRefresh]), + returnValue: _i6.Future<_i3.IdTokenResult>.value( + _FakeIdTokenResult_4( + this, + Invocation.method(#getIdTokenResult, [forceRefresh]), + ), + ), + ) + as _i6.Future<_i3.IdTokenResult>); @override _i6.Future<_i4.UserCredential> linkWithCredential( - _i3.AuthCredential? credential) => - (super.noSuchMethod( - Invocation.method( - #linkWithCredential, - [credential], - ), - returnValue: _i6.Future<_i4.UserCredential>.value(_FakeUserCredential_5( - this, - Invocation.method( - #linkWithCredential, - [credential], - ), - )), - ) as _i6.Future<_i4.UserCredential>); + _i3.AuthCredential? credential, + ) => + (super.noSuchMethod( + Invocation.method(#linkWithCredential, [credential]), + returnValue: _i6.Future<_i4.UserCredential>.value( + _FakeUserCredential_5( + this, + Invocation.method(#linkWithCredential, [credential]), + ), + ), + ) + as _i6.Future<_i4.UserCredential>); @override _i6.Future<_i4.UserCredential> linkWithProvider(_i3.AuthProvider? provider) => (super.noSuchMethod( - Invocation.method( - #linkWithProvider, - [provider], - ), - returnValue: _i6.Future<_i4.UserCredential>.value(_FakeUserCredential_5( - this, - Invocation.method( - #linkWithProvider, - [provider], - ), - )), - ) as _i6.Future<_i4.UserCredential>); + Invocation.method(#linkWithProvider, [provider]), + returnValue: _i6.Future<_i4.UserCredential>.value( + _FakeUserCredential_5( + this, + Invocation.method(#linkWithProvider, [provider]), + ), + ), + ) + as _i6.Future<_i4.UserCredential>); @override _i6.Future<_i4.UserCredential> reauthenticateWithProvider( - _i3.AuthProvider? provider) => - (super.noSuchMethod( - Invocation.method( - #reauthenticateWithProvider, - [provider], - ), - returnValue: _i6.Future<_i4.UserCredential>.value(_FakeUserCredential_5( - this, - Invocation.method( - #reauthenticateWithProvider, - [provider], - ), - )), - ) as _i6.Future<_i4.UserCredential>); + _i3.AuthProvider? provider, + ) => + (super.noSuchMethod( + Invocation.method(#reauthenticateWithProvider, [provider]), + returnValue: _i6.Future<_i4.UserCredential>.value( + _FakeUserCredential_5( + this, + Invocation.method(#reauthenticateWithProvider, [provider]), + ), + ), + ) + as _i6.Future<_i4.UserCredential>); @override _i6.Future<_i4.UserCredential> reauthenticateWithPopup( - _i3.AuthProvider? provider) => - (super.noSuchMethod( - Invocation.method( - #reauthenticateWithPopup, - [provider], - ), - returnValue: _i6.Future<_i4.UserCredential>.value(_FakeUserCredential_5( - this, - Invocation.method( - #reauthenticateWithPopup, - [provider], - ), - )), - ) as _i6.Future<_i4.UserCredential>); + _i3.AuthProvider? provider, + ) => + (super.noSuchMethod( + Invocation.method(#reauthenticateWithPopup, [provider]), + returnValue: _i6.Future<_i4.UserCredential>.value( + _FakeUserCredential_5( + this, + Invocation.method(#reauthenticateWithPopup, [provider]), + ), + ), + ) + as _i6.Future<_i4.UserCredential>); @override _i6.Future reauthenticateWithRedirect(_i3.AuthProvider? provider) => (super.noSuchMethod( - Invocation.method( - #reauthenticateWithRedirect, - [provider], - ), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), - ) as _i6.Future); + Invocation.method(#reauthenticateWithRedirect, [provider]), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) + as _i6.Future); @override _i6.Future<_i4.UserCredential> linkWithPopup(_i3.AuthProvider? provider) => (super.noSuchMethod( - Invocation.method( - #linkWithPopup, - [provider], - ), - returnValue: _i6.Future<_i4.UserCredential>.value(_FakeUserCredential_5( - this, - Invocation.method( - #linkWithPopup, - [provider], - ), - )), - ) as _i6.Future<_i4.UserCredential>); + Invocation.method(#linkWithPopup, [provider]), + returnValue: _i6.Future<_i4.UserCredential>.value( + _FakeUserCredential_5( + this, + Invocation.method(#linkWithPopup, [provider]), + ), + ), + ) + as _i6.Future<_i4.UserCredential>); @override _i6.Future linkWithRedirect(_i3.AuthProvider? provider) => (super.noSuchMethod( - Invocation.method( - #linkWithRedirect, - [provider], - ), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), - ) as _i6.Future); + Invocation.method(#linkWithRedirect, [provider]), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) + as _i6.Future); @override _i6.Future<_i4.ConfirmationResult> linkWithPhoneNumber( @@ -577,140 +460,113 @@ class MockUser extends _i1.Mock implements _i4.User { _i4.RecaptchaVerifier? verifier, ]) => (super.noSuchMethod( - Invocation.method( - #linkWithPhoneNumber, - [ - phoneNumber, - verifier, - ], - ), - returnValue: - _i6.Future<_i4.ConfirmationResult>.value(_FakeConfirmationResult_6( - this, - Invocation.method( - #linkWithPhoneNumber, - [ - phoneNumber, - verifier, - ], - ), - )), - ) as _i6.Future<_i4.ConfirmationResult>); + Invocation.method(#linkWithPhoneNumber, [phoneNumber, verifier]), + returnValue: _i6.Future<_i4.ConfirmationResult>.value( + _FakeConfirmationResult_6( + this, + Invocation.method(#linkWithPhoneNumber, [ + phoneNumber, + verifier, + ]), + ), + ), + ) + as _i6.Future<_i4.ConfirmationResult>); @override _i6.Future<_i4.UserCredential> reauthenticateWithCredential( - _i3.AuthCredential? credential) => - (super.noSuchMethod( - Invocation.method( - #reauthenticateWithCredential, - [credential], - ), - returnValue: _i6.Future<_i4.UserCredential>.value(_FakeUserCredential_5( - this, - Invocation.method( - #reauthenticateWithCredential, - [credential], - ), - )), - ) as _i6.Future<_i4.UserCredential>); - - @override - _i6.Future reload() => (super.noSuchMethod( - Invocation.method( - #reload, - [], - ), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), - ) as _i6.Future); - - @override - _i6.Future sendEmailVerification( - [_i3.ActionCodeSettings? actionCodeSettings]) => - (super.noSuchMethod( - Invocation.method( - #sendEmailVerification, - [actionCodeSettings], - ), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), - ) as _i6.Future); - - @override - _i6.Future<_i4.User> unlink(String? providerId) => (super.noSuchMethod( - Invocation.method( - #unlink, - [providerId], - ), - returnValue: _i6.Future<_i4.User>.value(_FakeUser_7( - this, - Invocation.method( - #unlink, - [providerId], - ), - )), - ) as _i6.Future<_i4.User>); - - @override - _i6.Future updatePassword(String? newPassword) => (super.noSuchMethod( - Invocation.method( - #updatePassword, - [newPassword], - ), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), - ) as _i6.Future); + _i3.AuthCredential? credential, + ) => + (super.noSuchMethod( + Invocation.method(#reauthenticateWithCredential, [credential]), + returnValue: _i6.Future<_i4.UserCredential>.value( + _FakeUserCredential_5( + this, + Invocation.method(#reauthenticateWithCredential, [credential]), + ), + ), + ) + as _i6.Future<_i4.UserCredential>); + + @override + _i6.Future reload() => + (super.noSuchMethod( + Invocation.method(#reload, []), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) + as _i6.Future); + + @override + _i6.Future sendEmailVerification([ + _i3.ActionCodeSettings? actionCodeSettings, + ]) => + (super.noSuchMethod( + Invocation.method(#sendEmailVerification, [actionCodeSettings]), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) + as _i6.Future); + + @override + _i6.Future<_i4.User> unlink(String? providerId) => + (super.noSuchMethod( + Invocation.method(#unlink, [providerId]), + returnValue: _i6.Future<_i4.User>.value( + _FakeUser_7(this, Invocation.method(#unlink, [providerId])), + ), + ) + as _i6.Future<_i4.User>); + + @override + _i6.Future updatePassword(String? newPassword) => + (super.noSuchMethod( + Invocation.method(#updatePassword, [newPassword]), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) + as _i6.Future); @override _i6.Future updatePhoneNumber( - _i3.PhoneAuthCredential? phoneCredential) => + _i3.PhoneAuthCredential? phoneCredential, + ) => (super.noSuchMethod( - Invocation.method( - #updatePhoneNumber, - [phoneCredential], - ), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), - ) as _i6.Future); + Invocation.method(#updatePhoneNumber, [phoneCredential]), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) + as _i6.Future); @override _i6.Future updateDisplayName(String? displayName) => (super.noSuchMethod( - Invocation.method( - #updateDisplayName, - [displayName], - ), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), - ) as _i6.Future); + Invocation.method(#updateDisplayName, [displayName]), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) + as _i6.Future); @override - _i6.Future updatePhotoURL(String? photoURL) => (super.noSuchMethod( - Invocation.method( - #updatePhotoURL, - [photoURL], - ), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), - ) as _i6.Future); + _i6.Future updatePhotoURL(String? photoURL) => + (super.noSuchMethod( + Invocation.method(#updatePhotoURL, [photoURL]), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) + as _i6.Future); @override - _i6.Future updateProfile({ - String? displayName, - String? photoURL, - }) => + _i6.Future updateProfile({String? displayName, String? photoURL}) => (super.noSuchMethod( - Invocation.method( - #updateProfile, - [], - { - #displayName: displayName, - #photoURL: photoURL, - }, - ), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), - ) as _i6.Future); + Invocation.method(#updateProfile, [], { + #displayName: displayName, + #photoURL: photoURL, + }), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) + as _i6.Future); @override _i6.Future verifyBeforeUpdateEmail( @@ -718,16 +574,14 @@ class MockUser extends _i1.Mock implements _i4.User { _i3.ActionCodeSettings? actionCodeSettings, ]) => (super.noSuchMethod( - Invocation.method( - #verifyBeforeUpdateEmail, - [ - newEmail, - actionCodeSettings, - ], - ), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), - ) as _i6.Future); + Invocation.method(#verifyBeforeUpdateEmail, [ + newEmail, + actionCodeSettings, + ]), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) + as _i6.Future); } /// A class which mocks [FirebaseAppCheck]. @@ -739,34 +593,34 @@ class MockFirebaseAppCheck extends _i1.Mock implements _i10.FirebaseAppCheck { } @override - _i5.FirebaseApp get app => (super.noSuchMethod( - Invocation.getter(#app), - returnValue: _FakeFirebaseApp_8( - this, - Invocation.getter(#app), - ), - ) as _i5.FirebaseApp); + _i5.FirebaseApp get app => + (super.noSuchMethod( + Invocation.getter(#app), + returnValue: _FakeFirebaseApp_8(this, Invocation.getter(#app)), + ) + as _i5.FirebaseApp); @override - _i6.Stream get onTokenChange => (super.noSuchMethod( - Invocation.getter(#onTokenChange), - returnValue: _i6.Stream.empty(), - ) as _i6.Stream); + _i6.Stream get onTokenChange => + (super.noSuchMethod( + Invocation.getter(#onTokenChange), + returnValue: _i6.Stream.empty(), + ) + as _i6.Stream); @override set app(_i5.FirebaseApp? value) => super.noSuchMethod( - Invocation.setter( - #app, - value, - ), - returnValueForMissingStub: null, - ); + Invocation.setter(#app, value), + returnValueForMissingStub: null, + ); @override - Map get pluginConstants => (super.noSuchMethod( - Invocation.getter(#pluginConstants), - returnValue: {}, - ) as Map); + Map get pluginConstants => + (super.noSuchMethod( + Invocation.getter(#pluginConstants), + returnValue: {}, + ) + as Map); @override _i6.Future activate({ @@ -782,56 +636,51 @@ class MockFirebaseAppCheck extends _i1.Mock implements _i10.FirebaseAppCheck { const _i11.WindowsDebugProvider(), }) => (super.noSuchMethod( - Invocation.method( - #activate, - [], - { - #webProvider: webProvider, - #providerWeb: providerWeb, - #androidProvider: androidProvider, - #appleProvider: appleProvider, - #providerAndroid: providerAndroid, - #providerApple: providerApple, - #providerWindows: providerWindows, - }, - ), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), - ) as _i6.Future); - - @override - _i6.Future getToken([bool? forceRefresh]) => (super.noSuchMethod( - Invocation.method( - #getToken, - [forceRefresh], - ), - returnValue: _i6.Future.value(), - ) as _i6.Future); + Invocation.method(#activate, [], { + #webProvider: webProvider, + #providerWeb: providerWeb, + #androidProvider: androidProvider, + #appleProvider: appleProvider, + #providerAndroid: providerAndroid, + #providerApple: providerApple, + #providerWindows: providerWindows, + }), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) + as _i6.Future); + + @override + _i6.Future getToken([bool? forceRefresh]) => + (super.noSuchMethod( + Invocation.method(#getToken, [forceRefresh]), + returnValue: _i6.Future.value(), + ) + as _i6.Future); @override _i6.Future setTokenAutoRefreshEnabled( - bool? isTokenAutoRefreshEnabled) => - (super.noSuchMethod( - Invocation.method( - #setTokenAutoRefreshEnabled, - [isTokenAutoRefreshEnabled], - ), - returnValue: _i6.Future.value(), - returnValueForMissingStub: _i6.Future.value(), - ) as _i6.Future); - - @override - _i6.Future getLimitedUseToken() => (super.noSuchMethod( - Invocation.method( - #getLimitedUseToken, - [], - ), - returnValue: _i6.Future.value(_i8.dummyValue( - this, - Invocation.method( - #getLimitedUseToken, - [], - ), - )), - ) as _i6.Future); + bool? isTokenAutoRefreshEnabled, + ) => + (super.noSuchMethod( + Invocation.method(#setTokenAutoRefreshEnabled, [ + isTokenAutoRefreshEnabled, + ]), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) + as _i6.Future); + + @override + _i6.Future getLimitedUseToken() => + (super.noSuchMethod( + Invocation.method(#getLimitedUseToken, []), + returnValue: _i6.Future.value( + _i8.dummyValue( + this, + Invocation.method(#getLimitedUseToken, []), + ), + ), + ) + as _i6.Future); } diff --git a/packages/firebase_data_connect/firebase_data_connect/test/src/network/websocket_transport_test.dart b/packages/firebase_data_connect/firebase_data_connect/test/src/network/websocket_transport_test.dart index afbbff322873..76c8ce12391c 100644 --- a/packages/firebase_data_connect/firebase_data_connect/test/src/network/websocket_transport_test.dart +++ b/packages/firebase_data_connect/firebase_data_connect/test/src/network/websocket_transport_test.dart @@ -46,15 +46,19 @@ void main() { when(mockUser1.uid).thenReturn('uid-1'); when(mockUser2.uid).thenReturn('uid-2'); when(mockAuth.currentUser).thenReturn(mockUser1); - when(mockAuth.idTokenChanges()) - .thenAnswer((_) => authChangesController.stream); + when( + mockAuth.idTokenChanges(), + ).thenAnswer((_) => authChangesController.stream); localHttpServer = await HttpServer.bind(InternetAddress.loopbackIPv4, 0); addTearDown(() => localHttpServer.close(force: true)); transport = WebSocketTransport( TransportOptions( - localHttpServer.address.host, localHttpServer.port, false), + localHttpServer.address.host, + localHttpServer.port, + false, + ), DataConnectOptions( 'testProject', 'testLocation', @@ -71,24 +75,25 @@ void main() { group('WebSocketTransport Idle Reconnection Guard', () { test( - 'should not schedule or perform any reconnect on auth user switch if there are no active subscriptions', - () async { - // Emit initial user (uid-1) - authChangesController.add(mockUser1); - await Future.delayed(Duration.zero); - - // Emit different user (uid-2) to trigger a user switch reconnect scenario - authChangesController.add(mockUser2); - await Future.delayed(Duration.zero); - - // Wait for longer than the initial reconnect delay (1000ms) - await Future.delayed(const Duration(milliseconds: 1500)); - - // Verify that the transport never attempted to refresh the token - // (which is the first step of a reconnect) since the client is idle. - verifyNever(mockUser2.getIdToken()); - expect(transport.isConnected, isFalse); - }); + 'should not schedule or perform any reconnect on auth user switch if there are no active subscriptions', + () async { + // Emit initial user (uid-1) + authChangesController.add(mockUser1); + await Future.delayed(Duration.zero); + + // Emit different user (uid-2) to trigger a user switch reconnect scenario + authChangesController.add(mockUser2); + await Future.delayed(Duration.zero); + + // Wait for longer than the initial reconnect delay (1000ms) + await Future.delayed(const Duration(milliseconds: 1500)); + + // Verify that the transport never attempted to refresh the token + // (which is the first step of a reconnect) since the client is idle. + verifyNever(mockUser2.getIdToken()); + expect(transport.isConnected, isFalse); + }, + ); }); group('WebSocketTransport URL Validation', () { diff --git a/packages/firebase_data_connect/firebase_data_connect/test/src/network/websocket_transport_test.mocks.dart b/packages/firebase_data_connect/firebase_data_connect/test/src/network/websocket_transport_test.mocks.dart index bdfabe96506d..0c3d8edd708a 100644 --- a/packages/firebase_data_connect/firebase_data_connect/test/src/network/websocket_transport_test.mocks.dart +++ b/packages/firebase_data_connect/firebase_data_connect/test/src/network/websocket_transport_test.mocks.dart @@ -45,97 +45,52 @@ import 'package:mockito/src/dummies.dart' as _i6; // ignore_for_file: invalid_use_of_internal_member class _FakeFirebaseApp_0 extends _i1.SmartFake implements _i2.FirebaseApp { - _FakeFirebaseApp_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeFirebaseApp_0(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeActionCodeInfo_1 extends _i1.SmartFake implements _i3.ActionCodeInfo { - _FakeActionCodeInfo_1( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeActionCodeInfo_1(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeUserCredential_2 extends _i1.SmartFake implements _i4.UserCredential { - _FakeUserCredential_2( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeUserCredential_2(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeConfirmationResult_3 extends _i1.SmartFake implements _i4.ConfirmationResult { - _FakeConfirmationResult_3( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeConfirmationResult_3(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakePasswordValidationStatus_4 extends _i1.SmartFake implements _i3.PasswordValidationStatus { - _FakePasswordValidationStatus_4( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakePasswordValidationStatus_4(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeUserMetadata_5 extends _i1.SmartFake implements _i3.UserMetadata { - _FakeUserMetadata_5( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeUserMetadata_5(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeMultiFactor_6 extends _i1.SmartFake implements _i4.MultiFactor { - _FakeMultiFactor_6( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeMultiFactor_6(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeIdTokenResult_7 extends _i1.SmartFake implements _i3.IdTokenResult { - _FakeIdTokenResult_7( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeIdTokenResult_7(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeUser_8 extends _i1.SmartFake implements _i4.User { - _FakeUser_8( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeUser_8(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } /// A class which mocks [FirebaseAuth]. @@ -147,46 +102,38 @@ class MockFirebaseAuth extends _i1.Mock implements _i4.FirebaseAuth { } @override - _i2.FirebaseApp get app => (super.noSuchMethod( - Invocation.getter(#app), - returnValue: _FakeFirebaseApp_0( - this, - Invocation.getter(#app), - ), - ) as _i2.FirebaseApp); + _i2.FirebaseApp get app => + (super.noSuchMethod( + Invocation.getter(#app), + returnValue: _FakeFirebaseApp_0(this, Invocation.getter(#app)), + ) + as _i2.FirebaseApp); @override set app(_i2.FirebaseApp? value) => super.noSuchMethod( - Invocation.setter( - #app, - value, - ), - returnValueForMissingStub: null, - ); + Invocation.setter(#app, value), + returnValueForMissingStub: null, + ); @override set tenantId(String? tenantId) => super.noSuchMethod( - Invocation.setter( - #tenantId, - tenantId, - ), - returnValueForMissingStub: null, - ); + Invocation.setter(#tenantId, tenantId), + returnValueForMissingStub: null, + ); @override set customAuthDomain(String? customAuthDomain) => super.noSuchMethod( - Invocation.setter( - #customAuthDomain, - customAuthDomain, - ), - returnValueForMissingStub: null, - ); + Invocation.setter(#customAuthDomain, customAuthDomain), + returnValueForMissingStub: null, + ); @override - Map get pluginConstants => (super.noSuchMethod( - Invocation.getter(#pluginConstants), - returnValue: {}, - ) as Map); + Map get pluginConstants => + (super.noSuchMethod( + Invocation.getter(#pluginConstants), + returnValue: {}, + ) + as Map); @override _i5.Future useAuthEmulator( @@ -195,43 +142,37 @@ class MockFirebaseAuth extends _i1.Mock implements _i4.FirebaseAuth { bool? automaticHostMapping = true, }) => (super.noSuchMethod( - Invocation.method( - #useAuthEmulator, - [ - host, - port, - ], - {#automaticHostMapping: automaticHostMapping}, - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); - - @override - _i5.Future applyActionCode(String? code) => (super.noSuchMethod( - Invocation.method( - #applyActionCode, - [code], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method( + #useAuthEmulator, + [host, port], + {#automaticHostMapping: automaticHostMapping}, + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); + + @override + _i5.Future applyActionCode(String? code) => + (super.noSuchMethod( + Invocation.method(#applyActionCode, [code]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future<_i3.ActionCodeInfo> checkActionCode(String? code) => (super.noSuchMethod( - Invocation.method( - #checkActionCode, - [code], - ), - returnValue: _i5.Future<_i3.ActionCodeInfo>.value(_FakeActionCodeInfo_1( - this, - Invocation.method( - #checkActionCode, - [code], - ), - )), - ) as _i5.Future<_i3.ActionCodeInfo>); + Invocation.method(#checkActionCode, [code]), + returnValue: _i5.Future<_i3.ActionCodeInfo>.value( + _FakeActionCodeInfo_1( + this, + Invocation.method(#checkActionCode, [code]), + ), + ), + ) + as _i5.Future<_i3.ActionCodeInfo>); @override _i5.Future confirmPasswordReset({ @@ -239,17 +180,14 @@ class MockFirebaseAuth extends _i1.Mock implements _i4.FirebaseAuth { required String? newPassword, }) => (super.noSuchMethod( - Invocation.method( - #confirmPasswordReset, - [], - { - #code: code, - #newPassword: newPassword, - }, - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#confirmPasswordReset, [], { + #code: code, + #newPassword: newPassword, + }), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future<_i4.UserCredential> createUserWithEmailAndPassword({ @@ -257,77 +195,66 @@ class MockFirebaseAuth extends _i1.Mock implements _i4.FirebaseAuth { required String? password, }) => (super.noSuchMethod( - Invocation.method( - #createUserWithEmailAndPassword, - [], - { - #email: email, - #password: password, - }, - ), - returnValue: _i5.Future<_i4.UserCredential>.value(_FakeUserCredential_2( - this, - Invocation.method( - #createUserWithEmailAndPassword, - [], - { + Invocation.method(#createUserWithEmailAndPassword, [], { #email: email, #password: password, - }, - ), - )), - ) as _i5.Future<_i4.UserCredential>); - - @override - _i5.Future<_i4.UserCredential> getRedirectResult() => (super.noSuchMethod( - Invocation.method( - #getRedirectResult, - [], - ), - returnValue: _i5.Future<_i4.UserCredential>.value(_FakeUserCredential_2( - this, - Invocation.method( - #getRedirectResult, - [], - ), - )), - ) as _i5.Future<_i4.UserCredential>); - - @override - bool isSignInWithEmailLink(String? emailLink) => (super.noSuchMethod( - Invocation.method( - #isSignInWithEmailLink, - [emailLink], - ), - returnValue: false, - ) as bool); - - @override - _i5.Stream<_i4.User?> authStateChanges() => (super.noSuchMethod( - Invocation.method( - #authStateChanges, - [], - ), - returnValue: _i5.Stream<_i4.User?>.empty(), - ) as _i5.Stream<_i4.User?>); - - @override - _i5.Stream<_i4.User?> idTokenChanges() => (super.noSuchMethod( - Invocation.method( - #idTokenChanges, - [], - ), - returnValue: _i5.Stream<_i4.User?>.empty(), - ) as _i5.Stream<_i4.User?>); - - @override - _i5.Stream<_i4.User?> userChanges() => (super.noSuchMethod( - Invocation.method( - #userChanges, - [], - ), - returnValue: _i5.Stream<_i4.User?>.empty(), - ) as _i5.Stream<_i4.User?>); + }), + returnValue: _i5.Future<_i4.UserCredential>.value( + _FakeUserCredential_2( + this, + Invocation.method(#createUserWithEmailAndPassword, [], { + #email: email, + #password: password, + }), + ), + ), + ) + as _i5.Future<_i4.UserCredential>); + + @override + _i5.Future<_i4.UserCredential> getRedirectResult() => + (super.noSuchMethod( + Invocation.method(#getRedirectResult, []), + returnValue: _i5.Future<_i4.UserCredential>.value( + _FakeUserCredential_2( + this, + Invocation.method(#getRedirectResult, []), + ), + ), + ) + as _i5.Future<_i4.UserCredential>); + + @override + bool isSignInWithEmailLink(String? emailLink) => + (super.noSuchMethod( + Invocation.method(#isSignInWithEmailLink, [emailLink]), + returnValue: false, + ) + as bool); + + @override + _i5.Stream<_i4.User?> authStateChanges() => + (super.noSuchMethod( + Invocation.method(#authStateChanges, []), + returnValue: _i5.Stream<_i4.User?>.empty(), + ) + as _i5.Stream<_i4.User?>); + + @override + _i5.Stream<_i4.User?> idTokenChanges() => + (super.noSuchMethod( + Invocation.method(#idTokenChanges, []), + returnValue: _i5.Stream<_i4.User?>.empty(), + ) + as _i5.Stream<_i4.User?>); + + @override + _i5.Stream<_i4.User?> userChanges() => + (super.noSuchMethod( + Invocation.method(#userChanges, []), + returnValue: _i5.Stream<_i4.User?>.empty(), + ) + as _i5.Stream<_i4.User?>); @override _i5.Future sendPasswordResetEmail({ @@ -335,17 +262,14 @@ class MockFirebaseAuth extends _i1.Mock implements _i4.FirebaseAuth { _i3.ActionCodeSettings? actionCodeSettings, }) => (super.noSuchMethod( - Invocation.method( - #sendPasswordResetEmail, - [], - { - #email: email, - #actionCodeSettings: actionCodeSettings, - }, - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#sendPasswordResetEmail, [], { + #email: email, + #actionCodeSettings: actionCodeSettings, + }), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future sendSignInLinkToEmail({ @@ -353,27 +277,23 @@ class MockFirebaseAuth extends _i1.Mock implements _i4.FirebaseAuth { required _i3.ActionCodeSettings? actionCodeSettings, }) => (super.noSuchMethod( - Invocation.method( - #sendSignInLinkToEmail, - [], - { - #email: email, - #actionCodeSettings: actionCodeSettings, - }, - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); - - @override - _i5.Future setLanguageCode(String? languageCode) => (super.noSuchMethod( - Invocation.method( - #setLanguageCode, - [languageCode], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#sendSignInLinkToEmail, [], { + #email: email, + #actionCodeSettings: actionCodeSettings, + }), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); + + @override + _i5.Future setLanguageCode(String? languageCode) => + (super.noSuchMethod( + Invocation.method(#setLanguageCode, [languageCode]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future setSettings({ @@ -385,81 +305,69 @@ class MockFirebaseAuth extends _i1.Mock implements _i4.FirebaseAuth { bool? forceRecaptchaFlow, }) => (super.noSuchMethod( - Invocation.method( - #setSettings, - [], - { - #appVerificationDisabledForTesting: - appVerificationDisabledForTesting, - #userAccessGroup: userAccessGroup, - #migrateCurrentUser: migrateCurrentUser, - #phoneNumber: phoneNumber, - #smsCode: smsCode, - #forceRecaptchaFlow: forceRecaptchaFlow, - }, - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#setSettings, [], { + #appVerificationDisabledForTesting: + appVerificationDisabledForTesting, + #userAccessGroup: userAccessGroup, + #migrateCurrentUser: migrateCurrentUser, + #phoneNumber: phoneNumber, + #smsCode: smsCode, + #forceRecaptchaFlow: forceRecaptchaFlow, + }), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future setPersistence(_i3.Persistence? persistence) => (super.noSuchMethod( - Invocation.method( - #setPersistence, - [persistence], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); - - @override - _i5.Future<_i4.UserCredential> signInAnonymously() => (super.noSuchMethod( - Invocation.method( - #signInAnonymously, - [], - ), - returnValue: _i5.Future<_i4.UserCredential>.value(_FakeUserCredential_2( - this, - Invocation.method( - #signInAnonymously, - [], - ), - )), - ) as _i5.Future<_i4.UserCredential>); + Invocation.method(#setPersistence, [persistence]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); + + @override + _i5.Future<_i4.UserCredential> signInAnonymously() => + (super.noSuchMethod( + Invocation.method(#signInAnonymously, []), + returnValue: _i5.Future<_i4.UserCredential>.value( + _FakeUserCredential_2( + this, + Invocation.method(#signInAnonymously, []), + ), + ), + ) + as _i5.Future<_i4.UserCredential>); @override _i5.Future<_i4.UserCredential> signInWithCredential( - _i3.AuthCredential? credential) => - (super.noSuchMethod( - Invocation.method( - #signInWithCredential, - [credential], - ), - returnValue: _i5.Future<_i4.UserCredential>.value(_FakeUserCredential_2( - this, - Invocation.method( - #signInWithCredential, - [credential], - ), - )), - ) as _i5.Future<_i4.UserCredential>); + _i3.AuthCredential? credential, + ) => + (super.noSuchMethod( + Invocation.method(#signInWithCredential, [credential]), + returnValue: _i5.Future<_i4.UserCredential>.value( + _FakeUserCredential_2( + this, + Invocation.method(#signInWithCredential, [credential]), + ), + ), + ) + as _i5.Future<_i4.UserCredential>); @override _i5.Future<_i4.UserCredential> signInWithCustomToken(String? token) => (super.noSuchMethod( - Invocation.method( - #signInWithCustomToken, - [token], - ), - returnValue: _i5.Future<_i4.UserCredential>.value(_FakeUserCredential_2( - this, - Invocation.method( - #signInWithCustomToken, - [token], - ), - )), - ) as _i5.Future<_i4.UserCredential>); + Invocation.method(#signInWithCustomToken, [token]), + returnValue: _i5.Future<_i4.UserCredential>.value( + _FakeUserCredential_2( + this, + Invocation.method(#signInWithCustomToken, [token]), + ), + ), + ) + as _i5.Future<_i4.UserCredential>); @override _i5.Future<_i4.UserCredential> signInWithEmailAndPassword({ @@ -467,26 +375,21 @@ class MockFirebaseAuth extends _i1.Mock implements _i4.FirebaseAuth { required String? password, }) => (super.noSuchMethod( - Invocation.method( - #signInWithEmailAndPassword, - [], - { - #email: email, - #password: password, - }, - ), - returnValue: _i5.Future<_i4.UserCredential>.value(_FakeUserCredential_2( - this, - Invocation.method( - #signInWithEmailAndPassword, - [], - { + Invocation.method(#signInWithEmailAndPassword, [], { #email: email, #password: password, - }, - ), - )), - ) as _i5.Future<_i4.UserCredential>); + }), + returnValue: _i5.Future<_i4.UserCredential>.value( + _FakeUserCredential_2( + this, + Invocation.method(#signInWithEmailAndPassword, [], { + #email: email, + #password: password, + }), + ), + ), + ) + as _i5.Future<_i4.UserCredential>); @override _i5.Future<_i4.UserCredential> signInWithEmailLink({ @@ -494,43 +397,36 @@ class MockFirebaseAuth extends _i1.Mock implements _i4.FirebaseAuth { required String? emailLink, }) => (super.noSuchMethod( - Invocation.method( - #signInWithEmailLink, - [], - { - #email: email, - #emailLink: emailLink, - }, - ), - returnValue: _i5.Future<_i4.UserCredential>.value(_FakeUserCredential_2( - this, - Invocation.method( - #signInWithEmailLink, - [], - { + Invocation.method(#signInWithEmailLink, [], { #email: email, #emailLink: emailLink, - }, - ), - )), - ) as _i5.Future<_i4.UserCredential>); + }), + returnValue: _i5.Future<_i4.UserCredential>.value( + _FakeUserCredential_2( + this, + Invocation.method(#signInWithEmailLink, [], { + #email: email, + #emailLink: emailLink, + }), + ), + ), + ) + as _i5.Future<_i4.UserCredential>); @override _i5.Future<_i4.UserCredential> signInWithProvider( - _i3.AuthProvider? provider) => - (super.noSuchMethod( - Invocation.method( - #signInWithProvider, - [provider], - ), - returnValue: _i5.Future<_i4.UserCredential>.value(_FakeUserCredential_2( - this, - Invocation.method( - #signInWithProvider, - [provider], - ), - )), - ) as _i5.Future<_i4.UserCredential>); + _i3.AuthProvider? provider, + ) => + (super.noSuchMethod( + Invocation.method(#signInWithProvider, [provider]), + returnValue: _i5.Future<_i4.UserCredential>.value( + _FakeUserCredential_2( + this, + Invocation.method(#signInWithProvider, [provider]), + ), + ), + ) + as _i5.Future<_i4.UserCredential>); @override _i5.Future<_i4.ConfirmationResult> signInWithPhoneNumber( @@ -538,68 +434,53 @@ class MockFirebaseAuth extends _i1.Mock implements _i4.FirebaseAuth { _i4.RecaptchaVerifier? verifier, ]) => (super.noSuchMethod( - Invocation.method( - #signInWithPhoneNumber, - [ - phoneNumber, - verifier, - ], - ), - returnValue: - _i5.Future<_i4.ConfirmationResult>.value(_FakeConfirmationResult_3( - this, - Invocation.method( - #signInWithPhoneNumber, - [ - phoneNumber, - verifier, - ], - ), - )), - ) as _i5.Future<_i4.ConfirmationResult>); + Invocation.method(#signInWithPhoneNumber, [phoneNumber, verifier]), + returnValue: _i5.Future<_i4.ConfirmationResult>.value( + _FakeConfirmationResult_3( + this, + Invocation.method(#signInWithPhoneNumber, [ + phoneNumber, + verifier, + ]), + ), + ), + ) + as _i5.Future<_i4.ConfirmationResult>); @override _i5.Future<_i4.UserCredential> signInWithPopup(_i3.AuthProvider? provider) => (super.noSuchMethod( - Invocation.method( - #signInWithPopup, - [provider], - ), - returnValue: _i5.Future<_i4.UserCredential>.value(_FakeUserCredential_2( - this, - Invocation.method( - #signInWithPopup, - [provider], - ), - )), - ) as _i5.Future<_i4.UserCredential>); + Invocation.method(#signInWithPopup, [provider]), + returnValue: _i5.Future<_i4.UserCredential>.value( + _FakeUserCredential_2( + this, + Invocation.method(#signInWithPopup, [provider]), + ), + ), + ) + as _i5.Future<_i4.UserCredential>); @override _i5.Future signInWithRedirect(_i3.AuthProvider? provider) => (super.noSuchMethod( - Invocation.method( - #signInWithRedirect, - [provider], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#signInWithRedirect, [provider]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future verifyPasswordResetCode(String? code) => (super.noSuchMethod( - Invocation.method( - #verifyPasswordResetCode, - [code], - ), - returnValue: _i5.Future.value(_i6.dummyValue( - this, - Invocation.method( - #verifyPasswordResetCode, - [code], - ), - )), - ) as _i5.Future); + Invocation.method(#verifyPasswordResetCode, [code]), + returnValue: _i5.Future.value( + _i6.dummyValue( + this, + Invocation.method(#verifyPasswordResetCode, [code]), + ), + ), + ) + as _i5.Future); @override _i5.Future verifyPhoneNumber({ @@ -615,68 +496,62 @@ class MockFirebaseAuth extends _i1.Mock implements _i4.FirebaseAuth { _i3.MultiFactorSession? multiFactorSession, }) => (super.noSuchMethod( - Invocation.method( - #verifyPhoneNumber, - [], - { - #phoneNumber: phoneNumber, - #multiFactorInfo: multiFactorInfo, - #verificationCompleted: verificationCompleted, - #verificationFailed: verificationFailed, - #codeSent: codeSent, - #codeAutoRetrievalTimeout: codeAutoRetrievalTimeout, - #autoRetrievedSmsCodeForTesting: autoRetrievedSmsCodeForTesting, - #timeout: timeout, - #forceResendingToken: forceResendingToken, - #multiFactorSession: multiFactorSession, - }, - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#verifyPhoneNumber, [], { + #phoneNumber: phoneNumber, + #multiFactorInfo: multiFactorInfo, + #verificationCompleted: verificationCompleted, + #verificationFailed: verificationFailed, + #codeSent: codeSent, + #codeAutoRetrievalTimeout: codeAutoRetrievalTimeout, + #autoRetrievedSmsCodeForTesting: autoRetrievedSmsCodeForTesting, + #timeout: timeout, + #forceResendingToken: forceResendingToken, + #multiFactorSession: multiFactorSession, + }), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future revokeTokenWithAuthorizationCode( - String? authorizationCode) => + String? authorizationCode, + ) => (super.noSuchMethod( - Invocation.method( - #revokeTokenWithAuthorizationCode, - [authorizationCode], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#revokeTokenWithAuthorizationCode, [ + authorizationCode, + ]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future revokeAccessToken(String? accessToken) => (super.noSuchMethod( - Invocation.method( - #revokeAccessToken, - [accessToken], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#revokeAccessToken, [accessToken]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override - _i5.Future signOut() => (super.noSuchMethod( - Invocation.method( - #signOut, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + _i5.Future signOut() => + (super.noSuchMethod( + Invocation.method(#signOut, []), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override - _i5.Future initializeRecaptchaConfig() => (super.noSuchMethod( - Invocation.method( - #initializeRecaptchaConfig, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + _i5.Future initializeRecaptchaConfig() => + (super.noSuchMethod( + Invocation.method(#initializeRecaptchaConfig, []), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future<_i3.PasswordValidationStatus> validatePassword( @@ -684,25 +559,15 @@ class MockFirebaseAuth extends _i1.Mock implements _i4.FirebaseAuth { String? password, ) => (super.noSuchMethod( - Invocation.method( - #validatePassword, - [ - auth, - password, - ], - ), - returnValue: _i5.Future<_i3.PasswordValidationStatus>.value( - _FakePasswordValidationStatus_4( - this, - Invocation.method( - #validatePassword, - [ - auth, - password, - ], - ), - )), - ) as _i5.Future<_i3.PasswordValidationStatus>); + Invocation.method(#validatePassword, [auth, password]), + returnValue: _i5.Future<_i3.PasswordValidationStatus>.value( + _FakePasswordValidationStatus_4( + this, + Invocation.method(#validatePassword, [auth, password]), + ), + ), + ) + as _i5.Future<_i3.PasswordValidationStatus>); } /// A class which mocks [User]. @@ -714,191 +579,173 @@ class MockUser extends _i1.Mock implements _i4.User { } @override - bool get emailVerified => (super.noSuchMethod( - Invocation.getter(#emailVerified), - returnValue: false, - ) as bool); + bool get emailVerified => + (super.noSuchMethod(Invocation.getter(#emailVerified), returnValue: false) + as bool); @override - bool get isAnonymous => (super.noSuchMethod( - Invocation.getter(#isAnonymous), - returnValue: false, - ) as bool); + bool get isAnonymous => + (super.noSuchMethod(Invocation.getter(#isAnonymous), returnValue: false) + as bool); @override - _i3.UserMetadata get metadata => (super.noSuchMethod( - Invocation.getter(#metadata), - returnValue: _FakeUserMetadata_5( - this, - Invocation.getter(#metadata), - ), - ) as _i3.UserMetadata); + _i3.UserMetadata get metadata => + (super.noSuchMethod( + Invocation.getter(#metadata), + returnValue: _FakeUserMetadata_5( + this, + Invocation.getter(#metadata), + ), + ) + as _i3.UserMetadata); @override - List<_i3.UserInfo> get providerData => (super.noSuchMethod( - Invocation.getter(#providerData), - returnValue: <_i3.UserInfo>[], - ) as List<_i3.UserInfo>); + List<_i3.UserInfo> get providerData => + (super.noSuchMethod( + Invocation.getter(#providerData), + returnValue: <_i3.UserInfo>[], + ) + as List<_i3.UserInfo>); @override - String get uid => (super.noSuchMethod( - Invocation.getter(#uid), - returnValue: _i6.dummyValue( - this, - Invocation.getter(#uid), - ), - ) as String); + String get uid => + (super.noSuchMethod( + Invocation.getter(#uid), + returnValue: _i6.dummyValue(this, Invocation.getter(#uid)), + ) + as String); @override - _i4.MultiFactor get multiFactor => (super.noSuchMethod( - Invocation.getter(#multiFactor), - returnValue: _FakeMultiFactor_6( - this, - Invocation.getter(#multiFactor), - ), - ) as _i4.MultiFactor); + _i4.MultiFactor get multiFactor => + (super.noSuchMethod( + Invocation.getter(#multiFactor), + returnValue: _FakeMultiFactor_6( + this, + Invocation.getter(#multiFactor), + ), + ) + as _i4.MultiFactor); @override - _i5.Future delete() => (super.noSuchMethod( - Invocation.method( - #delete, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + _i5.Future delete() => + (super.noSuchMethod( + Invocation.method(#delete, []), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future getIdToken([bool? forceRefresh = false]) => (super.noSuchMethod( - Invocation.method( - #getIdToken, - [forceRefresh], - ), - returnValue: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#getIdToken, [forceRefresh]), + returnValue: _i5.Future.value(), + ) + as _i5.Future); @override - _i5.Future<_i3.IdTokenResult> getIdTokenResult( - [bool? forceRefresh = false]) => + _i5.Future<_i3.IdTokenResult> getIdTokenResult([ + bool? forceRefresh = false, + ]) => (super.noSuchMethod( - Invocation.method( - #getIdTokenResult, - [forceRefresh], - ), - returnValue: _i5.Future<_i3.IdTokenResult>.value(_FakeIdTokenResult_7( - this, - Invocation.method( - #getIdTokenResult, - [forceRefresh], - ), - )), - ) as _i5.Future<_i3.IdTokenResult>); + Invocation.method(#getIdTokenResult, [forceRefresh]), + returnValue: _i5.Future<_i3.IdTokenResult>.value( + _FakeIdTokenResult_7( + this, + Invocation.method(#getIdTokenResult, [forceRefresh]), + ), + ), + ) + as _i5.Future<_i3.IdTokenResult>); @override _i5.Future<_i4.UserCredential> linkWithCredential( - _i3.AuthCredential? credential) => - (super.noSuchMethod( - Invocation.method( - #linkWithCredential, - [credential], - ), - returnValue: _i5.Future<_i4.UserCredential>.value(_FakeUserCredential_2( - this, - Invocation.method( - #linkWithCredential, - [credential], - ), - )), - ) as _i5.Future<_i4.UserCredential>); + _i3.AuthCredential? credential, + ) => + (super.noSuchMethod( + Invocation.method(#linkWithCredential, [credential]), + returnValue: _i5.Future<_i4.UserCredential>.value( + _FakeUserCredential_2( + this, + Invocation.method(#linkWithCredential, [credential]), + ), + ), + ) + as _i5.Future<_i4.UserCredential>); @override _i5.Future<_i4.UserCredential> linkWithProvider(_i3.AuthProvider? provider) => (super.noSuchMethod( - Invocation.method( - #linkWithProvider, - [provider], - ), - returnValue: _i5.Future<_i4.UserCredential>.value(_FakeUserCredential_2( - this, - Invocation.method( - #linkWithProvider, - [provider], - ), - )), - ) as _i5.Future<_i4.UserCredential>); + Invocation.method(#linkWithProvider, [provider]), + returnValue: _i5.Future<_i4.UserCredential>.value( + _FakeUserCredential_2( + this, + Invocation.method(#linkWithProvider, [provider]), + ), + ), + ) + as _i5.Future<_i4.UserCredential>); @override _i5.Future<_i4.UserCredential> reauthenticateWithProvider( - _i3.AuthProvider? provider) => - (super.noSuchMethod( - Invocation.method( - #reauthenticateWithProvider, - [provider], - ), - returnValue: _i5.Future<_i4.UserCredential>.value(_FakeUserCredential_2( - this, - Invocation.method( - #reauthenticateWithProvider, - [provider], - ), - )), - ) as _i5.Future<_i4.UserCredential>); + _i3.AuthProvider? provider, + ) => + (super.noSuchMethod( + Invocation.method(#reauthenticateWithProvider, [provider]), + returnValue: _i5.Future<_i4.UserCredential>.value( + _FakeUserCredential_2( + this, + Invocation.method(#reauthenticateWithProvider, [provider]), + ), + ), + ) + as _i5.Future<_i4.UserCredential>); @override _i5.Future<_i4.UserCredential> reauthenticateWithPopup( - _i3.AuthProvider? provider) => - (super.noSuchMethod( - Invocation.method( - #reauthenticateWithPopup, - [provider], - ), - returnValue: _i5.Future<_i4.UserCredential>.value(_FakeUserCredential_2( - this, - Invocation.method( - #reauthenticateWithPopup, - [provider], - ), - )), - ) as _i5.Future<_i4.UserCredential>); + _i3.AuthProvider? provider, + ) => + (super.noSuchMethod( + Invocation.method(#reauthenticateWithPopup, [provider]), + returnValue: _i5.Future<_i4.UserCredential>.value( + _FakeUserCredential_2( + this, + Invocation.method(#reauthenticateWithPopup, [provider]), + ), + ), + ) + as _i5.Future<_i4.UserCredential>); @override _i5.Future reauthenticateWithRedirect(_i3.AuthProvider? provider) => (super.noSuchMethod( - Invocation.method( - #reauthenticateWithRedirect, - [provider], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#reauthenticateWithRedirect, [provider]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future<_i4.UserCredential> linkWithPopup(_i3.AuthProvider? provider) => (super.noSuchMethod( - Invocation.method( - #linkWithPopup, - [provider], - ), - returnValue: _i5.Future<_i4.UserCredential>.value(_FakeUserCredential_2( - this, - Invocation.method( - #linkWithPopup, - [provider], - ), - )), - ) as _i5.Future<_i4.UserCredential>); + Invocation.method(#linkWithPopup, [provider]), + returnValue: _i5.Future<_i4.UserCredential>.value( + _FakeUserCredential_2( + this, + Invocation.method(#linkWithPopup, [provider]), + ), + ), + ) + as _i5.Future<_i4.UserCredential>); @override _i5.Future linkWithRedirect(_i3.AuthProvider? provider) => (super.noSuchMethod( - Invocation.method( - #linkWithRedirect, - [provider], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#linkWithRedirect, [provider]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future<_i4.ConfirmationResult> linkWithPhoneNumber( @@ -906,140 +753,113 @@ class MockUser extends _i1.Mock implements _i4.User { _i4.RecaptchaVerifier? verifier, ]) => (super.noSuchMethod( - Invocation.method( - #linkWithPhoneNumber, - [ - phoneNumber, - verifier, - ], - ), - returnValue: - _i5.Future<_i4.ConfirmationResult>.value(_FakeConfirmationResult_3( - this, - Invocation.method( - #linkWithPhoneNumber, - [ - phoneNumber, - verifier, - ], - ), - )), - ) as _i5.Future<_i4.ConfirmationResult>); + Invocation.method(#linkWithPhoneNumber, [phoneNumber, verifier]), + returnValue: _i5.Future<_i4.ConfirmationResult>.value( + _FakeConfirmationResult_3( + this, + Invocation.method(#linkWithPhoneNumber, [ + phoneNumber, + verifier, + ]), + ), + ), + ) + as _i5.Future<_i4.ConfirmationResult>); @override _i5.Future<_i4.UserCredential> reauthenticateWithCredential( - _i3.AuthCredential? credential) => - (super.noSuchMethod( - Invocation.method( - #reauthenticateWithCredential, - [credential], - ), - returnValue: _i5.Future<_i4.UserCredential>.value(_FakeUserCredential_2( - this, - Invocation.method( - #reauthenticateWithCredential, - [credential], - ), - )), - ) as _i5.Future<_i4.UserCredential>); - - @override - _i5.Future reload() => (super.noSuchMethod( - Invocation.method( - #reload, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); - - @override - _i5.Future sendEmailVerification( - [_i3.ActionCodeSettings? actionCodeSettings]) => - (super.noSuchMethod( - Invocation.method( - #sendEmailVerification, - [actionCodeSettings], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); - - @override - _i5.Future<_i4.User> unlink(String? providerId) => (super.noSuchMethod( - Invocation.method( - #unlink, - [providerId], - ), - returnValue: _i5.Future<_i4.User>.value(_FakeUser_8( - this, - Invocation.method( - #unlink, - [providerId], - ), - )), - ) as _i5.Future<_i4.User>); - - @override - _i5.Future updatePassword(String? newPassword) => (super.noSuchMethod( - Invocation.method( - #updatePassword, - [newPassword], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + _i3.AuthCredential? credential, + ) => + (super.noSuchMethod( + Invocation.method(#reauthenticateWithCredential, [credential]), + returnValue: _i5.Future<_i4.UserCredential>.value( + _FakeUserCredential_2( + this, + Invocation.method(#reauthenticateWithCredential, [credential]), + ), + ), + ) + as _i5.Future<_i4.UserCredential>); + + @override + _i5.Future reload() => + (super.noSuchMethod( + Invocation.method(#reload, []), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); + + @override + _i5.Future sendEmailVerification([ + _i3.ActionCodeSettings? actionCodeSettings, + ]) => + (super.noSuchMethod( + Invocation.method(#sendEmailVerification, [actionCodeSettings]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); + + @override + _i5.Future<_i4.User> unlink(String? providerId) => + (super.noSuchMethod( + Invocation.method(#unlink, [providerId]), + returnValue: _i5.Future<_i4.User>.value( + _FakeUser_8(this, Invocation.method(#unlink, [providerId])), + ), + ) + as _i5.Future<_i4.User>); + + @override + _i5.Future updatePassword(String? newPassword) => + (super.noSuchMethod( + Invocation.method(#updatePassword, [newPassword]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future updatePhoneNumber( - _i3.PhoneAuthCredential? phoneCredential) => + _i3.PhoneAuthCredential? phoneCredential, + ) => (super.noSuchMethod( - Invocation.method( - #updatePhoneNumber, - [phoneCredential], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#updatePhoneNumber, [phoneCredential]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future updateDisplayName(String? displayName) => (super.noSuchMethod( - Invocation.method( - #updateDisplayName, - [displayName], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#updateDisplayName, [displayName]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override - _i5.Future updatePhotoURL(String? photoURL) => (super.noSuchMethod( - Invocation.method( - #updatePhotoURL, - [photoURL], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + _i5.Future updatePhotoURL(String? photoURL) => + (super.noSuchMethod( + Invocation.method(#updatePhotoURL, [photoURL]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override - _i5.Future updateProfile({ - String? displayName, - String? photoURL, - }) => + _i5.Future updateProfile({String? displayName, String? photoURL}) => (super.noSuchMethod( - Invocation.method( - #updateProfile, - [], - { - #displayName: displayName, - #photoURL: photoURL, - }, - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#updateProfile, [], { + #displayName: displayName, + #photoURL: photoURL, + }), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future verifyBeforeUpdateEmail( @@ -1047,16 +867,14 @@ class MockUser extends _i1.Mock implements _i4.User { _i3.ActionCodeSettings? actionCodeSettings, ]) => (super.noSuchMethod( - Invocation.method( - #verifyBeforeUpdateEmail, - [ - newEmail, - actionCodeSettings, - ], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#verifyBeforeUpdateEmail, [ + newEmail, + actionCodeSettings, + ]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); } /// A class which mocks [FirebaseAppCheck]. @@ -1068,34 +886,34 @@ class MockFirebaseAppCheck extends _i1.Mock implements _i7.FirebaseAppCheck { } @override - _i2.FirebaseApp get app => (super.noSuchMethod( - Invocation.getter(#app), - returnValue: _FakeFirebaseApp_0( - this, - Invocation.getter(#app), - ), - ) as _i2.FirebaseApp); + _i2.FirebaseApp get app => + (super.noSuchMethod( + Invocation.getter(#app), + returnValue: _FakeFirebaseApp_0(this, Invocation.getter(#app)), + ) + as _i2.FirebaseApp); @override - _i5.Stream get onTokenChange => (super.noSuchMethod( - Invocation.getter(#onTokenChange), - returnValue: _i5.Stream.empty(), - ) as _i5.Stream); + _i5.Stream get onTokenChange => + (super.noSuchMethod( + Invocation.getter(#onTokenChange), + returnValue: _i5.Stream.empty(), + ) + as _i5.Stream); @override set app(_i2.FirebaseApp? value) => super.noSuchMethod( - Invocation.setter( - #app, - value, - ), - returnValueForMissingStub: null, - ); + Invocation.setter(#app, value), + returnValueForMissingStub: null, + ); @override - Map get pluginConstants => (super.noSuchMethod( - Invocation.getter(#pluginConstants), - returnValue: {}, - ) as Map); + Map get pluginConstants => + (super.noSuchMethod( + Invocation.getter(#pluginConstants), + returnValue: {}, + ) + as Map); @override _i5.Future activate({ @@ -1111,56 +929,51 @@ class MockFirebaseAppCheck extends _i1.Mock implements _i7.FirebaseAppCheck { const _i8.WindowsDebugProvider(), }) => (super.noSuchMethod( - Invocation.method( - #activate, - [], - { - #webProvider: webProvider, - #providerWeb: providerWeb, - #androidProvider: androidProvider, - #appleProvider: appleProvider, - #providerAndroid: providerAndroid, - #providerApple: providerApple, - #providerWindows: providerWindows, - }, - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); - - @override - _i5.Future getToken([bool? forceRefresh]) => (super.noSuchMethod( - Invocation.method( - #getToken, - [forceRefresh], - ), - returnValue: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#activate, [], { + #webProvider: webProvider, + #providerWeb: providerWeb, + #androidProvider: androidProvider, + #appleProvider: appleProvider, + #providerAndroid: providerAndroid, + #providerApple: providerApple, + #providerWindows: providerWindows, + }), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); + + @override + _i5.Future getToken([bool? forceRefresh]) => + (super.noSuchMethod( + Invocation.method(#getToken, [forceRefresh]), + returnValue: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future setTokenAutoRefreshEnabled( - bool? isTokenAutoRefreshEnabled) => - (super.noSuchMethod( - Invocation.method( - #setTokenAutoRefreshEnabled, - [isTokenAutoRefreshEnabled], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); - - @override - _i5.Future getLimitedUseToken() => (super.noSuchMethod( - Invocation.method( - #getLimitedUseToken, - [], - ), - returnValue: _i5.Future.value(_i6.dummyValue( - this, - Invocation.method( - #getLimitedUseToken, - [], - ), - )), - ) as _i5.Future); + bool? isTokenAutoRefreshEnabled, + ) => + (super.noSuchMethod( + Invocation.method(#setTokenAutoRefreshEnabled, [ + isTokenAutoRefreshEnabled, + ]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); + + @override + _i5.Future getLimitedUseToken() => + (super.noSuchMethod( + Invocation.method(#getLimitedUseToken, []), + returnValue: _i5.Future.value( + _i6.dummyValue( + this, + Invocation.method(#getLimitedUseToken, []), + ), + ), + ) + as _i5.Future); } diff --git a/packages/firebase_data_connect/firebase_data_connect/test/src/optional_test.dart b/packages/firebase_data_connect/firebase_data_connect/test/src/optional_test.dart index d12e97ad25db..c17ef630b406 100644 --- a/packages/firebase_data_connect/firebase_data_connect/test/src/optional_test.dart +++ b/packages/firebase_data_connect/firebase_data_connect/test/src/optional_test.dart @@ -92,11 +92,15 @@ void main() { expect(nativeFromJson('42000000000000'), equals(42000000000000)); }); - test('nativeFromJson throws UnsupportedError for bigint’s too big for int', - () { - expect(() => nativeFromJson('42000000000000000000'), - throwsUnsupportedError); - }); + test( + 'nativeFromJson throws UnsupportedError for bigint’s too big for int', + () { + expect( + () => nativeFromJson('42000000000000000000'), + throwsUnsupportedError, + ); + }, + ); test('nativeToJson correctly serializes null primitive types', () { Optional intValue = Optional(nativeFromJson, nativeToJson); @@ -108,13 +112,15 @@ void main() { }); // Since protobuf doesn't distinguish between int and double, we need to do the parsing ourselves - test('nativeFromJson correctly matches int to int and double to double', - () { - double expectedDouble = 42; - int expectedInt = 42; - expect(nativeFromJson(42), equals(expectedDouble)); - expect(nativeFromJson(expectedDouble), equals(expectedInt)); - }); + test( + 'nativeFromJson correctly matches int to int and double to double', + () { + double expectedDouble = 42; + int expectedInt = 42; + expect(nativeFromJson(42), equals(expectedDouble)); + expect(nativeFromJson(expectedDouble), equals(expectedInt)); + }, + ); test('nativeFromJson correctly deserializes DateTime strings', () { expect( nativeFromJson('2024-01-01'), diff --git a/packages/firebase_data_connect/firebase_data_connect/test/src/timestamp_test.dart b/packages/firebase_data_connect/firebase_data_connect/test/src/timestamp_test.dart index 46d104bca462..292e6fa59ef9 100644 --- a/packages/firebase_data_connect/firebase_data_connect/test/src/timestamp_test.dart +++ b/packages/firebase_data_connect/firebase_data_connect/test/src/timestamp_test.dart @@ -27,12 +27,14 @@ void main() { expect(() => Timestamp.fromJson('invalid-date'), throwsException); }); - test('fromJson correctly parses date with nanoseconds and UTC (Z) format', - () { - final timestamp = Timestamp.fromJson('1970-01-11T00:00:00.123456789Z'); - expect(timestamp.seconds, 864000); - expect(timestamp.nanoseconds, 123456789); - }); + test( + 'fromJson correctly parses date with nanoseconds and UTC (Z) format', + () { + final timestamp = Timestamp.fromJson('1970-01-11T00:00:00.123456789Z'); + expect(timestamp.seconds, 864000); + expect(timestamp.nanoseconds, 123456789); + }, + ); test('fromJson correctly parses date without nanoseconds', () { final timestamp = Timestamp.fromJson('1970-01-11T00:00:00Z'); @@ -62,12 +64,14 @@ void main() { expect(json, '1970-01-11T00:00:00.123456789Z'); }); - test('toJson correctly serializes to ISO8601 string without nanoseconds', - () { - final timestamp = Timestamp(0, 864000); // No nanoseconds - final json = timestamp.toJson(); - expect(json, '1970-01-11T00:00:00.000Z'); - }); + test( + 'toJson correctly serializes to ISO8601 string without nanoseconds', + () { + final timestamp = Timestamp(0, 864000); // No nanoseconds + final json = timestamp.toJson(); + expect(json, '1970-01-11T00:00:00.000Z'); + }, + ); test('toDateTime correctly converts to DateTime object', () { final timestamp = Timestamp(0, 864000); // Example timestamp diff --git a/packages/firebase_database/firebase_database/example/integration_test/data_snapshot_e2e.dart b/packages/firebase_database/firebase_database/example/integration_test/data_snapshot_e2e.dart index 8828ba723198..9ce3a370f331 100644 --- a/packages/firebase_database/firebase_database/example/integration_test/data_snapshot_e2e.dart +++ b/packages/firebase_database/firebase_database/example/integration_test/data_snapshot_e2e.dart @@ -64,10 +64,7 @@ void setupDataSnapshotTests() { 2, true, ['foo'], - { - 0: 'hello', - 1: 'foo', - } + {0: 'hello', 1: 'foo'}, ]; await ref.set(data); final s = await ref.get(); @@ -163,11 +160,7 @@ void setupDataSnapshotTests() { test('children returns the children in order', () async { final ref = getRef('children'); - await ref.set({ - 'a': 3, - 'b': 2, - 'c': 1, - }); + await ref.set({'a': 3, 'b': 2, 'c': 1}); // Use .once() instead of .get() because the REST API used by .get() // does not guarantee ordered results from the emulator. final event = await ref.orderByValue().once(); diff --git a/packages/firebase_database/firebase_database/example/integration_test/database_e2e.dart b/packages/firebase_database/firebase_database/example/integration_test/database_e2e.dart index 12cfde2ba479..63c0e96bd058 100644 --- a/packages/firebase_database/firebase_database/example/integration_test/database_e2e.dart +++ b/packages/firebase_database/firebase_database/example/integration_test/database_e2e.dart @@ -25,15 +25,12 @@ void setupDatabaseTests() { expect(snapshot.value, 0); }); - test( - 'root reference path returns as "/"', - () async { - final rootRef = database.ref(); - expect(rootRef.path, '/'); - expect(rootRef.key, isNull); - expect(rootRef.parent, isNull); - }, - ); + test('root reference path returns as "/"', () async { + final rootRef = database.ref(); + expect(rootRef.path, '/'); + expect(rootRef.key, isNull); + expect(rootRef.parent, isNull); + }); test( 'returns a reference to the root of the database if no path specified', @@ -80,12 +77,15 @@ void setupDatabaseTests() { expect(() => database.refFromURL('foo'), throwsArgumentError); }); - test('throws [ArgumentError] if database url does not match instance url', - () async { - expect( - () => database.refFromURL('https://some-other-database.firebaseio.com'), - throwsArgumentError, - ); - }); + test( + 'throws [ArgumentError] if database url does not match instance url', + () async { + expect( + () => + database.refFromURL('https://some-other-database.firebaseio.com'), + throwsArgumentError, + ); + }, + ); }); } diff --git a/packages/firebase_database/firebase_database/example/integration_test/database_reference_e2e.dart b/packages/firebase_database/firebase_database/example/integration_test/database_reference_e2e.dart index deddc05b6e32..b444d82eedca 100644 --- a/packages/firebase_database/firebase_database/example/integration_test/database_reference_e2e.dart +++ b/packages/firebase_database/firebase_database/example/integration_test/database_reference_e2e.dart @@ -13,9 +13,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'e2e_test.dart'; DatabaseReference _uniqueRef(String name) { - return database.ref( - 'tests/$name-${DateTime.now().microsecondsSinceEpoch}', - ); + return database.ref('tests/$name-${DateTime.now().microsecondsSinceEpoch}'); } void setupDatabaseReferenceTests() { @@ -49,20 +47,22 @@ void setupDatabaseReferenceTests() { // plugin computed a mapped code but sent it without a Pigeon `details` // payload, so every native error reached Dart as `unknown` with the code // dropped. - test('a rejected write keeps its native error code and message', - () async { - // `denied_read` denies reads and writes in database.rules.json. - final ref = database.ref('denied_read/rejected-write'); - - await expectLater( - ref.set('probe'), - throwsA( - isA() - .having((e) => e.code, 'code', 'permission-denied') - .having((e) => e.message, 'message', isNotEmpty), - ), - ); - }); + test( + 'a rejected write keeps its native error code and message', + () async { + // `denied_read` denies reads and writes in database.rules.json. + final ref = database.ref('denied_read/rejected-write'); + + await expectLater( + ref.set('probe'), + throwsA( + isA() + .having((e) => e.code, 'code', 'permission-denied') + .having((e) => e.message, 'message', isNotEmpty), + ), + ); + }, + ); }); group('setPriority()', () { @@ -101,10 +101,7 @@ void setupDatabaseReferenceTests() { await ref.update({'bar': newValue}); final actual = await ref.get(); - expect(actual.value, { - 'foo': 'bar', - 'bar': newValue, - }); + expect(actual.value, {'foo': 'bar', 'bar': newValue}); }); }); @@ -249,14 +246,16 @@ void setupDatabaseReferenceTests() { await ref .runTransaction((value) => Transaction.success(1)) .then((result) { - // No-op - }).catchError((e) { - errorReceived.complete(e as FirebaseException); - }); + // No-op + }) + .catchError((e) { + errorReceived.complete(e as FirebaseException); + }); // Fail the test rather than hang the suite if the error never arrives. - final streamError = - await errorReceived.future.timeout(const Duration(seconds: 30)); + final streamError = await errorReceived.future.timeout( + const Duration(seconds: 30), + ); expect(streamError, isA()); if (defaultTargetPlatform == TargetPlatform.windows) { // The desktop C++ SDK replaces any non-`datastale` server error on a diff --git a/packages/firebase_database/firebase_database/example/integration_test/query_e2e.dart b/packages/firebase_database/firebase_database/example/integration_test/query_e2e.dart index 2b7d8a2ac2d5..7dc393494f93 100644 --- a/packages/firebase_database/firebase_database/example/integration_test/query_e2e.dart +++ b/packages/firebase_database/firebase_database/example/integration_test/query_e2e.dart @@ -25,35 +25,28 @@ void setupQueryTests() { group('startAt', () { test('returns null when no order modifier is applied', () async { - await ref.set({ - 'a': 1, - 'b': 2, - 'c': 3, - }); + await ref.set({'a': 1, 'b': 2, 'c': 3}); final snapshot = await ref.startAt(2).get(); expect(snapshot.value, isNull); }); - test( - 'streams respect orderByChild with numeric startAt', - () async { - await ref.set({ - 't1': {'timestamp': 1, 'value': 'old'}, - 't2': {'timestamp': 1000, 'value': 'current'}, - }); + test('streams respect orderByChild with numeric startAt', () async { + await ref.set({ + 't1': {'timestamp': 1, 'value': 'old'}, + 't2': {'timestamp': 1000, 'value': 'current'}, + }); - final events = await ref - .orderByChild('timestamp') - .startAt(1000) - .onChildAdded - .take(1) - .toList(); + final events = await ref + .orderByChild('timestamp') + .startAt(1000) + .onChildAdded + .take(1) + .toList(); - expect(events.single.snapshot.key, 't2'); - expect(events.single.snapshot.child('value').value, 'current'); - }, - ); + expect(events.single.snapshot.key, 't2'); + expect(events.single.snapshot.child('value').value, 'current'); + }); test( 'onValue with startAt(value, key) and no orderBy should not crash', @@ -70,12 +63,7 @@ void setupQueryTests() { ); test('starts at the correct value', () async { - await ref.set({ - 'a': 1, - 'b': 2, - 'c': 3, - 'd': 4, - }); + await ref.set({'a': 1, 'b': 2, 'c': 3, 'd': 4}); final snapshot = await ref.orderByValue().startAt(2).get(); @@ -90,11 +78,7 @@ void setupQueryTests() { group('startAfter', () { test('returns null when no order modifier is applied', () async { - await ref.set({ - 'a': 1, - 'b': 2, - 'c': 3, - }); + await ref.set({'a': 1, 'b': 2, 'c': 3}); final snapshot = await ref.startAfter(2).get(); expect(snapshot.value, isNull); @@ -103,12 +87,7 @@ void setupQueryTests() { test( 'starts after the correct value', () async { - await ref.set({ - 'a': 1, - 'b': 2, - 'c': 3, - 'd': 4, - }); + await ref.set({'a': 1, 'b': 2, 'c': 3, 'd': 4}); // TODO(ehesp): Using `get` returns the wrong results. Have flagged with SDK team. final e = await ref.orderByValue().startAfter(2).once(); @@ -129,11 +108,7 @@ void setupQueryTests() { group('endAt', () { test('returns all values when no order modifier is applied', () async { - await ref.set({ - 'a': 1, - 'b': 2, - 'c': 3, - }); + await ref.set({'a': 1, 'b': 2, 'c': 3}); final expected = ['a', 'b', 'c']; @@ -146,12 +121,7 @@ void setupQueryTests() { }); test('ends at the correct value', () async { - await ref.set({ - 'a': 1, - 'b': 2, - 'c': 3, - 'd': 4, - }); + await ref.set({'a': 1, 'b': 2, 'c': 3, 'd': 4}); final snapshot = await ref.orderByValue().endAt(2).get(); @@ -166,11 +136,7 @@ void setupQueryTests() { group('endBefore', () { test('returns all values when no order modifier is applied', () async { - await ref.set({ - 'a': 1, - 'b': 2, - 'c': 3, - }); + await ref.set({'a': 1, 'b': 2, 'c': 3}); final expected = ['a', 'b', 'c']; @@ -185,12 +151,7 @@ void setupQueryTests() { test( 'ends before the correct value', () async { - await ref.set({ - 'a': 1, - 'b': 2, - 'c': 3, - 'd': 4, - }); + await ref.set({'a': 1, 'b': 2, 'c': 3, 'd': 4}); final snapshot = await ref.orderByValue().endBefore(2).get(); @@ -209,24 +170,14 @@ void setupQueryTests() { group('equalTo', () { test('returns null when no order modifier is applied', () async { - await ref.set({ - 'a': 1, - 'b': 2, - 'c': 3, - }); + await ref.set({'a': 1, 'b': 2, 'c': 3}); final snapshot = await ref.equalTo(2).get(); expect(snapshot.value, isNull); }); test('returns the correct value', () async { - await ref.set({ - 'a': 1, - 'b': 2, - 'c': 3, - 'd': 4, - 'e': 2, - }); + await ref.set({'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 2}); final snapshot = await ref.orderByValue().equalTo(2).get(); @@ -241,11 +192,7 @@ void setupQueryTests() { group('limitToFirst', () { test('returns a limited array', () async { - await ref.set({ - 0: 'foo', - 1: 'bar', - 2: 'baz', - }); + await ref.set({0: 'foo', 1: 'bar', 2: 'baz'}); final snapshot = await ref.limitToFirst(2).get(); @@ -254,18 +201,11 @@ void setupQueryTests() { }); test('returns a limited object', () async { - await ref.set({ - 'a': 'foo', - 'b': 'bar', - 'c': 'baz', - }); + await ref.set({'a': 'foo', 'b': 'bar', 'c': 'baz'}); final snapshot = await ref.limitToFirst(2).get(); - final expected = { - 'a': 'foo', - 'b': 'bar', - }; + final expected = {'a': 'foo', 'b': 'bar'}; expect(snapshot.value, equals(expected)); }); @@ -279,31 +219,17 @@ void setupQueryTests() { }); test('streams emit limited maps', () async { - await ref.set({ - 'a': 'foo', - 'b': 'bar', - 'c': 'baz', - }); + await ref.set({'a': 'foo', 'b': 'bar', 'c': 'baz'}); final event = await ref.orderByKey().limitToFirst(2).onValue.first; - expect( - event.snapshot.value, - equals({ - 'a': 'foo', - 'b': 'bar', - }), - ); + expect(event.snapshot.value, equals({'a': 'foo', 'b': 'bar'})); }); }); group('limitToLast', () { test('returns a limited array', () async { - await ref.set({ - 0: 'foo', - 1: 'bar', - 2: 'baz', - }); + await ref.set({0: 'foo', 1: 'bar', 2: 'baz'}); final snapshot = await ref.limitToLast(2).get(); @@ -312,18 +238,11 @@ void setupQueryTests() { }); test('returns a limited object', () async { - await ref.set({ - 'a': 'foo', - 'b': 'bar', - 'c': 'baz', - }); + await ref.set({'a': 'foo', 'b': 'bar', 'c': 'baz'}); final snapshot = await ref.limitToLast(2).get(); - final expected = { - 'b': 'bar', - 'c': 'baz', - }; + final expected = {'b': 'bar', 'c': 'baz'}; expect(snapshot.value, equals(expected)); }); @@ -337,39 +256,20 @@ void setupQueryTests() { }); test('streams emit limited maps', () async { - await ref.set({ - 'a': 'foo', - 'b': 'bar', - 'c': 'baz', - }); + await ref.set({'a': 'foo', 'b': 'bar', 'c': 'baz'}); final event = await ref.orderByKey().limitToLast(2).onValue.first; - expect( - event.snapshot.value, - equals({ - 'b': 'bar', - 'c': 'baz', - }), - ); + expect(event.snapshot.value, equals({'b': 'bar', 'c': 'baz'})); }); }); group('orderByChild', () { test('orders by a child value', () async { await ref.set({ - 'a': { - 'string': 'foo', - 'number': 10, - }, - 'b': { - 'string': 'bar', - 'number': 5, - }, - 'c': { - 'string': 'baz', - 'number': 8, - }, + 'a': {'string': 'foo', 'number': 10}, + 'b': {'string': 'bar', 'number': 5}, + 'c': {'string': 'baz', 'number': 8}, }); final snapshot = await ref.orderByChild('number').get(); @@ -385,18 +285,9 @@ void setupQueryTests() { group('orderByKey', () { test('orders by a key', () async { await ref.set({ - 'b': { - 'string': 'bar', - 'number': 5, - }, - 'a': { - 'string': 'foo', - 'number': 10, - }, - 'c': { - 'string': 'baz', - 'number': 8, - }, + 'b': {'string': 'bar', 'number': 5}, + 'a': {'string': 'foo', 'number': 10}, + 'c': {'string': 'baz', 'number': 8}, }); final snapshot = await ref.orderByKey().get(); @@ -413,18 +304,9 @@ void setupQueryTests() { group('orderByPriority', () { test('orders by priority', () async { await ref.set({ - 'a': { - 'string': 'foo', - 'number': 10, - }, - 'b': { - 'string': 'bar', - 'number': 5, - }, - 'c': { - 'string': 'baz', - 'number': 8, - }, + 'a': {'string': 'foo', 'number': 10}, + 'b': {'string': 'bar', 'number': 5}, + 'c': {'string': 'baz', 'number': 8}, }); await Future.wait([ @@ -445,11 +327,7 @@ void setupQueryTests() { group('orderByValue', () { test('orders by a value', () async { - await ref.set({ - 'a': 2, - 'b': 3, - 'c': 1, - }); + await ref.set({'a': 2, 'b': 3, 'c': 1}); await Future.wait([ ref.child('a').setPriority(2), @@ -468,55 +346,50 @@ void setupQueryTests() { }); group('onChildAdded', () { - test( - 'emits an event when a child is added', - () async { - // Set data first, then subscribe. onChildAdded fires for - // existing children on initial listen, avoiding race conditions - // with native listener registration. - // Use keys that sort alphabetically in the expected order, - // since onChildAdded returns children in key order. - await ref.child('a_first').set('foo'); - await ref.child('b_second').set('bar'); - - final events = await ref.onChildAdded.take(2).toList(); - - expect(events[0].snapshot.value, 'foo'); - expect(events[0].type, DatabaseEventType.childAdded); - expect(events[1].snapshot.value, 'bar'); - expect(events[1].type, DatabaseEventType.childAdded); - }, - ); + test('emits an event when a child is added', () async { + // Set data first, then subscribe. onChildAdded fires for + // existing children on initial listen, avoiding race conditions + // with native listener registration. + // Use keys that sort alphabetically in the expected order, + // since onChildAdded returns children in key order. + await ref.child('a_first').set('foo'); + await ref.child('b_second').set('bar'); + + final events = await ref.onChildAdded.take(2).toList(); + + expect(events[0].snapshot.value, 'foo'); + expect(events[0].type, DatabaseEventType.childAdded); + expect(events[1].snapshot.value, 'bar'); + expect(events[1].type, DatabaseEventType.childAdded); + }); }); group('onChildRemoved', () { - test( - 'emits an event when a child is removed', - () async { - await ref.child('foo').set('foo'); - await ref.child('bar').set('bar'); - - final completer = Completer(); - final subscription = ref.onChildRemoved.listen((event) { - // Skip probe events used for listener registration - if (event.snapshot.key == '__probe__') return; - if (!completer.isCompleted) completer.complete(event); - }); + test('emits an event when a child is removed', () async { + await ref.child('foo').set('foo'); + await ref.child('bar').set('bar'); + + final completer = Completer(); + final subscription = ref.onChildRemoved.listen((event) { + // Skip probe events used for listener registration + if (event.snapshot.key == '__probe__') return; + if (!completer.isCompleted) completer.complete(event); + }); - // Wait for native listener registration by doing a round-trip - await ref.child('__probe__').set(true); - await ref.child('__probe__').remove(); + // Wait for native listener registration by doing a round-trip + await ref.child('__probe__').set(true); + await ref.child('__probe__').remove(); - await ref.child('bar').remove(); + await ref.child('bar').remove(); - final event = - await completer.future.timeout(const Duration(seconds: 10)); - expect(event.snapshot.value, 'bar'); - expect(event.type, DatabaseEventType.childRemoved); + final event = await completer.future.timeout( + const Duration(seconds: 10), + ); + expect(event.snapshot.value, 'bar'); + expect(event.type, DatabaseEventType.childRemoved); - await subscription.cancel(); - }, - ); + await subscription.cancel(); + }); }); group('onChildChanged', () { @@ -528,98 +401,91 @@ void setupQueryTests() { await childRef.remove(); }); - test( - 'emits an event when a child is changed', - () async { - await childRef.child('foo').set('foo'); - await childRef.child('bar').set('bar'); - - final events = []; - final receivedTwo = Completer(); - final subscription = childRef.onChildChanged.listen((event) { - events.add(event); - if (events.length >= 2 && !receivedTwo.isCompleted) { - receivedTwo.complete(); - } - }); + test('emits an event when a child is changed', () async { + await childRef.child('foo').set('foo'); + await childRef.child('bar').set('bar'); - // Wait for native listener registration by doing a round-trip - await childRef.child('__probe__').set(true); - await childRef.child('__probe__').remove(); + final events = []; + final receivedTwo = Completer(); + final subscription = childRef.onChildChanged.listen((event) { + events.add(event); + if (events.length >= 2 && !receivedTwo.isCompleted) { + receivedTwo.complete(); + } + }); - await childRef.child('bar').set('baz'); - await childRef.child('foo').set('bar'); + // Wait for native listener registration by doing a round-trip + await childRef.child('__probe__').set(true); + await childRef.child('__probe__').remove(); - await receivedTwo.future.timeout(const Duration(seconds: 10)); + await childRef.child('bar').set('baz'); + await childRef.child('foo').set('bar'); - expect(events[0].snapshot.key, 'bar'); - expect(events[0].snapshot.value, 'baz'); - expect(events[0].type, DatabaseEventType.childChanged); - expect(events[1].snapshot.key, 'foo'); - expect(events[1].snapshot.value, 'bar'); - expect(events[1].type, DatabaseEventType.childChanged); + await receivedTwo.future.timeout(const Duration(seconds: 10)); - await subscription.cancel(); - }, - ); + expect(events[0].snapshot.key, 'bar'); + expect(events[0].snapshot.value, 'baz'); + expect(events[0].type, DatabaseEventType.childChanged); + expect(events[1].snapshot.key, 'foo'); + expect(events[1].snapshot.value, 'bar'); + expect(events[1].type, DatabaseEventType.childChanged); + + await subscription.cancel(); + }); }); group('onChildMoved', () { - test( - 'emits an event when a child is moved', - () async { - await ref.set({ - 'alex': {'nuggets': 60}, - 'rob': {'nuggets': 56}, - 'vassili': {'nuggets': 55.5}, - 'tony': {'nuggets': 52}, - 'greg': {'nuggets': 52}, - }); + test('emits an event when a child is moved', () async { + await ref.set({ + 'alex': {'nuggets': 60}, + 'rob': {'nuggets': 56}, + 'vassili': {'nuggets': 55.5}, + 'tony': {'nuggets': 52}, + 'greg': {'nuggets': 52}, + }); - final events = []; - final receivedTwo = Completer(); - final subscription = - ref.orderByChild('nuggets').onChildMoved.listen((event) { - events.add(event); - if (events.length >= 2 && !receivedTwo.isCompleted) { - receivedTwo.complete(); - } - }); + final events = []; + final receivedTwo = Completer(); + final subscription = ref.orderByChild('nuggets').onChildMoved.listen(( + event, + ) { + events.add(event); + if (events.length >= 2 && !receivedTwo.isCompleted) { + receivedTwo.complete(); + } + }); - // Wait for native listener registration by doing a round-trip - await ref.child('__probe__').set(true); - await ref.child('__probe__').remove(); + // Wait for native listener registration by doing a round-trip + await ref.child('__probe__').set(true); + await ref.child('__probe__').remove(); - await ref.child('greg/nuggets').set(57); - await ref.child('rob/nuggets').set(61); + await ref.child('greg/nuggets').set(57); + await ref.child('rob/nuggets').set(61); - await receivedTwo.future.timeout(const Duration(seconds: 10)); + await receivedTwo.future.timeout(const Duration(seconds: 10)); - expect(events[0].snapshot.value, {'nuggets': 57}); - expect(events[0].type, DatabaseEventType.childMoved); - expect(events[1].snapshot.value, {'nuggets': 61}); - expect(events[1].type, DatabaseEventType.childMoved); + expect(events[0].snapshot.value, {'nuggets': 57}); + expect(events[0].type, DatabaseEventType.childMoved); + expect(events[1].snapshot.value, {'nuggets': 61}); + expect(events[1].type, DatabaseEventType.childMoved); - await subscription.cancel(); - }, - ); + await subscription.cancel(); + }); }); group('onValue', () { test('emits an event when the data changes', () async { - await ref.set({ - 'a': 2, - 'b': 3, - 'c': 1, - }); + await ref.set({'a': 2, 'b': 3, 'c': 1}); expect( ref.onValue, emitsInOrder([ - isA().having((s) => s.snapshot.value, 'value', { - 'a': 2, - 'b': 3, - 'c': 1, - }).having((e) => e.type, 'type', DatabaseEventType.value), + isA() + .having((s) => s.snapshot.value, 'value', { + 'a': 2, + 'b': 3, + 'c': 1, + }) + .having((e) => e.type, 'type', DatabaseEventType.value), ]), ); }); @@ -638,16 +504,13 @@ void setupQueryTests() { for (var i = 0; i < subscriptionCount; i++) { subscriptions.add( - queryRef.onValue.listen( - (_) { - firstEventCount++; - if (firstEventCount >= subscriptionCount && - !firstEventsReceived.isCompleted) { - firstEventsReceived.complete(); - } - }, - onError: errors.add, - ), + queryRef.onValue.listen((_) { + firstEventCount++; + if (firstEventCount >= subscriptionCount && + !firstEventsReceived.isCompleted) { + firstEventsReceived.complete(); + } + }, onError: errors.add), ); } @@ -662,55 +525,57 @@ void setupQueryTests() { ); test( - 'throw a `permission-denied` exception when accessing restricted data', - () async { - final Completer errorReceived = - Completer(); - FirebaseDatabase.instance.ref().child('restricted').onValue.listen( - (event) { - // Do nothing - }, - onError: (error) { - errorReceived.complete(error); - }, - ); + 'throw a `permission-denied` exception when accessing restricted data', + () async { + final Completer errorReceived = + Completer(); + FirebaseDatabase.instance + .ref() + .child('restricted') + .onValue + .listen( + (event) { + // Do nothing + }, + onError: (error) { + errorReceived.complete(error); + }, + ); - // Fail the test rather than hang the suite if the error never arrives. - final streamError = - await errorReceived.future.timeout(const Duration(seconds: 30)); - expect(streamError, isA()); - expect(streamError.code, 'permission-denied'); - }); + // Fail the test rather than hang the suite if the error never arrives. + final streamError = await errorReceived.future.timeout( + const Duration(seconds: 30), + ); + expect(streamError, isA()); + expect(streamError.code, 'permission-denied'); + }, + ); }); group('keepSynced', () { - test( - 'multiple queries can enable keepSynced without crashing', - () async { - await ref.set({ - 'a': {'value': 1}, - 'b': {'value': 2}, - 'c': {'value': 3}, - }); + test('multiple queries can enable keepSynced without crashing', () async { + await ref.set({ + 'a': {'value': 1}, + 'b': {'value': 2}, + 'c': {'value': 3}, + }); - // Enable keepSynced on multiple different queries - final query1 = ref.orderByChild('value').limitToFirst(2); - final query2 = ref.orderByChild('value').limitToLast(2); - final query3 = ref.orderByKey().startAt('a'); - final query4 = ref.orderByValue(); + // Enable keepSynced on multiple different queries + final query1 = ref.orderByChild('value').limitToFirst(2); + final query2 = ref.orderByChild('value').limitToLast(2); + final query3 = ref.orderByKey().startAt('a'); + final query4 = ref.orderByValue(); - // These should all complete without throwing - await query1.keepSynced(true); - await query2.keepSynced(true); - await query3.keepSynced(true); - await query4.keepSynced(true); + // These should all complete without throwing + await query1.keepSynced(true); + await query2.keepSynced(true); + await query3.keepSynced(true); + await query4.keepSynced(true); - // Verify data is still accessible after enabling keepSynced - final snapshot = await ref.get(); - expect(snapshot.value, isNotNull); - }, - skip: kIsWeb, - ); + // Verify data is still accessible after enabling keepSynced + final snapshot = await ref.get(); + expect(snapshot.value, isNotNull); + }, skip: kIsWeb); test( 'multiple queries can disable keepSynced without crashing', @@ -745,10 +610,7 @@ void setupQueryTests() { test( 'calling keepSynced multiple times on same query does not crash', () async { - await ref.set({ - 'a': 1, - 'b': 2, - }); + await ref.set({'a': 1, 'b': 2}); final query = ref.orderByValue().limitToFirst(5); @@ -767,42 +629,38 @@ void setupQueryTests() { skip: kIsWeb, ); - test( - 'keepSynced works with various query combinations', - () async { - await ref.set({ - 'item1': {'name': 'alpha', 'priority': 1}, - 'item2': {'name': 'beta', 'priority': 2}, - 'item3': {'name': 'gamma', 'priority': 3}, - 'item4': {'name': 'delta', 'priority': 4}, - }); + test('keepSynced works with various query combinations', () async { + await ref.set({ + 'item1': {'name': 'alpha', 'priority': 1}, + 'item2': {'name': 'beta', 'priority': 2}, + 'item3': {'name': 'gamma', 'priority': 3}, + 'item4': {'name': 'delta', 'priority': 4}, + }); - // Test various query combinations with keepSynced - final queries = [ - ref.orderByChild('name'), - ref.orderByChild('priority').startAt(2), - ref.orderByChild('priority').endAt(3), - ref.orderByChild('priority').equalTo(2), - ref.orderByKey().limitToFirst(2), - ref.orderByKey().limitToLast(2), - ]; - - // Enable keepSynced on all queries - for (final query in queries) { - await query.keepSynced(true); - } + // Test various query combinations with keepSynced + final queries = [ + ref.orderByChild('name'), + ref.orderByChild('priority').startAt(2), + ref.orderByChild('priority').endAt(3), + ref.orderByChild('priority').equalTo(2), + ref.orderByKey().limitToFirst(2), + ref.orderByKey().limitToLast(2), + ]; + + // Enable keepSynced on all queries + for (final query in queries) { + await query.keepSynced(true); + } - // Disable keepSynced on all queries - for (final query in queries) { - await query.keepSynced(false); - } + // Disable keepSynced on all queries + for (final query in queries) { + await query.keepSynced(false); + } - // Verify everything still works - final snapshot = await ref.get(); - expect(snapshot.children.length, 4); - }, - skip: kIsWeb, - ); + // Verify everything still works + final snapshot = await ref.get(); + expect(snapshot.children.length, 4); + }, skip: kIsWeb); }); }); } diff --git a/packages/firebase_database/firebase_database/example/integration_test/report_test_results.dart b/packages/firebase_database/firebase_database/example/integration_test/report_test_results.dart index fb80e3ba19f7..db17f5dab066 100644 --- a/packages/firebase_database/firebase_database/example/integration_test/report_test_results.dart +++ b/packages/firebase_database/firebase_database/example/integration_test/report_test_results.dart @@ -26,8 +26,9 @@ void reportTestResultsToDriver(IntegrationTestWidgetsFlutterBinding binding) { for (final entry in binding.results.entries) if (entry.value is Failure) entry.key, ]; - bool didFail(String name) => failures - .any((failure) => name == failure || name.endsWith(' $failure')); + bool didFail(String name) => failures.any( + (failure) => name == failure || name.endsWith(' $failure'), + ); binding.reportData ??= {}; binding.reportData!['testResults'] = { diff --git a/packages/firebase_database/firebase_database/example/integration_test/web_only.dart b/packages/firebase_database/firebase_database/example/integration_test/web_only.dart index 132f0d71870c..81af4d58158f 100644 --- a/packages/firebase_database/firebase_database/example/integration_test/web_only.dart +++ b/packages/firebase_database/firebase_database/example/integration_test/web_only.dart @@ -10,45 +10,35 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:firebase_database_web/firebase_database_web.dart'; void setupWebOnlyTests() { - group( - 'web', - () { - test('convertFirebaseDatabaseException', () { - Object jsErr(String? message) { - return { - 'message': message, - }.jsify()! as Object; - } + group('web', () { + test('convertFirebaseDatabaseException', () { + Object jsErr(String? message) { + return {'message': message}.jsify()! as Object; + } - final cases = [ - ['Capital small', 'unknown'], - [null, 'unknown'], - ['Index not defined', 'index-not-defined'], - ]; + final cases = [ + ['Capital small', 'unknown'], + [null, 'unknown'], + ['Index not defined', 'index-not-defined'], + ]; - for (var i = 0; i < cases.length; i++) { - final message = cases[i][0]; - final convertedCode = cases[i][1]; - var converted = convertFirebaseDatabaseException(jsErr(message)); + for (var i = 0; i < cases.length; i++) { + final message = cases[i][0]; + final convertedCode = cases[i][1]; + var converted = convertFirebaseDatabaseException(jsErr(message)); - expect( - converted.message, - message ?? '', - reason: '[$i] Failed message check', - ); - expect( - converted.code, - convertedCode, - reason: '[$i] Failed code check', - ); - expect( - converted.plugin, - 'firebase_database', - reason: '[$i] Failed plugin check', - ); - } - }); - }, - skip: !kIsWeb, - ); + expect( + converted.message, + message ?? '', + reason: '[$i] Failed message check', + ); + expect(converted.code, convertedCode, reason: '[$i] Failed code check'); + expect( + converted.plugin, + 'firebase_database', + reason: '[$i] Failed plugin check', + ); + } + }); + }, skip: !kIsWeb); } diff --git a/packages/firebase_database/firebase_database/example/lib/firebase_options.dart b/packages/firebase_database/firebase_database/example/lib/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/firebase_database/firebase_database/example/lib/firebase_options.dart +++ b/packages/firebase_database/firebase_database/example/lib/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/firebase_database/firebase_database/example/lib/main.dart b/packages/firebase_database/firebase_database/example/lib/main.dart index 9e808375566d..a4ee96a75449 100755 --- a/packages/firebase_database/firebase_database/example/lib/main.dart +++ b/packages/firebase_database/firebase_database/example/lib/main.dart @@ -21,24 +21,19 @@ const emulatorPort = 9000; // so let's use that if running on Android. final emulatorHost = (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) - ? '10.0.2.2' - : 'localhost'; + ? '10.0.2.2' + : 'localhost'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); + await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); if (USE_DATABASE_EMULATOR) { FirebaseDatabase.instance.useDatabaseEmulator(emulatorHost, emulatorPort); } runApp( - const MaterialApp( - title: 'Flutter Database Example', - home: MyHomePage(), - ), + const MaterialApp(title: 'Flutter Database Example', home: MyHomePage()), ); } @@ -139,9 +134,9 @@ class _MyHomePageState extends State { Future _increment() async { await _counterRef.set(ServerValue.increment(1)); - await _messagesRef - .push() - .set({_kTestKey: '$_kTestValue $_counter'}); + await _messagesRef.push().set({ + _kTestKey: '$_kTestValue $_counter', + }); } Future _incrementAsTransaction() async { @@ -181,9 +176,7 @@ class _MyHomePageState extends State { if (!initialized) return Container(); return Scaffold( - appBar: AppBar( - title: const Text('Flutter Database Example'), - ), + appBar: AppBar(title: const Text('Flutter Database Example')), body: Column( children: [ Flexible( diff --git a/packages/firebase_database/firebase_database/example/pubspec.yaml b/packages/firebase_database/firebase_database/example/pubspec.yaml index 422595e5b6c9..bd543dcb5fdb 100755 --- a/packages/firebase_database/firebase_database/example/pubspec.yaml +++ b/packages/firebase_database/firebase_database/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the firebase_database plugin. resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core: ^4.14.0 diff --git a/packages/firebase_database/firebase_database/example/test_driver/integration_test.dart b/packages/firebase_database/firebase_database/example/test_driver/integration_test.dart index 691723cbbfe1..9ccbcc26ab97 100644 --- a/packages/firebase_database/firebase_database/example/test_driver/integration_test.dart +++ b/packages/firebase_database/firebase_database/example/test_driver/integration_test.dart @@ -7,28 +7,32 @@ import 'dart:io'; import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver( - writeResponseOnFailure: true, - responseDataCallback: (Map? data) async { - final results = - (data?['testResults'] as Map?)?.cast() ?? - const {}; - var passed = 0; - var failed = 0; - for (final entry in results.entries) { - final ok = entry.value == 'success'; - ok ? passed++ : failed++; - // ignore: avoid_print - print('${ok ? '✅' : '❌'} ${entry.key}'); - } - // ignore: avoid_print - print('Web e2e summary: $passed passed, $failed failed, ' - '${results.length} total'); - if (results.isEmpty) { - // ignore: avoid_print - print('[E] No tests reported by the app - treating as ' - 'infrastructure failure.'); - exit(1); - } - await writeResponseData(data); - }, + writeResponseOnFailure: true, + responseDataCallback: (Map? data) async { + final results = + (data?['testResults'] as Map?)?.cast() ?? + const {}; + var passed = 0; + var failed = 0; + for (final entry in results.entries) { + final ok = entry.value == 'success'; + ok ? passed++ : failed++; + // ignore: avoid_print + print('${ok ? '✅' : '❌'} ${entry.key}'); + } + // ignore: avoid_print + print( + 'Web e2e summary: $passed passed, $failed failed, ' + '${results.length} total', ); + if (results.isEmpty) { + // ignore: avoid_print + print( + '[E] No tests reported by the app - treating as ' + 'infrastructure failure.', + ); + exit(1); + } + await writeResponseData(data); + }, +); diff --git a/packages/firebase_database/firebase_database/lib/src/firebase_database.dart b/packages/firebase_database/firebase_database/lib/src/firebase_database.dart index 4090063e08a4..863307d2a219 100644 --- a/packages/firebase_database/firebase_database/lib/src/firebase_database.dart +++ b/packages/firebase_database/firebase_database/lib/src/firebase_database.dart @@ -8,7 +8,7 @@ part of '../firebase_database.dart'; /// by calling `FirebaseDatabase.instance` or `FirebaseDatabase.instanceFor()`. class FirebaseDatabase extends FirebasePlugin { FirebaseDatabase._({required this.app, this.databaseURL}) - : super(app.name, 'plugins.flutter.io/firebase_database') { + : super(app.name, 'plugins.flutter.io/firebase_database') { if (databaseURL != null && databaseURL!.endsWith('/')) { databaseURL = databaseURL!.substring(0, databaseURL!.length - 1); } @@ -24,9 +24,7 @@ class FirebaseDatabase extends FirebasePlugin { /// Returns an instance using the default [FirebaseApp]. static FirebaseDatabase get instance { - return FirebaseDatabase.instanceFor( - app: Firebase.app(), - ); + return FirebaseDatabase.instanceFor(app: Firebase.app()); } /// Returns an instance using a specified [FirebaseApp]. @@ -39,8 +37,10 @@ class FirebaseDatabase extends FirebasePlugin { return _cachedInstances[cacheKey]!; } - FirebaseDatabase newInstance = - FirebaseDatabase._(app: app, databaseURL: databaseURL); + FirebaseDatabase newInstance = FirebaseDatabase._( + app: app, + databaseURL: databaseURL, + ); _cachedInstances[cacheKey] = newInstance; return newInstance; @@ -52,8 +52,10 @@ class FirebaseDatabase extends FirebasePlugin { DatabasePlatform? _delegatePackingProperty; DatabasePlatform get _delegate { - return _delegatePackingProperty ??= - DatabasePlatform.instanceFor(app: app, databaseURL: databaseURL); + return _delegatePackingProperty ??= DatabasePlatform.instanceFor( + app: app, + databaseURL: databaseURL, + ); } /// Changes this instance to point to a FirebaseDatabase emulator running locally. diff --git a/packages/firebase_database/firebase_database/lib/src/query.dart b/packages/firebase_database/firebase_database/lib/src/query.dart index fa28ceb0b3bc..a46d48799fd7 100644 --- a/packages/firebase_database/firebase_database/lib/src/query.dart +++ b/packages/firebase_database/firebase_database/lib/src/query.dart @@ -7,7 +7,7 @@ part of '../firebase_database.dart'; /// Represents a query over the data at a particular location. class Query { Query._(this._queryDelegate, [QueryModifiers? modifiers]) - : _modifiers = modifiers ?? QueryModifiers([]) { + : _modifiers = modifiers ?? QueryModifiers([]) { QueryPlatform.verify(_queryDelegate); } @@ -178,9 +178,7 @@ class Query { Query orderByKey() { return Query._( _queryDelegate, - _modifiers.order( - OrderModifier.orderByKey(), - ), + _modifiers.order(OrderModifier.orderByKey()), ); } @@ -191,9 +189,7 @@ class Query { Query orderByValue() { return Query._( _queryDelegate, - _modifiers.order( - OrderModifier.orderByValue(), - ), + _modifiers.order(OrderModifier.orderByValue()), ); } @@ -204,9 +200,7 @@ class Query { Query orderByPriority() { return Query._( _queryDelegate, - _modifiers.order( - OrderModifier.orderByPriority(), - ), + _modifiers.order(OrderModifier.orderByPriority()), ); } diff --git a/packages/firebase_database/firebase_database/lib/ui/firebase_animated_list.dart b/packages/firebase_database/firebase_database/lib/ui/firebase_animated_list.dart index e67ca959981e..e28cbd4d0058 100755 --- a/packages/firebase_database/firebase_database/lib/ui/firebase_animated_list.dart +++ b/packages/firebase_database/firebase_database/lib/ui/firebase_animated_list.dart @@ -8,12 +8,13 @@ import '../firebase_database.dart'; import 'firebase_list.dart'; import 'firebase_sorted_list.dart'; -typedef FirebaseAnimatedListItemBuilder = Widget Function( - BuildContext context, - DataSnapshot snapshot, - Animation animation, - int index, -); +typedef FirebaseAnimatedListItemBuilder = + Widget Function( + BuildContext context, + DataSnapshot snapshot, + Animation animation, + int index, + ); /// An AnimatedList widget that is bound to a query class FirebaseAnimatedList extends StatefulWidget { @@ -176,13 +177,12 @@ class FirebaseAnimatedListState extends State { void _onChildRemoved(int index, DataSnapshot snapshot) { // The child should have already been removed from the model by now assert(index >= _model.length || _model[index].key != snapshot.key); - _animatedListKey.currentState?.removeItem( - index, - (BuildContext context, Animation animation) { - return widget.itemBuilder(context, snapshot, animation, index); - }, - duration: widget.duration, - ); + _animatedListKey.currentState?.removeItem(index, ( + BuildContext context, + Animation animation, + ) { + return widget.itemBuilder(context, snapshot, animation, index); + }, duration: widget.duration); } // No animation, just update contents diff --git a/packages/firebase_database/firebase_database/lib/ui/firebase_list.dart b/packages/firebase_database/firebase_database/lib/ui/firebase_list.dart index fbe4ee5d382a..7e9c9bae88cb 100644 --- a/packages/firebase_database/firebase_database/lib/ui/firebase_list.dart +++ b/packages/firebase_database/firebase_database/lib/ui/firebase_list.dart @@ -10,11 +10,8 @@ import '../firebase_database.dart' show DataSnapshot, DatabaseEvent, Query; import 'utils/stream_subscriber_mixin.dart'; typedef ChildCallback = void Function(int index, DataSnapshot snapshot); -typedef ChildMovedCallback = void Function( - int fromIndex, - int toIndex, - DataSnapshot snapshot, -); +typedef ChildMovedCallback = + void Function(int fromIndex, int toIndex, DataSnapshot snapshot); typedef ValueCallback = void Function(DataSnapshot snapshot); typedef ErrorCallback = void Function(FirebaseException error); diff --git a/packages/firebase_database/firebase_database/lib/ui/firebase_sorted_list.dart b/packages/firebase_database/firebase_database/lib/ui/firebase_sorted_list.dart index 38399a423383..84c48cf2260f 100644 --- a/packages/firebase_database/firebase_database/lib/ui/firebase_sorted_list.dart +++ b/packages/firebase_database/firebase_database/lib/ui/firebase_sorted_list.dart @@ -95,8 +95,9 @@ class FirebaseSortedList extends ListBase } void _onChildRemoved(DatabaseEvent event) { - final DataSnapshot snapshot = - _snapshots.firstWhere((DataSnapshot snapshot) { + final DataSnapshot snapshot = _snapshots.firstWhere(( + DataSnapshot snapshot, + ) { return snapshot.key == event.snapshot.key; }); final int index = _snapshots.indexOf(snapshot); @@ -105,8 +106,9 @@ class FirebaseSortedList extends ListBase } void _onChildChanged(DatabaseEvent event) { - final DataSnapshot snapshot = - _snapshots.firstWhere((DataSnapshot snapshot) { + final DataSnapshot snapshot = _snapshots.firstWhere(( + DataSnapshot snapshot, + ) { return snapshot.key == event.snapshot.key; }); final int index = _snapshots.indexOf(snapshot); diff --git a/packages/firebase_database/firebase_database/pubspec.yaml b/packages/firebase_database/firebase_database/pubspec.yaml index 612e3c81f575..fbddf7ca621f 100755 --- a/packages/firebase_database/firebase_database/pubspec.yaml +++ b/packages/firebase_database/firebase_database/pubspec.yaml @@ -14,8 +14,8 @@ false_secrets: - example/** environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core: ^4.14.0 diff --git a/packages/firebase_database/firebase_database/test/firebase_list_test.dart b/packages/firebase_database/firebase_database/test/firebase_list_test.dart index 634ef8707e96..6df844a933e0 100644 --- a/packages/firebase_database/firebase_database/test/firebase_list_test.dart +++ b/packages/firebase_database/firebase_database/test/firebase_list_test.dart @@ -93,11 +93,7 @@ void main() { final DataSnapshot snapshot = MockDataSnapshot('key10', 10); expect( await processChildAddedEvent( - MockEvent( - DatabaseEventType.childAdded, - null, - snapshot, - ), + MockEvent(DatabaseEventType.childAdded, null, snapshot), ), ListChange.at(0, snapshot), ); @@ -108,19 +104,11 @@ void main() { final DataSnapshot snapshot1 = MockDataSnapshot('key10', 10); final DataSnapshot snapshot2 = MockDataSnapshot('key20', 20); await processChildAddedEvent( - MockEvent( - DatabaseEventType.childAdded, - null, - snapshot2, - ), + MockEvent(DatabaseEventType.childAdded, null, snapshot2), ); expect( await processChildAddedEvent( - MockEvent( - DatabaseEventType.childAdded, - null, - snapshot1, - ), + MockEvent(DatabaseEventType.childAdded, null, snapshot1), ), ListChange.at(0, snapshot1), ); @@ -131,19 +119,11 @@ void main() { final DataSnapshot snapshot1 = MockDataSnapshot('key10', 10); final DataSnapshot snapshot2 = MockDataSnapshot('key20', 20); await processChildAddedEvent( - MockEvent( - DatabaseEventType.childAdded, - null, - snapshot1, - ), + MockEvent(DatabaseEventType.childAdded, null, snapshot1), ); expect( await processChildAddedEvent( - MockEvent( - DatabaseEventType.childAdded, - 'key10', - snapshot2, - ), + MockEvent(DatabaseEventType.childAdded, 'key10', snapshot2), ), ListChange.at(1, snapshot2), ); @@ -153,19 +133,11 @@ void main() { test('can remove from singleton list', () async { final DataSnapshot snapshot = MockDataSnapshot('key10', 10); await processChildAddedEvent( - MockEvent( - DatabaseEventType.childAdded, - null, - snapshot, - ), + MockEvent(DatabaseEventType.childAdded, null, snapshot), ); expect( await processChildRemovedEvent( - MockEvent( - DatabaseEventType.childRemoved, - null, - snapshot, - ), + MockEvent(DatabaseEventType.childRemoved, null, snapshot), ), ListChange.at(0, snapshot), ); @@ -176,26 +148,14 @@ void main() { final DataSnapshot snapshot1 = MockDataSnapshot('key10', 10); final DataSnapshot snapshot2 = MockDataSnapshot('key20', 20); await processChildAddedEvent( - MockEvent( - DatabaseEventType.childAdded, - null, - snapshot2, - ), + MockEvent(DatabaseEventType.childAdded, null, snapshot2), ); await processChildAddedEvent( - MockEvent( - DatabaseEventType.childAdded, - null, - snapshot1, - ), + MockEvent(DatabaseEventType.childAdded, null, snapshot1), ); expect( await processChildRemovedEvent( - MockEvent( - DatabaseEventType.childRemoved, - null, - snapshot1, - ), + MockEvent(DatabaseEventType.childRemoved, null, snapshot1), ), ListChange.at(0, snapshot1), ); @@ -206,26 +166,14 @@ void main() { final DataSnapshot snapshot1 = MockDataSnapshot('key10', 10); final DataSnapshot snapshot2 = MockDataSnapshot('key20', 20); await processChildAddedEvent( - MockEvent( - DatabaseEventType.childAdded, - null, - snapshot2, - ), + MockEvent(DatabaseEventType.childAdded, null, snapshot2), ); await processChildAddedEvent( - MockEvent( - DatabaseEventType.childAdded, - null, - snapshot1, - ), + MockEvent(DatabaseEventType.childAdded, null, snapshot1), ); expect( await processChildRemovedEvent( - MockEvent( - DatabaseEventType.childRemoved, - 'key10', - snapshot2, - ), + MockEvent(DatabaseEventType.childRemoved, 'key10', snapshot2), ), ListChange.at(1, snapshot2), ); @@ -238,25 +186,13 @@ void main() { final DataSnapshot snapshot2b = MockDataSnapshot('key20', 25); final DataSnapshot snapshot3 = MockDataSnapshot('key30', 30); await processChildAddedEvent( - MockEvent( - DatabaseEventType.childAdded, - null, - snapshot3, - ), + MockEvent(DatabaseEventType.childAdded, null, snapshot3), ); await processChildAddedEvent( - MockEvent( - DatabaseEventType.childAdded, - null, - snapshot2a, - ), + MockEvent(DatabaseEventType.childAdded, null, snapshot2a), ); await processChildAddedEvent( - MockEvent( - DatabaseEventType.childAdded, - null, - snapshot1, - ), + MockEvent(DatabaseEventType.childAdded, null, snapshot1), ); expect( await processChildChangedEvent( @@ -271,33 +207,17 @@ void main() { final DataSnapshot snapshot2 = MockDataSnapshot('key20', 20); final DataSnapshot snapshot3 = MockDataSnapshot('key30', 30); await processChildAddedEvent( - MockEvent( - DatabaseEventType.childAdded, - null, - snapshot3, - ), + MockEvent(DatabaseEventType.childAdded, null, snapshot3), ); await processChildAddedEvent( - MockEvent( - DatabaseEventType.childAdded, - null, - snapshot2, - ), + MockEvent(DatabaseEventType.childAdded, null, snapshot2), ); await processChildAddedEvent( - MockEvent( - DatabaseEventType.childAdded, - null, - snapshot1, - ), + MockEvent(DatabaseEventType.childAdded, null, snapshot1), ); expect( await processChildMovedEvent( - MockEvent( - DatabaseEventType.childMoved, - 'key30', - snapshot1, - ), + MockEvent(DatabaseEventType.childMoved, 'key30', snapshot1), ), ListChange.move(0, 2, snapshot1), ); @@ -395,10 +315,10 @@ class MockQuery extends Mock implements Query { class ListChange { ListChange.at(int index, DataSnapshot snapshot) - : this._(index, null, snapshot); + : this._(index, null, snapshot); ListChange.move(int from, int to, DataSnapshot snapshot) - : this._(from, to, snapshot); + : this._(from, to, snapshot); ListChange._(this.index, this.index2, this.snapshot); diff --git a/packages/firebase_database/firebase_database/test/instance_test.dart b/packages/firebase_database/firebase_database/test/instance_test.dart index 44509757f17e..ce71a76422ed 100644 --- a/packages/firebase_database/firebase_database/test/instance_test.dart +++ b/packages/firebase_database/firebase_database/test/instance_test.dart @@ -27,16 +27,17 @@ void main() { }); test( - 'ensure databaseUrl has "/" removed on FirebaseDatabase initialisation', - () { - String secondDb = 'https://second-db.firebaseio.com'; - final shared = FirebaseDatabase.instanceFor( - app: Firebase.app(), - // add forward slash to end - databaseURL: '$secondDb/', - ); - - expect(shared.databaseURL, secondDb); - }); + 'ensure databaseUrl has "/" removed on FirebaseDatabase initialisation', + () { + String secondDb = 'https://second-db.firebaseio.com'; + final shared = FirebaseDatabase.instanceFor( + app: Firebase.app(), + // add forward slash to end + databaseURL: '$secondDb/', + ); + + expect(shared.databaseURL, secondDb); + }, + ); }); } diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_data_snapshot.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_data_snapshot.dart index e89f6b48a1e0..8050af8cc40f 100644 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_data_snapshot.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_data_snapshot.dart @@ -6,10 +6,7 @@ import 'package:firebase_database_platform_interface/firebase_database_platform_ /// Represents a query over the data at a particular location. class MethodChannelDataSnapshot extends DataSnapshotPlatform { - MethodChannelDataSnapshot( - this._ref, - this._data, - ) : super(_ref, _data); + MethodChannelDataSnapshot(this._ref, this._data) : super(_ref, _data); DatabaseReferencePlatform _ref; @@ -45,34 +42,29 @@ class MethodChannelDataSnapshot extends DataSnapshotPlatform { } if (childValue == null) { - return MethodChannelDataSnapshot( - _ref.child(childPath), - { - 'key': _ref.child(childPath).key, - 'value': null, - 'priority': null, - 'childKeys': [], - }, - ); - } - - return MethodChannelDataSnapshot( - _ref.child(childPath), - { + return MethodChannelDataSnapshot(_ref.child(childPath), { 'key': _ref.child(childPath).key, - 'value': childValue, + 'value': null, 'priority': null, - 'childKeys': _childKeysFromValue(childValue), - }, - ); + 'childKeys': [], + }); + } + + return MethodChannelDataSnapshot(_ref.child(childPath), { + 'key': _ref.child(childPath).key, + 'value': childValue, + 'priority': null, + 'childKeys': _childKeysFromValue(childValue), + }); } @override Iterable get children { List _childKeys = List.from(_data['childKeys']); - return Iterable.generate(_childKeys.length, - (int index) { + return Iterable.generate(_childKeys.length, ( + int index, + ) { String childKey = _childKeys[index]; dynamic childValue; @@ -84,15 +76,12 @@ class MethodChannelDataSnapshot extends DataSnapshotPlatform { } } - return MethodChannelDataSnapshot( - _ref.child(childKey), - { - 'key': childKey, - 'value': childValue, - 'priority': null, - 'childKeys': _childKeysFromValue(childValue), - }, - ); + return MethodChannelDataSnapshot(_ref.child(childKey), { + 'key': childKey, + 'value': childValue, + 'priority': null, + 'childKeys': _childKeysFromValue(childValue), + }); }); } } diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_database.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_database.dart index 2d513f0222f1..858cda6e15e4 100755 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_database.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_database.dart @@ -78,7 +78,7 @@ class MethodChannelDatabase extends DatabasePlatform { } MethodChannelDatabase({FirebaseApp? app, String? databaseURL}) - : super(app: app, databaseURL: databaseURL) { + : super(app: app, databaseURL: databaseURL) { if (_initialized) return; // Set up the Pigeon FlutterApi for transaction handler callbacks @@ -123,8 +123,9 @@ class MethodChannelDatabase extends DatabasePlatform { /// The [MethodChannel] used to communicate with the native plugin /// This is kept for backward compatibility with query operations - static const MethodChannel channel = - MethodChannel('plugins.flutter.io/firebase_database'); + static const MethodChannel channel = MethodChannel( + 'plugins.flutter.io/firebase_database', + ); @override void useDatabaseEmulator(String host, int port) { diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_database_reference.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_database_reference.dart index 47511234b58a..063b38aa1917 100644 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_database_reference.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_database_reference.dart @@ -30,10 +30,7 @@ class MethodChannelDatabaseReference extends MethodChannelQuery MethodChannelDatabaseReference({ required DatabasePlatform database, required List pathComponents, - }) : super( - database: database, - pathComponents: pathComponents, - ); + }) : super(database: database, pathComponents: pathComponents); /// Gets the Pigeon app object from the database DatabasePigeonFirebaseApp get _pigeonApp { @@ -133,10 +130,7 @@ class MethodChannelDatabaseReference extends MethodChannelQuery try { await _api.databaseReferenceSetPriority( _pigeonApp, - DatabaseReferenceRequest( - path: path, - priority: priority, - ), + DatabaseReferenceRequest(path: path, priority: priority), ); } catch (e, s) { convertPlatformException(e, s); @@ -197,9 +191,6 @@ class MethodChannelDatabaseReference extends MethodChannelQuery @override OnDisconnectPlatform onDisconnect() { - return MethodChannelOnDisconnect( - database: database, - ref: this, - ); + return MethodChannelOnDisconnect(database: database, ref: this); } } diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_on_disconnect.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_on_disconnect.dart index 9fd644665f53..4897470c92e4 100755 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_on_disconnect.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_on_disconnect.dart @@ -63,10 +63,7 @@ class MethodChannelOnDisconnect extends OnDisconnectPlatform { @override Future cancel() async { try { - await _api.onDisconnectCancel( - _pigeonApp, - ref.path, - ); + await _api.onDisconnectCancel(_pigeonApp, ref.path); } catch (e, s) { convertPlatformException(e, s); } diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_query.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_query.dart index 5ca46b4db2c7..aff93948e8fd 100755 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_query.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_query.dart @@ -52,19 +52,20 @@ class MethodChannelQuery extends QueryPlatform { // Create the EventChannel on native using Pigeon. final channelName = await _api.queryObserve( _pigeonApp, - QueryRequest( - path: path, - modifiers: modifierList, - ), + QueryRequest(path: path, modifiers: modifierList), ); - yield* EventChannel(channelName).receiveGuardedBroadcastStream( - arguments: {'eventType': eventTypeToString(eventType)}, - onError: convertPlatformException, - ).map( - (event) => - MethodChannelDatabaseEvent(ref, Map.from(event)), - ); + yield* EventChannel(channelName) + .receiveGuardedBroadcastStream( + arguments: { + 'eventType': eventTypeToString(eventType), + }, + onError: convertPlatformException, + ) + .map( + (event) => + MethodChannelDatabaseEvent(ref, Map.from(event)), + ); } /// Gets the most up-to-date result for this query. @@ -73,22 +74,16 @@ class MethodChannelQuery extends QueryPlatform { try { final result = await _api.queryGet( _pigeonApp, - QueryRequest( - path: path, - modifiers: modifiers.toList(), - ), + QueryRequest(path: path, modifiers: modifiers.toList()), ); final snapshotData = result['snapshot']; if (snapshotData == null) { - return MethodChannelDataSnapshot( - ref, - { - 'key': ref.key, - 'value': null, - 'priority': null, - 'childKeys': [], - }, - ); + return MethodChannelDataSnapshot(ref, { + 'key': ref.key, + 'value': null, + 'priority': null, + 'childKeys': [], + }); } return MethodChannelDataSnapshot( ref, @@ -117,11 +112,7 @@ class MethodChannelQuery extends QueryPlatform { try { await _api.queryKeepSynced( _pigeonApp, - QueryRequest( - path: path, - modifiers: modifiers.toList(), - value: value, - ), + QueryRequest(path: path, modifiers: modifiers.toList(), value: value), ); } catch (e, s) { convertPlatformException(e, s); diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_transaction_result.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_transaction_result.dart index 0abbd19fce02..d574502dd9db 100644 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_transaction_result.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_transaction_result.dart @@ -8,7 +8,7 @@ import 'method_channel_data_snapshot.dart'; class MethodChannelTransactionResult extends TransactionResultPlatform { MethodChannelTransactionResult(bool committed, this._ref, this._snapshot) - : super(committed); + : super(committed); DatabaseReferencePlatform _ref; diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/pigeon/messages.pigeon.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/pigeon/messages.pigeon.dart index f8b622a7016a..c54d1cee9634 100644 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/pigeon/messages.pigeon.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/pigeon/messages.pigeon.dart @@ -37,8 +37,11 @@ Object? _extractReplyValueOrThrow( return replyList.firstOrNull; } -List wrapResponse( - {Object? result, PlatformException? error, bool empty = false}) { +List wrapResponse({ + Object? result, + PlatformException? error, + bool empty = false, +}) { if (empty) { return []; } @@ -60,8 +63,9 @@ bool _deepEquals(Object? a, Object? b) { } if (a is List && b is List) { return a.length == b.length && - a.indexed - .every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1])); + a.indexed.every( + ((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]), + ); } if (a is Map && b is Map) { if (a.length != b.length) { @@ -189,11 +193,7 @@ class DatabasePigeonFirebaseApp { DatabasePigeonSettings settings; List _toList() { - return [ - appName, - databaseURL, - settings, - ]; + return [appName, databaseURL, settings]; } Object encode() { @@ -230,16 +230,12 @@ class DatabasePigeonFirebaseApp { } class DatabaseReferencePlatform { - DatabaseReferencePlatform({ - required this.path, - }); + DatabaseReferencePlatform({required this.path}); String path; List _toList() { - return [ - path, - ]; + return [path]; } Object encode() { @@ -248,9 +244,7 @@ class DatabaseReferencePlatform { static DatabaseReferencePlatform decode(Object result) { result as List; - return DatabaseReferencePlatform( - path: result[0]! as String, - ); + return DatabaseReferencePlatform(path: result[0]! as String); } @override @@ -272,11 +266,7 @@ class DatabaseReferencePlatform { } class DatabaseReferenceRequest { - DatabaseReferenceRequest({ - required this.path, - this.value, - this.priority, - }); + DatabaseReferenceRequest({required this.path, this.value, this.priority}); String path; @@ -285,11 +275,7 @@ class DatabaseReferenceRequest { Object? priority; List _toList() { - return [ - path, - value, - priority, - ]; + return [path, value, priority]; } Object encode() { @@ -326,20 +312,14 @@ class DatabaseReferenceRequest { } class UpdateRequest { - UpdateRequest({ - required this.path, - required this.value, - }); + UpdateRequest({required this.path, required this.value}); String path; Map value; List _toList() { - return [ - path, - value, - ]; + return [path, value]; } Object encode() { @@ -385,11 +365,7 @@ class TransactionRequest { bool applyLocally; List _toList() { - return [ - path, - transactionKey, - applyLocally, - ]; + return [path, transactionKey, applyLocally]; } Object encode() { @@ -425,11 +401,7 @@ class TransactionRequest { } class QueryRequest { - QueryRequest({ - required this.path, - required this.modifiers, - this.value, - }); + QueryRequest({required this.path, required this.modifiers, this.value}); String path; @@ -438,11 +410,7 @@ class QueryRequest { bool? value; List _toList() { - return [ - path, - modifiers, - value, - ]; + return [path, modifiers, value]; } Object encode() { @@ -491,11 +459,7 @@ class TransactionHandlerResult { bool exception; List _toList() { - return [ - value, - aborted, - exception, - ]; + return [value, aborted, exception]; } Object encode() { @@ -596,11 +560,13 @@ class FirebaseDatabaseHostApi { /// Constructor for [FirebaseDatabaseHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - FirebaseDatabaseHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + FirebaseDatabaseHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -615,8 +581,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -634,8 +601,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -646,7 +614,9 @@ class FirebaseDatabaseHostApi { } Future setPersistenceEnabled( - DatabasePigeonFirebaseApp app, bool enabled) async { + DatabasePigeonFirebaseApp app, + bool enabled, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.setPersistenceEnabled$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -654,8 +624,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, enabled]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, enabled], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -666,7 +637,9 @@ class FirebaseDatabaseHostApi { } Future setPersistenceCacheSizeBytes( - DatabasePigeonFirebaseApp app, int cacheSize) async { + DatabasePigeonFirebaseApp app, + int cacheSize, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.setPersistenceCacheSizeBytes$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -674,8 +647,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, cacheSize]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, cacheSize], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -686,7 +660,9 @@ class FirebaseDatabaseHostApi { } Future setLoggingEnabled( - DatabasePigeonFirebaseApp app, bool enabled) async { + DatabasePigeonFirebaseApp app, + bool enabled, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.setLoggingEnabled$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -694,8 +670,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, enabled]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, enabled], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -706,7 +683,10 @@ class FirebaseDatabaseHostApi { } Future useDatabaseEmulator( - DatabasePigeonFirebaseApp app, String host, int port) async { + DatabasePigeonFirebaseApp app, + String host, + int port, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.useDatabaseEmulator$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -714,8 +694,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, host, port]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, host, port], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -725,8 +706,10 @@ class FirebaseDatabaseHostApi { ); } - Future ref(DatabasePigeonFirebaseApp app, - [String? path]) async { + Future ref( + DatabasePigeonFirebaseApp app, [ + String? path, + ]) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.ref$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -734,8 +717,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, path]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, path], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -747,7 +731,9 @@ class FirebaseDatabaseHostApi { } Future refFromURL( - DatabasePigeonFirebaseApp app, String url) async { + DatabasePigeonFirebaseApp app, + String url, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.refFromURL$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -755,8 +741,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, url]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, url], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -775,8 +762,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -787,7 +775,9 @@ class FirebaseDatabaseHostApi { } Future databaseReferenceSet( - DatabasePigeonFirebaseApp app, DatabaseReferenceRequest request) async { + DatabasePigeonFirebaseApp app, + DatabaseReferenceRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceSet$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -795,8 +785,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -807,7 +798,9 @@ class FirebaseDatabaseHostApi { } Future databaseReferenceSetWithPriority( - DatabasePigeonFirebaseApp app, DatabaseReferenceRequest request) async { + DatabasePigeonFirebaseApp app, + DatabaseReferenceRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceSetWithPriority$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -815,8 +808,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -827,7 +821,9 @@ class FirebaseDatabaseHostApi { } Future databaseReferenceUpdate( - DatabasePigeonFirebaseApp app, UpdateRequest request) async { + DatabasePigeonFirebaseApp app, + UpdateRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceUpdate$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -835,8 +831,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -847,7 +844,9 @@ class FirebaseDatabaseHostApi { } Future databaseReferenceSetPriority( - DatabasePigeonFirebaseApp app, DatabaseReferenceRequest request) async { + DatabasePigeonFirebaseApp app, + DatabaseReferenceRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceSetPriority$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -855,8 +854,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -867,7 +867,9 @@ class FirebaseDatabaseHostApi { } Future databaseReferenceRunTransaction( - DatabasePigeonFirebaseApp app, TransactionRequest request) async { + DatabasePigeonFirebaseApp app, + TransactionRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceRunTransaction$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -875,8 +877,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -887,7 +890,9 @@ class FirebaseDatabaseHostApi { } Future> databaseReferenceGetTransactionResult( - DatabasePigeonFirebaseApp app, int transactionKey) async { + DatabasePigeonFirebaseApp app, + int transactionKey, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceGetTransactionResult$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -895,8 +900,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, transactionKey]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, transactionKey], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -909,7 +915,9 @@ class FirebaseDatabaseHostApi { } Future onDisconnectSet( - DatabasePigeonFirebaseApp app, DatabaseReferenceRequest request) async { + DatabasePigeonFirebaseApp app, + DatabaseReferenceRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.onDisconnectSet$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -917,8 +925,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -929,7 +938,9 @@ class FirebaseDatabaseHostApi { } Future onDisconnectSetWithPriority( - DatabasePigeonFirebaseApp app, DatabaseReferenceRequest request) async { + DatabasePigeonFirebaseApp app, + DatabaseReferenceRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.onDisconnectSetWithPriority$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -937,8 +948,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -949,7 +961,9 @@ class FirebaseDatabaseHostApi { } Future onDisconnectUpdate( - DatabasePigeonFirebaseApp app, UpdateRequest request) async { + DatabasePigeonFirebaseApp app, + UpdateRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.onDisconnectUpdate$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -957,8 +971,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -969,7 +984,9 @@ class FirebaseDatabaseHostApi { } Future onDisconnectCancel( - DatabasePigeonFirebaseApp app, String path) async { + DatabasePigeonFirebaseApp app, + String path, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.onDisconnectCancel$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -977,8 +994,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, path]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, path], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -989,7 +1007,9 @@ class FirebaseDatabaseHostApi { } Future queryObserve( - DatabasePigeonFirebaseApp app, QueryRequest request) async { + DatabasePigeonFirebaseApp app, + QueryRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.queryObserve$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -997,8 +1017,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1010,7 +1031,9 @@ class FirebaseDatabaseHostApi { } Future queryKeepSynced( - DatabasePigeonFirebaseApp app, QueryRequest request) async { + DatabasePigeonFirebaseApp app, + QueryRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.queryKeepSynced$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1018,8 +1041,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -1030,7 +1054,9 @@ class FirebaseDatabaseHostApi { } Future> queryGet( - DatabasePigeonFirebaseApp app, QueryRequest request) async { + DatabasePigeonFirebaseApp app, + QueryRequest request, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.queryGet$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1038,8 +1064,9 @@ class FirebaseDatabaseHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, request]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, request], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1056,20 +1083,24 @@ abstract class FirebaseDatabaseFlutterApi { static const MessageCodec pigeonChannelCodec = _PigeonCodec(); Future callTransactionHandler( - int transactionKey, Object? snapshotValue); + int transactionKey, + Object? snapshotValue, + ); static void setUp( FirebaseDatabaseFlutterApi? api, { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseFlutterApi.callTransactionHandler$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseFlutterApi.callTransactionHandler$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { pigeonVar_channel.setMessageHandler(null); } else { @@ -1085,7 +1116,8 @@ abstract class FirebaseDatabaseFlutterApi { return wrapResponse(error: e); } catch (e) { return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); + error: PlatformException(code: 'error', message: e.toString()), + ); } }); } diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_database.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_database.dart index 44aa54648703..1645bed78ca6 100644 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_database.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_database.dart @@ -29,8 +29,10 @@ abstract class DatabasePlatform extends PlatformInterface { required FirebaseApp app, String? databaseURL, }) { - return DatabasePlatform.instance - .delegateFor(app: app, databaseURL: databaseURL); + return DatabasePlatform.instance.delegateFor( + app: app, + databaseURL: databaseURL, + ); } /// The current default [DatabasePlatform] instance. diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_database_reference.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_database_reference.dart index 94711b48f7cb..82c44d13ebb5 100755 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_database_reference.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_database_reference.dart @@ -15,9 +15,8 @@ import 'package:firebase_database_platform_interface/firebase_database_platform_ /// Note: [QueryPlatform] extends PlatformInterface already. abstract class DatabaseReferencePlatform extends QueryPlatform { /// Create a [DatabaseReferencePlatform] using [pathComponents] - DatabaseReferencePlatform._( - DatabasePlatform database, - ) : super(database: database); + DatabaseReferencePlatform._(DatabasePlatform database) + : super(database: database); /// Gets a DatabaseReference for the location at the specified relative /// path. The relative path can either be a simple child key (e.g. ‘fred’) or diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_on_disconnect.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_on_disconnect.dart index d5fc6367cee3..459274daa720 100755 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_on_disconnect.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_on_disconnect.dart @@ -10,7 +10,7 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; abstract class OnDisconnectPlatform extends PlatformInterface { /// Create a [OnDisconnectPlatform] instance OnDisconnectPlatform({required this.database, required this.ref}) - : super(token: _token); + : super(token: _token); /// Throws an [AssertionError] if [instance] does not extend /// [OnDisconnectPlatform]. diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_query.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_query.dart index 157e9b7eee10..2c38dd86e7c2 100755 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_query.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_query.dart @@ -23,9 +23,7 @@ abstract class QueryPlatform extends PlatformInterface { } /// Create a [QueryPlatform] instance - QueryPlatform({ - required this.database, - }) : super(token: _token); + QueryPlatform({required this.database}) : super(token: _token); /// Returns the path to this reference. String get path { diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_transaction_result.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_transaction_result.dart index 9a7dd9ab2ec7..700d713e81ed 100644 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_transaction_result.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/platform_interface/platform_interface_transaction_result.dart @@ -11,9 +11,7 @@ typedef TransactionHandler = Transaction Function(Object? value); /// Interface for [TransactionResultPlatform] class TransactionResultPlatform extends PlatformInterface { /// Constructor for [TransactionResultPlatform] - TransactionResultPlatform( - this.committed, - ) : super(token: _token); + TransactionResultPlatform(this.committed) : super(token: _token); /// Throws an [AssertionError] if [instance] does not extend /// [TransactionResultPlatform]. diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/query_modifiers.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/query_modifiers.dart index 528a16749e50..5296de4afae1 100644 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/query_modifiers.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/query_modifiers.dart @@ -177,29 +177,29 @@ class LimitModifier implements QueryModifier { /// A modifier representing a start cursor query. class StartCursorModifier extends _CursorModifier { StartCursorModifier._(String name, Object? value, String? key) - : super(name, value, key); + : super(name, value, key); /// Creates a new `startAt` modifier with an optional key. StartCursorModifier.startAt(Object? value, String? key) - : this._('startAt', value, key); + : this._('startAt', value, key); /// Creates a new `startAfter` modifier with an optional key. StartCursorModifier.startAfter(Object? value, String? key) - : this._('startAfter', value, key); + : this._('startAfter', value, key); } /// A modifier representing a end cursor query. class EndCursorModifier extends _CursorModifier { EndCursorModifier._(String name, Object? value, String? key) - : super(name, value, key); + : super(name, value, key); /// Creates a new `endAt` modifier with an optional key. EndCursorModifier.endAt(Object? value, String? key) - : this._('endAt', value, key); + : this._('endAt', value, key); /// Creates a new `endBefore` modifier with an optional key. EndCursorModifier.endBefore(Object? value, String? key) - : this._('endBefore', value, key); + : this._('endBefore', value, key); } /// Underlying cursor query modifier for start and end points. diff --git a/packages/firebase_database/firebase_database_platform_interface/pigeons/messages.dart b/packages/firebase_database/firebase_database_platform_interface/pigeons/messages.dart index 2db035bbae4c..2a7583eb2839 100644 --- a/packages/firebase_database/firebase_database_platform_interface/pigeons/messages.dart +++ b/packages/firebase_database/firebase_database_platform_interface/pigeons/messages.dart @@ -51,9 +51,7 @@ class DatabasePigeonFirebaseApp { } class DatabaseReferencePlatform { - const DatabaseReferencePlatform({ - required this.path, - }); + const DatabaseReferencePlatform({required this.path}); final String path; } @@ -71,10 +69,7 @@ class DatabaseReferenceRequest { } class UpdateRequest { - const UpdateRequest({ - required this.path, - required this.value, - }); + const UpdateRequest({required this.path, required this.value}); final String path; final Map value; @@ -93,11 +88,7 @@ class TransactionRequest { } class QueryRequest { - const QueryRequest({ - required this.path, - required this.modifiers, - this.value, - }); + const QueryRequest({required this.path, required this.modifiers, this.value}); final String path; final List> modifiers; @@ -117,21 +108,28 @@ abstract class FirebaseDatabaseHostApi { @async void setPersistenceCacheSizeBytes( - DatabasePigeonFirebaseApp app, int cacheSize); + DatabasePigeonFirebaseApp app, + int cacheSize, + ); @async void setLoggingEnabled(DatabasePigeonFirebaseApp app, bool enabled); @async void useDatabaseEmulator( - DatabasePigeonFirebaseApp app, String host, int port); + DatabasePigeonFirebaseApp app, + String host, + int port, + ); @async DatabaseReferencePlatform ref(DatabasePigeonFirebaseApp app, [String? path]); @async DatabaseReferencePlatform refFromURL( - DatabasePigeonFirebaseApp app, String url); + DatabasePigeonFirebaseApp app, + String url, + ); @async void purgeOutstandingWrites(DatabasePigeonFirebaseApp app); @@ -139,36 +137,52 @@ abstract class FirebaseDatabaseHostApi { // DatabaseReference methods @async void databaseReferenceSet( - DatabasePigeonFirebaseApp app, DatabaseReferenceRequest request); + DatabasePigeonFirebaseApp app, + DatabaseReferenceRequest request, + ); @async void databaseReferenceSetWithPriority( - DatabasePigeonFirebaseApp app, DatabaseReferenceRequest request); + DatabasePigeonFirebaseApp app, + DatabaseReferenceRequest request, + ); @async void databaseReferenceUpdate( - DatabasePigeonFirebaseApp app, UpdateRequest request); + DatabasePigeonFirebaseApp app, + UpdateRequest request, + ); @async void databaseReferenceSetPriority( - DatabasePigeonFirebaseApp app, DatabaseReferenceRequest request); + DatabasePigeonFirebaseApp app, + DatabaseReferenceRequest request, + ); @async void databaseReferenceRunTransaction( - DatabasePigeonFirebaseApp app, TransactionRequest request); + DatabasePigeonFirebaseApp app, + TransactionRequest request, + ); @async Map databaseReferenceGetTransactionResult( - DatabasePigeonFirebaseApp app, int transactionKey); + DatabasePigeonFirebaseApp app, + int transactionKey, + ); // OnDisconnect methods @async void onDisconnectSet( - DatabasePigeonFirebaseApp app, DatabaseReferenceRequest request); + DatabasePigeonFirebaseApp app, + DatabaseReferenceRequest request, + ); @async void onDisconnectSetWithPriority( - DatabasePigeonFirebaseApp app, DatabaseReferenceRequest request); + DatabasePigeonFirebaseApp app, + DatabaseReferenceRequest request, + ); @async void onDisconnectUpdate(DatabasePigeonFirebaseApp app, UpdateRequest request); @@ -185,7 +199,9 @@ abstract class FirebaseDatabaseHostApi { @async Map queryGet( - DatabasePigeonFirebaseApp app, QueryRequest request); + DatabasePigeonFirebaseApp app, + QueryRequest request, + ); } class TransactionHandlerResult { @@ -205,5 +221,7 @@ class TransactionHandlerResult { abstract class FirebaseDatabaseFlutterApi { @async TransactionHandlerResult callTransactionHandler( - int transactionKey, Object? snapshotValue); + int transactionKey, + Object? snapshotValue, + ); } diff --git a/packages/firebase_database/firebase_database_platform_interface/pubspec.yaml b/packages/firebase_database/firebase_database_platform_interface/pubspec.yaml index b71223843a97..e7a1598fcf4b 100755 --- a/packages/firebase_database/firebase_database_platform_interface/pubspec.yaml +++ b/packages/firebase_database/firebase_database_platform_interface/pubspec.yaml @@ -5,8 +5,8 @@ resolution: workspace homepage: https://github.com/firebase/flutterfire/tree/main/packages/firebase_database/firebase_database_platform_interface environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_database/firebase_database_platform_interface/test/method_channel_test.dart b/packages/firebase_database/firebase_database_platform_interface/test/method_channel_test.dart index f21a7ba0bb07..1a747d9256cf 100755 --- a/packages/firebase_database/firebase_database_platform_interface/test/method_channel_test.dart +++ b/packages/firebase_database/firebase_database_platform_interface/test/method_channel_test.dart @@ -34,9 +34,11 @@ class MockFirebaseDatabaseHostApi implements TestFirebaseDatabaseHostApi { pigeon.DatabasePigeonFirebaseApp app, bool enabled, ) async { - log.add( - {'method': 'setPersistenceEnabled', 'app': app, 'enabled': enabled}, - ); + log.add({ + 'method': 'setPersistenceEnabled', + 'app': app, + 'enabled': enabled, + }); } @override @@ -75,13 +77,12 @@ class MockFirebaseDatabaseHostApi implements TestFirebaseDatabaseHostApi { @override Future ref( - pigeon.DatabasePigeonFirebaseApp app, - // ignore: require_trailing_commas - [String? path]) async { + pigeon.DatabasePigeonFirebaseApp app, [ + // ignore: require_trailing_commas + String? path, + ]) async { log.add({'method': 'ref', 'app': app, 'path': path}); - return pigeon.DatabaseReferencePlatform( - path: path ?? '', - ); + return pigeon.DatabaseReferencePlatform(path: path ?? ''); } @override @@ -90,9 +91,7 @@ class MockFirebaseDatabaseHostApi implements TestFirebaseDatabaseHostApi { String url, ) async { log.add({'method': 'refFromURL', 'app': app, 'url': url}); - return pigeon.DatabaseReferencePlatform( - path: '', - ); + return pigeon.DatabaseReferencePlatform(path: ''); } @override @@ -127,9 +126,11 @@ class MockFirebaseDatabaseHostApi implements TestFirebaseDatabaseHostApi { pigeon.DatabasePigeonFirebaseApp app, pigeon.UpdateRequest request, ) async { - log.add( - {'method': 'databaseReferenceUpdate', 'app': app, 'request': request}, - ); + log.add({ + 'method': 'databaseReferenceUpdate', + 'app': app, + 'request': request, + }); } @override @@ -236,10 +237,7 @@ class MockFirebaseDatabaseHostApi implements TestFirebaseDatabaseHostApi { pigeon.QueryRequest request, ) async { log.add({'method': 'queryGet', 'app': app, 'request': request}); - return { - 'value': 'test-value', - 'key': 'test-key', - }; + return {'value': 'test-value', 'key': 'test-key'}; } } @@ -281,46 +279,30 @@ void main() { database.useDatabaseEmulator('localhost', 1234); // Options are only sent on subsequent calls to Pigeon. await database.goOnline(); - expect( - mockApi.log, - [ - containsPair('method', 'setLoggingEnabled'), - containsPair('method', 'setPersistenceCacheSizeBytes'), - containsPair('method', 'setPersistenceEnabled'), - containsPair('method', 'useDatabaseEmulator'), - containsPair('method', 'goOnline'), - ], - ); + expect(mockApi.log, [ + containsPair('method', 'setLoggingEnabled'), + containsPair('method', 'setPersistenceCacheSizeBytes'), + containsPair('method', 'setPersistenceEnabled'), + containsPair('method', 'useDatabaseEmulator'), + containsPair('method', 'goOnline'), + ]); }); test('goOnline', () async { await database.goOnline(); - expect( - mockApi.log, - [ - containsPair('method', 'goOnline'), - ], - ); + expect(mockApi.log, [containsPair('method', 'goOnline')]); }); test('goOffline', () async { await database.goOffline(); - expect( - mockApi.log, - [ - containsPair('method', 'goOffline'), - ], - ); + expect(mockApi.log, [containsPair('method', 'goOffline')]); }); test('purgeOutstandingWrites', () async { await database.purgeOutstandingWrites(); - expect( - mockApi.log, - [ - containsPair('method', 'purgeOutstandingWrites'), - ], - ); + expect(mockApi.log, [ + containsPair('method', 'purgeOutstandingWrites'), + ]); }); group('$MethodChannelDatabaseReference', () { @@ -334,36 +316,27 @@ void main() { await database.ref('bar').setWithPriority(value, priority); await database.ref('bar').setWithPriority(value, null); await database.ref('baz').set(serverValue); - expect( - mockApi.log, - [ - containsPair('method', 'databaseReferenceSet'), - containsPair('method', 'databaseReferenceSetWithPriority'), - containsPair('method', 'databaseReferenceSetWithPriority'), - containsPair('method', 'databaseReferenceSet'), - ], - ); + expect(mockApi.log, [ + containsPair('method', 'databaseReferenceSet'), + containsPair('method', 'databaseReferenceSetWithPriority'), + containsPair('method', 'databaseReferenceSetWithPriority'), + containsPair('method', 'databaseReferenceSet'), + ]); }); test('update', () async { final dynamic value = {'hello': 'world'}; await database.ref('foo').update(value); - expect( - mockApi.log, - [ - containsPair('method', 'databaseReferenceUpdate'), - ], - ); + expect(mockApi.log, [ + containsPair('method', 'databaseReferenceUpdate'), + ]); }); test('setPriority', () async { const int priority = 42; await database.ref('foo').setPriority(priority); - expect( - mockApi.log, - [ - containsPair('method', 'databaseReferenceSetPriority'), - ], - ); + expect(mockApi.log, [ + containsPair('method', 'databaseReferenceSetPriority'), + ]); }); test('runTransaction', () async { @@ -376,13 +349,10 @@ void main() { }); }); - expect( - mockApi.log, - [ - containsPair('method', 'databaseReferenceRunTransaction'), - containsPair('method', 'databaseReferenceGetTransactionResult'), - ], - ); + expect(mockApi.log, [ + containsPair('method', 'databaseReferenceRunTransaction'), + containsPair('method', 'databaseReferenceGetTransactionResult'), + ]); expect(result.committed, equals(true)); @@ -406,44 +376,32 @@ void main() { .setWithPriority(value, 'priority'); await ref.child('por').onDisconnect().setWithPriority(value, value); await ref.child('por').onDisconnect().setWithPriority(value, null); - expect( - mockApi.log, - [ - containsPair('method', 'onDisconnectSet'), - containsPair('method', 'onDisconnectSetWithPriority'), - containsPair('method', 'onDisconnectSetWithPriority'), - containsPair('method', 'onDisconnectSetWithPriority'), - containsPair('method', 'onDisconnectSetWithPriority'), - ], - ); + expect(mockApi.log, [ + containsPair('method', 'onDisconnectSet'), + containsPair('method', 'onDisconnectSetWithPriority'), + containsPair('method', 'onDisconnectSetWithPriority'), + containsPair('method', 'onDisconnectSetWithPriority'), + containsPair('method', 'onDisconnectSetWithPriority'), + ]); }); test('update', () async { final dynamic value = {'hello': 'world'}; await database.ref('foo').onDisconnect().update(value); - expect( - mockApi.log, - [ - containsPair('method', 'onDisconnectUpdate'), - ], - ); + expect(mockApi.log, [ + containsPair('method', 'onDisconnectUpdate'), + ]); }); test('cancel', () async { await database.ref('foo').onDisconnect().cancel(); - expect( - mockApi.log, - [ - containsPair('method', 'onDisconnectCancel'), - ], - ); + expect(mockApi.log, [ + containsPair('method', 'onDisconnectCancel'), + ]); }); test('remove', () async { await database.ref('foo').onDisconnect().remove(); - expect( - mockApi.log, - [ - containsPair('method', 'onDisconnectSet'), - ], - ); + expect(mockApi.log, [ + containsPair('method', 'onDisconnectSet'), + ]); }); }); @@ -452,12 +410,9 @@ void main() { const String path = 'foo'; final QueryPlatform query = database.ref(path); await query.keepSynced(QueryModifiers([]), true); - expect( - mockApi.log, - [ - containsPair('method', 'queryKeepSynced'), - ], - ); + expect(mockApi.log, [ + containsPair('method', 'queryKeepSynced'), + ]); }); test('observing error events', () async { const String errorCode = 'some-error'; @@ -466,19 +421,17 @@ void main() { Future simulateError(String errorMessage) async { await TestDefaultBinaryMessengerBinding - .instance.defaultBinaryMessenger + .instance + .defaultBinaryMessenger .handlePlatformMessage( - eventChannel.name, - eventChannel.codec.encodeErrorEnvelope( - code: errorCode, - message: errorMessage, - details: { - 'code': errorCode, - 'message': errorMessage, - }, - ), - (_) {}, - ); + eventChannel.name, + eventChannel.codec.encodeErrorEnvelope( + code: errorCode, + message: errorMessage, + details: {'code': errorCode, 'message': errorMessage}, + ), + (_) {}, + ); } final errors = AsyncQueue(); @@ -514,21 +467,19 @@ void main() { Future simulateEvent(Map event) async { await TestDefaultBinaryMessengerBinding - .instance.defaultBinaryMessenger + .instance + .defaultBinaryMessenger .handlePlatformMessage( - eventChannel.name, - eventChannel.codec.encodeSuccessEnvelope(event), - (_) {}, - ); + eventChannel.name, + eventChannel.codec.encodeSuccessEnvelope(event), + (_) {}, + ); } Map createValueEvent(dynamic value) { return { 'eventType': 'value', - 'snapshot': { - 'value': value, - 'key': path.split('/').last, - }, + 'snapshot': {'value': value, 'key': path.split('/').last}, }; } @@ -536,8 +487,9 @@ void main() { AsyncQueue(); // Subscribe and allow subscription to complete. - final subscription = - query.onValue(QueryModifiers([])).listen(events.add); + final subscription = query + .onValue(QueryModifiers([])) + .listen(events.add); await Future.delayed(Duration.zero); await simulateEvent(createValueEvent(1)); @@ -555,12 +507,7 @@ void main() { await subscription.cancel(); await Future.delayed(Duration.zero); - expect( - mockApi.log, - [ - containsPair('method', 'queryObserve'), - ], - ); + expect(mockApi.log, [containsPair('method', 'queryObserve')]); }); }); }); diff --git a/packages/firebase_database/firebase_database_platform_interface/test/pigeon/test_api.dart b/packages/firebase_database/firebase_database_platform_interface/test/pigeon/test_api.dart index da5370c5adb2..aa6ee89a2f6d 100644 --- a/packages/firebase_database/firebase_database_platform_interface/test/pigeon/test_api.dart +++ b/packages/firebase_database/firebase_database_platform_interface/test/pigeon/test_api.dart @@ -84,691 +84,874 @@ abstract class TestFirebaseDatabaseHostApi { Future goOffline(DatabasePigeonFirebaseApp app); Future setPersistenceEnabled( - DatabasePigeonFirebaseApp app, bool enabled); + DatabasePigeonFirebaseApp app, + bool enabled, + ); Future setPersistenceCacheSizeBytes( - DatabasePigeonFirebaseApp app, int cacheSize); + DatabasePigeonFirebaseApp app, + int cacheSize, + ); Future setLoggingEnabled(DatabasePigeonFirebaseApp app, bool enabled); Future useDatabaseEmulator( - DatabasePigeonFirebaseApp app, String host, int port); + DatabasePigeonFirebaseApp app, + String host, + int port, + ); - Future ref(DatabasePigeonFirebaseApp app, - [String? path]); + Future ref( + DatabasePigeonFirebaseApp app, [ + String? path, + ]); Future refFromURL( - DatabasePigeonFirebaseApp app, String url); + DatabasePigeonFirebaseApp app, + String url, + ); Future purgeOutstandingWrites(DatabasePigeonFirebaseApp app); Future databaseReferenceSet( - DatabasePigeonFirebaseApp app, DatabaseReferenceRequest request); + DatabasePigeonFirebaseApp app, + DatabaseReferenceRequest request, + ); Future databaseReferenceSetWithPriority( - DatabasePigeonFirebaseApp app, DatabaseReferenceRequest request); + DatabasePigeonFirebaseApp app, + DatabaseReferenceRequest request, + ); Future databaseReferenceUpdate( - DatabasePigeonFirebaseApp app, UpdateRequest request); + DatabasePigeonFirebaseApp app, + UpdateRequest request, + ); Future databaseReferenceSetPriority( - DatabasePigeonFirebaseApp app, DatabaseReferenceRequest request); + DatabasePigeonFirebaseApp app, + DatabaseReferenceRequest request, + ); Future databaseReferenceRunTransaction( - DatabasePigeonFirebaseApp app, TransactionRequest request); + DatabasePigeonFirebaseApp app, + TransactionRequest request, + ); Future> databaseReferenceGetTransactionResult( - DatabasePigeonFirebaseApp app, int transactionKey); + DatabasePigeonFirebaseApp app, + int transactionKey, + ); Future onDisconnectSet( - DatabasePigeonFirebaseApp app, DatabaseReferenceRequest request); + DatabasePigeonFirebaseApp app, + DatabaseReferenceRequest request, + ); Future onDisconnectSetWithPriority( - DatabasePigeonFirebaseApp app, DatabaseReferenceRequest request); + DatabasePigeonFirebaseApp app, + DatabaseReferenceRequest request, + ); Future onDisconnectUpdate( - DatabasePigeonFirebaseApp app, UpdateRequest request); + DatabasePigeonFirebaseApp app, + UpdateRequest request, + ); Future onDisconnectCancel(DatabasePigeonFirebaseApp app, String path); Future queryObserve( - DatabasePigeonFirebaseApp app, QueryRequest request); + DatabasePigeonFirebaseApp app, + QueryRequest request, + ); Future queryKeepSynced( - DatabasePigeonFirebaseApp app, QueryRequest request); + DatabasePigeonFirebaseApp app, + QueryRequest request, + ); Future> queryGet( - DatabasePigeonFirebaseApp app, QueryRequest request); + DatabasePigeonFirebaseApp app, + QueryRequest request, + ); static void setUp( TestFirebaseDatabaseHostApi? api, { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.goOnline$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.goOnline$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - try { - await api.goOnline(arg_app); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + try { + await api.goOnline(arg_app); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.goOffline$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.goOffline$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - try { - await api.goOffline(arg_app); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + try { + await api.goOffline(arg_app); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.setPersistenceEnabled$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.setPersistenceEnabled$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final bool arg_enabled = args[1]! as bool; - try { - await api.setPersistenceEnabled(arg_app, arg_enabled); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final bool arg_enabled = args[1]! as bool; + try { + await api.setPersistenceEnabled(arg_app, arg_enabled); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.setPersistenceCacheSizeBytes$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.setPersistenceCacheSizeBytes$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final int arg_cacheSize = args[1]! as int; - try { - await api.setPersistenceCacheSizeBytes(arg_app, arg_cacheSize); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final int arg_cacheSize = args[1]! as int; + try { + await api.setPersistenceCacheSizeBytes(arg_app, arg_cacheSize); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.setLoggingEnabled$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.setLoggingEnabled$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final bool arg_enabled = args[1]! as bool; - try { - await api.setLoggingEnabled(arg_app, arg_enabled); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final bool arg_enabled = args[1]! as bool; + try { + await api.setLoggingEnabled(arg_app, arg_enabled); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.useDatabaseEmulator$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.useDatabaseEmulator$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final String arg_host = args[1]! as String; - final int arg_port = args[2]! as int; - try { - await api.useDatabaseEmulator(arg_app, arg_host, arg_port); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final String arg_host = args[1]! as String; + final int arg_port = args[2]! as int; + try { + await api.useDatabaseEmulator(arg_app, arg_host, arg_port); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.ref$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.ref$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final String? arg_path = args[1] as String?; - try { - final DatabaseReferencePlatform output = - await api.ref(arg_app, arg_path); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final String? arg_path = args[1] as String?; + try { + final DatabaseReferencePlatform output = await api.ref( + arg_app, + arg_path, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.refFromURL$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.refFromURL$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final String arg_url = args[1]! as String; - try { - final DatabaseReferencePlatform output = - await api.refFromURL(arg_app, arg_url); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final String arg_url = args[1]! as String; + try { + final DatabaseReferencePlatform output = await api.refFromURL( + arg_app, + arg_url, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.purgeOutstandingWrites$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.purgeOutstandingWrites$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - try { - await api.purgeOutstandingWrites(arg_app); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + try { + await api.purgeOutstandingWrites(arg_app); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceSet$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceSet$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final DatabaseReferenceRequest arg_request = - args[1]! as DatabaseReferenceRequest; - try { - await api.databaseReferenceSet(arg_app, arg_request); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final DatabaseReferenceRequest arg_request = + args[1]! as DatabaseReferenceRequest; + try { + await api.databaseReferenceSet(arg_app, arg_request); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceSetWithPriority$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceSetWithPriority$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final DatabaseReferenceRequest arg_request = - args[1]! as DatabaseReferenceRequest; - try { - await api.databaseReferenceSetWithPriority(arg_app, arg_request); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final DatabaseReferenceRequest arg_request = + args[1]! as DatabaseReferenceRequest; + try { + await api.databaseReferenceSetWithPriority( + arg_app, + arg_request, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceUpdate$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceUpdate$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final UpdateRequest arg_request = args[1]! as UpdateRequest; - try { - await api.databaseReferenceUpdate(arg_app, arg_request); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final UpdateRequest arg_request = args[1]! as UpdateRequest; + try { + await api.databaseReferenceUpdate(arg_app, arg_request); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceSetPriority$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceSetPriority$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final DatabaseReferenceRequest arg_request = - args[1]! as DatabaseReferenceRequest; - try { - await api.databaseReferenceSetPriority(arg_app, arg_request); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final DatabaseReferenceRequest arg_request = + args[1]! as DatabaseReferenceRequest; + try { + await api.databaseReferenceSetPriority(arg_app, arg_request); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceRunTransaction$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceRunTransaction$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final TransactionRequest arg_request = args[1]! as TransactionRequest; - try { - await api.databaseReferenceRunTransaction(arg_app, arg_request); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final TransactionRequest arg_request = + args[1]! as TransactionRequest; + try { + await api.databaseReferenceRunTransaction(arg_app, arg_request); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceGetTransactionResult$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.databaseReferenceGetTransactionResult$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final int arg_transactionKey = args[1]! as int; - try { - final Map output = - await api.databaseReferenceGetTransactionResult( - arg_app, arg_transactionKey); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final int arg_transactionKey = args[1]! as int; + try { + final Map output = await api + .databaseReferenceGetTransactionResult( + arg_app, + arg_transactionKey, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.onDisconnectSet$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.onDisconnectSet$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final DatabaseReferenceRequest arg_request = - args[1]! as DatabaseReferenceRequest; - try { - await api.onDisconnectSet(arg_app, arg_request); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final DatabaseReferenceRequest arg_request = + args[1]! as DatabaseReferenceRequest; + try { + await api.onDisconnectSet(arg_app, arg_request); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.onDisconnectSetWithPriority$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.onDisconnectSetWithPriority$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final DatabaseReferenceRequest arg_request = - args[1]! as DatabaseReferenceRequest; - try { - await api.onDisconnectSetWithPriority(arg_app, arg_request); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final DatabaseReferenceRequest arg_request = + args[1]! as DatabaseReferenceRequest; + try { + await api.onDisconnectSetWithPriority(arg_app, arg_request); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.onDisconnectUpdate$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.onDisconnectUpdate$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final UpdateRequest arg_request = args[1]! as UpdateRequest; - try { - await api.onDisconnectUpdate(arg_app, arg_request); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final UpdateRequest arg_request = args[1]! as UpdateRequest; + try { + await api.onDisconnectUpdate(arg_app, arg_request); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.onDisconnectCancel$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.onDisconnectCancel$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final String arg_path = args[1]! as String; - try { - await api.onDisconnectCancel(arg_app, arg_path); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final String arg_path = args[1]! as String; + try { + await api.onDisconnectCancel(arg_app, arg_path); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.queryObserve$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.queryObserve$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final QueryRequest arg_request = args[1]! as QueryRequest; - try { - final String output = await api.queryObserve(arg_app, arg_request); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final QueryRequest arg_request = args[1]! as QueryRequest; + try { + final String output = await api.queryObserve( + arg_app, + arg_request, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.queryKeepSynced$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.queryKeepSynced$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final QueryRequest arg_request = args[1]! as QueryRequest; - try { - await api.queryKeepSynced(arg_app, arg_request); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final QueryRequest arg_request = args[1]! as QueryRequest; + try { + await api.queryKeepSynced(arg_app, arg_request); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.queryGet$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_database_platform_interface.FirebaseDatabaseHostApi.queryGet$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final DatabasePigeonFirebaseApp arg_app = - args[0]! as DatabasePigeonFirebaseApp; - final QueryRequest arg_request = args[1]! as QueryRequest; - try { - final Map output = - await api.queryGet(arg_app, arg_request); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final DatabasePigeonFirebaseApp arg_app = + args[0]! as DatabasePigeonFirebaseApp; + final QueryRequest arg_request = args[1]! as QueryRequest; + try { + final Map output = await api.queryGet( + arg_app, + arg_request, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } diff --git a/packages/firebase_database/firebase_database_platform_interface/test/query_modifiers_test.dart b/packages/firebase_database/firebase_database_platform_interface/test/query_modifiers_test.dart index 50cafc7efcd0..6b59683dd4c8 100644 --- a/packages/firebase_database/firebase_database_platform_interface/test/query_modifiers_test.dart +++ b/packages/firebase_database/firebase_database_platform_interface/test/query_modifiers_test.dart @@ -20,8 +20,9 @@ void main() { group('start()', () { test('fails assertion if a starting point is already set', () { final instance = QueryModifiers([]); - final modifier = - instance.start(StartCursorModifier.startAt('foo', 'bar')); + final modifier = instance.start( + StartCursorModifier.startAt('foo', 'bar'), + ); expect( () => modifier.start(StartCursorModifier.startAfter('foo', 'bar')), @@ -42,8 +43,9 @@ void main() { final instance = QueryModifiers([]); expect(instance.toList().length, 0); - final modifiers = - instance.start(StartCursorModifier.startAfter('foo', 'bar')); + final modifiers = instance.start( + StartCursorModifier.startAfter('foo', 'bar'), + ); expect( modifiers.toList(), @@ -53,7 +55,7 @@ void main() { 'name': 'startAfter', 'value': 'foo', 'key': 'bar', - } + }, ]), ); }); @@ -149,10 +151,7 @@ void main() { expect( modifiers.toList(), equals([ - { - 'type': 'orderBy', - 'name': 'orderByPriority', - } + {'type': 'orderBy', 'name': 'orderByPriority'}, ]), ); }); @@ -160,59 +159,68 @@ void main() { group('validation', () { test( - 'it fails assertion when ordering by key, but the key provided to a cursor modifier is also set', - () { - final instance = QueryModifiers([]); + 'it fails assertion when ordering by key, but the key provided to a cursor modifier is also set', + () { + final instance = QueryModifiers([]); - final modifiers = - instance.start(StartCursorModifier.startAt('foo', 'bar')); + final modifiers = instance.start( + StartCursorModifier.startAt('foo', 'bar'), + ); - expect( - () => modifiers.order(OrderModifier.orderByKey()), - throwsAssertionError, - ); - }); + expect( + () => modifiers.order(OrderModifier.orderByKey()), + throwsAssertionError, + ); + }, + ); test( - 'it fails assertion when ordering by key, but the value provided to a cursor modifier is not a string', - () { - final instance = QueryModifiers([]); + 'it fails assertion when ordering by key, but the value provided to a cursor modifier is not a string', + () { + final instance = QueryModifiers([]); - final modifiers = - instance.start(StartCursorModifier.startAt(123, null)); + final modifiers = instance.start( + StartCursorModifier.startAt(123, null), + ); - expect( - () => modifiers.order(OrderModifier.orderByKey()), - throwsAssertionError, - ); - }); + expect( + () => modifiers.order(OrderModifier.orderByKey()), + throwsAssertionError, + ); + }, + ); test( - 'it fails assertion when ordering by priority, but start cursor value is not a valid priority value', - () { - final instance = QueryModifiers([]); + 'it fails assertion when ordering by priority, but start cursor value is not a valid priority value', + () { + final instance = QueryModifiers([]); - final modifiers = - instance.start(StartCursorModifier.startAfter(true, null)); + final modifiers = instance.start( + StartCursorModifier.startAfter(true, null), + ); - expect( - () => modifiers.order(OrderModifier.orderByPriority()), - throwsAssertionError, - ); - }); + expect( + () => modifiers.order(OrderModifier.orderByPriority()), + throwsAssertionError, + ); + }, + ); test( - 'it fails assertion when ordering by priority, but end cursor value is not a valid priority value', - () { - final instance = QueryModifiers([]); - - final modifiers = instance.end(EndCursorModifier.endBefore(true, null)); - - expect( - () => modifiers.order(OrderModifier.orderByPriority()), - throwsAssertionError, - ); - }); + 'it fails assertion when ordering by priority, but end cursor value is not a valid priority value', + () { + final instance = QueryModifiers([]); + + final modifiers = instance.end( + EndCursorModifier.endBefore(true, null), + ); + + expect( + () => modifiers.order(OrderModifier.orderByPriority()), + throwsAssertionError, + ); + }, + ); }); }); } diff --git a/packages/firebase_database/firebase_database_web/lib/firebase_database_web.dart b/packages/firebase_database/firebase_database_web/lib/firebase_database_web.dart index 5cb2ec1bef79..244b7a296c5f 100755 --- a/packages/firebase_database/firebase_database_web/lib/firebase_database_web.dart +++ b/packages/firebase_database/firebase_database_web/lib/firebase_database_web.dart @@ -36,11 +36,8 @@ class FirebaseDatabaseWeb extends DatabasePlatform { /// Lazily initialize [_firebaseDatabase] on first method call database_interop.Database get _delegate { - return _firebaseDatabase ??= - _firebaseDatabase = database_interop.getDatabaseInstance( - core_interop.app(app?.name), - databaseURL, - ); + return _firebaseDatabase ??= _firebaseDatabase = database_interop + .getDatabaseInstance(core_interop.app(app?.name), databaseURL); } /// Called by PluginRegistry to register this plugin for Flutter Web @@ -56,8 +53,10 @@ class FirebaseDatabaseWeb extends DatabasePlatform { FirebaseDatabaseWeb({super.app, super.databaseURL}); @override - DatabasePlatform delegateFor( - {required FirebaseApp app, String? databaseURL}) { + DatabasePlatform delegateFor({ + required FirebaseApp app, + String? databaseURL, + }) { return FirebaseDatabaseWeb(app: app, databaseURL: databaseURL); } @@ -83,7 +82,8 @@ class FirebaseDatabaseWeb extends DatabasePlatform { @override void setPersistenceCacheSizeBytes(int cacheSize) { throw UnsupportedError( - "setPersistenceCacheSizeBytes() is not supported for web"); + "setPersistenceCacheSizeBytes() is not supported for web", + ); } @override @@ -124,7 +124,8 @@ class FirebaseDatabaseWeb extends DatabasePlatform { // Hot reload keeps state, so ignore if this is thrown. if (exception.message != null && exception.message!.contains( - 'Cannot call useEmulator() after instance has already been initialized')) { + 'Cannot call useEmulator() after instance has already been initialized', + )) { return; } diff --git a/packages/firebase_database/firebase_database_web/lib/src/data_snapshot_web.dart b/packages/firebase_database/firebase_database_web/lib/src/data_snapshot_web.dart index f077fc3a7caa..8cbbc4dec42f 100644 --- a/packages/firebase_database/firebase_database_web/lib/src/data_snapshot_web.dart +++ b/packages/firebase_database/firebase_database_web/lib/src/data_snapshot_web.dart @@ -9,11 +9,11 @@ class DataSnapshotWeb extends DataSnapshotPlatform { final database_interop.DataSnapshot _delegate; DataSnapshotWeb(DatabaseReferencePlatform ref, this._delegate) - : super(ref, { - 'key': _delegate.key, - 'value': _delegate.val(), - 'priority': _delegate.getPriority(), - }); + : super(ref, { + 'key': _delegate.key, + 'value': _delegate.val(), + 'priority': _delegate.getPriority(), + }); @override DataSnapshotPlatform child(String childPath) { @@ -29,8 +29,9 @@ class DataSnapshotWeb extends DataSnapshotPlatform { snapshots.add(snapshot); }); - return Iterable.generate(snapshots.length, - (int index) { + return Iterable.generate(snapshots.length, ( + int index, + ) { database_interop.DataSnapshot snapshot = snapshots[index]; return DataSnapshotWeb(ref.child(snapshot.key!), snapshot); }); diff --git a/packages/firebase_database/firebase_database_web/lib/src/database_event_web.dart b/packages/firebase_database/firebase_database_web/lib/src/database_event_web.dart index 5cd1264dde65..4b13654fd82e 100644 --- a/packages/firebase_database/firebase_database_web/lib/src/database_event_web.dart +++ b/packages/firebase_database/firebase_database_web/lib/src/database_event_web.dart @@ -6,14 +6,11 @@ part of '../firebase_database_web.dart'; /// Web implementation for firebase [DataSnapshotPlatform] class DatabaseEventWeb extends DatabaseEventPlatform { - DatabaseEventWeb( - this._ref, - DatabaseEventType eventType, - this._event, - ) : super({ - 'previousChildKey': _event.prevChildKey, - 'eventType': eventTypeToString(eventType), - }); + DatabaseEventWeb(this._ref, DatabaseEventType eventType, this._event) + : super({ + 'previousChildKey': _event.prevChildKey, + 'eventType': eventTypeToString(eventType), + }); final DatabaseReferencePlatform _ref; diff --git a/packages/firebase_database/firebase_database_web/lib/src/database_reference_web.dart b/packages/firebase_database/firebase_database_web/lib/src/database_reference_web.dart index e74f1530c5f3..ccef53bd3f0f 100755 --- a/packages/firebase_database/firebase_database_web/lib/src/database_reference_web.dart +++ b/packages/firebase_database/firebase_database_web/lib/src/database_reference_web.dart @@ -9,10 +9,8 @@ class DatabaseReferenceWeb extends QueryWeb implements DatabaseReferencePlatform { /// Builds an instance of [DatabaseReferenceWeb] delegating to a package:firebase [DatabaseReferencePlatform] /// to delegate queries to underlying firebase web plugin - DatabaseReferenceWeb( - DatabasePlatform database, - this._delegate, - ) : super(database, _delegate); + DatabaseReferenceWeb(DatabasePlatform database, this._delegate) + : super(database, _delegate); final database_interop.DatabaseReference _delegate; @@ -92,7 +90,9 @@ class DatabaseReferenceWeb extends QueryWeb bool applyLocally = true, }) async { return TransactionResultWeb._( - this, await _delegate.transaction(transactionHandler, applyLocally)); + this, + await _delegate.transaction(transactionHandler, applyLocally), + ); } @override diff --git a/packages/firebase_database/firebase_database_web/lib/src/interop/database.dart b/packages/firebase_database/firebase_database_web/lib/src/interop/database.dart index e9095b557278..18279659257a 100755 --- a/packages/firebase_database/firebase_database_web/lib/src/interop/database.dart +++ b/packages/firebase_database/firebase_database_web/lib/src/interop/database.dart @@ -22,7 +22,8 @@ import 'database_interop.dart' as database_interop; /// Given an AppJSImp, return the Database instance. Database getDatabaseInstance([App? app, String? databaseURL]) { return Database.getInstance( - database_interop.getDatabase(app?.jsObject, databaseURL?.toJS)); + database_interop.getDatabase(app?.jsObject, databaseURL?.toJS), + ); } /// Logs debugging information to the console. @@ -66,12 +67,14 @@ class Database /// Returns a [DatabaseReference] to the root or provided [path]. DatabaseReference ref([String? path = '/']) => DatabaseReference.getInstance( - database_interop.ref(jsObject, (path ?? '/').toJS)); + database_interop.ref(jsObject, (path ?? '/').toJS), + ); /// Returns a [DatabaseReference] from provided [url]. /// Url must be in the same domain as the current database. DatabaseReference refFromURL(String url) => DatabaseReference.getInstance( - database_interop.refFromURL(jsObject, url.toJS)); + database_interop.refFromURL(jsObject, url.toJS), + ); } /// A DatabaseReference represents a specific location in database and @@ -98,14 +101,14 @@ class DatabaseReference extends Query { /// Creates a new DatabaseReference from a [jsObject]. static DatabaseReference getInstance( database_interop.ReferenceJsImpl jsObject, - ) => - _expando[jsObject] ??= DatabaseReference._fromJsObject(jsObject); + ) => _expando[jsObject] ??= DatabaseReference._fromJsObject(jsObject); DatabaseReference._fromJsObject(super.jsObject) : super.fromJsObject(); /// Returns child DatabaseReference from provided relative [path]. DatabaseReference child(String path) => DatabaseReference.getInstance( - database_interop.child(jsObject, path.toJS)); + database_interop.child(jsObject, path.toJS), + ); /// Returns [OnDisconnect] object. OnDisconnect onDisconnect() => @@ -126,7 +129,8 @@ class DatabaseReference extends Query { /// This method returns [ThenableReference], [DatabaseReference] /// with a [Future] property. ThenableReference push([Object? value]) => ThenableReference.fromJsObject( - database_interop.push(jsObject, value?.jsify())); + database_interop.push(jsObject, value?.jsify()), + ); /// Removes data from actual database location. Future remove() => database_interop.remove(jsObject).toDart; @@ -185,7 +189,9 @@ class DatabaseReference extends Query { /// /// Set [applyLocally] to `false` to not see intermediate states. Future transaction( - TransactionHandler transactionUpdate, bool applyLocally) async { + TransactionHandler transactionUpdate, + bool applyLocally, + ) async { final JSAny? Function(JSAny?) transactionUpdateWrap = ((JSAny? update) { final dartUpdate = update?.dartify(); final transaction = transactionUpdate(dartUpdate); @@ -201,7 +207,8 @@ class DatabaseReference extends Query { jsObject, transactionUpdateWrap.toJS, database_interop.TransactionOptions( - applyLocally: applyLocally.toJS), + applyLocally: applyLocally.toJS, + ), ) .toDart; return Transaction( @@ -248,11 +255,8 @@ class Query extends JsObjectWrapper { /// DatabaseReference to the Query's location. DatabaseReference get ref => DatabaseReference.getInstance(jsObject.ref); - Stream _onValue(String appName, String hashCode) => _createStream( - 'value', - appName, - hashCode, - ); + Stream _onValue(String appName, String hashCode) => + _createStream('value', appName, hashCode); /// Stream for a value event. Event is triggered once with the initial /// data stored at location, and then again each time the data changes. @@ -260,11 +264,7 @@ class Query extends JsObjectWrapper { _onValue(appName, hashCode); Stream _onChildAdded(String appName, String hashCode) => - _createStream( - 'child_added', - appName, - hashCode, - ); + _createStream('child_added', appName, hashCode); /// Stream for a child_added event. Event is triggered once for each /// initial child at location, and then again every time a new child is added. @@ -272,11 +272,7 @@ class Query extends JsObjectWrapper { _onChildAdded(appName, hashCode); Stream _onChildRemoved(String appName, String hashCode) => - _createStream( - 'child_removed', - appName, - hashCode, - ); + _createStream('child_removed', appName, hashCode); /// Stream for a child_removed event. Event is triggered once every time /// a child is removed. @@ -284,11 +280,7 @@ class Query extends JsObjectWrapper { _onChildRemoved(appName, hashCode); Stream _onChildChanged(String appName, String hashCode) => - _createStream( - 'child_changed', - appName, - hashCode, - ); + _createStream('child_changed', appName, hashCode); /// Stream for a child_changed event. Event is triggered when the data /// stored in a child (or any of its descendants) changes. @@ -296,11 +288,7 @@ class Query extends JsObjectWrapper { Stream onChildChanged(String appName, String hashCode) => _onChildChanged(appName, hashCode); Stream _onChildMoved(String appName, String hashCode) => - _createStream( - 'child_moved', - appName, - hashCode, - ); + _createStream('child_moved', appName, hashCode); /// Stream for a child_moved event. Event is triggered when a child's priority /// changes such that its position relative to its siblings changes. @@ -410,13 +398,12 @@ class Query extends JsObjectWrapper { ) { late StreamController streamController; unsubscribeWindowsListener(_streamWindowsKey(appName, eventType, hashCode)); - final callbackWrap = (( - database_interop.DataSnapshotJsImpl data, [ - String? prevChild, - ]) { - streamController - .add(QueryEvent(DataSnapshot.getInstance(data), prevChild)); - }); + final callbackWrap = + ((database_interop.DataSnapshotJsImpl data, [String? prevChild]) { + streamController.add( + QueryEvent(DataSnapshot.getInstance(data), prevChild), + ); + }); final void Function(JSObject) cancelCallbackWrap = ((JSObject error) { streamController.addError(convertFirebaseDatabaseException(error)); @@ -469,11 +456,7 @@ class Query extends JsObjectWrapper { void stopListen() { onUnsubscribe.callAsFunction(); streamController.close(); - removeWindowsListener(_streamWindowsKey( - appName, - eventType, - hashCode, - )); + removeWindowsListener(_streamWindowsKey(appName, eventType, hashCode)); } streamController = StreamController.broadcast( @@ -503,23 +486,23 @@ class Query extends JsObjectWrapper { /// Returns a new Query ordered by the specified child [path]. Query orderByChild(String path) => Query.fromJsObject( - database_interop.query( - jsObject, - database_interop.orderByChild(path.toJS), - ), - ); + database_interop.query(jsObject, database_interop.orderByChild(path.toJS)), + ); /// Returns a new Query ordered by key. Query orderByKey() => Query.fromJsObject( - database_interop.query(jsObject, database_interop.orderByKey())); + database_interop.query(jsObject, database_interop.orderByKey()), + ); /// Returns a new Query ordered by priority. Query orderByPriority() => Query.fromJsObject( - database_interop.query(jsObject, database_interop.orderByPriority())); + database_interop.query(jsObject, database_interop.orderByPriority()), + ); /// Returns a new Query ordered by child values. Query orderByValue() => Query.fromJsObject( - database_interop.query(jsObject, database_interop.orderByValue())); + database_interop.query(jsObject, database_interop.orderByValue()), + ); /// Returns a Query with the starting point [value]. The starting point /// is inclusive. @@ -564,8 +547,7 @@ class TransactionResult /// Creates a new TransactionResult from a [jsObject]. static TransactionResult getInstance( database_interop.TransactionResultJsImpl jsObject, - ) => - _expando[jsObject] ??= TransactionResult._fromJsObject(jsObject); + ) => _expando[jsObject] ??= TransactionResult._fromJsObject(jsObject); TransactionResult._fromJsObject(super.jsObject) : super.fromJsObject(); @@ -592,8 +574,7 @@ class DataSnapshot /// Creates a new DataSnapshot from a [jsObject]. static DataSnapshot getInstance( database_interop.DataSnapshotJsImpl jsObject, - ) => - _expando[jsObject] ??= DataSnapshot._fromJsObject(jsObject); + ) => _expando[jsObject] ??= DataSnapshot._fromJsObject(jsObject); DataSnapshot._fromJsObject(super.jsObject) : super.fromJsObject(); @@ -610,8 +591,9 @@ class DataSnapshot /// Enumerates the top-level children of the DataSnapshot in their query-order. /// [action] is called for each child DataSnapshot. bool forEach(void Function(DataSnapshot) action) { - final actionWrap = ((database_interop.DataSnapshotJsImpl d) => - action(DataSnapshot.getInstance(d))).toJS; + final actionWrap = ((database_interop.DataSnapshotJsImpl d) => action( + DataSnapshot.getInstance(d), + )).toJS; return (jsObject.forEach(actionWrap)).toDart; } @@ -674,12 +656,17 @@ class OnDisconnect class ThenableReference extends DatabaseReference { late final Future _future = (jsObject as database_interop.ThenableReferenceJsImpl) - .then(((database_interop.ReferenceJsImpl reference) { - return reference; - }).toJS) + .then( + ((database_interop.ReferenceJsImpl reference) { + return reference; + }).toJS, + ) .toDart - .then((value) => DatabaseReference.getInstance( - value as database_interop.ReferenceJsImpl)); + .then( + (value) => DatabaseReference.getInstance( + value as database_interop.ReferenceJsImpl, + ), + ); /// Creates a new ThenableReference from a [jsObject]. ThenableReference.fromJsObject( diff --git a/packages/firebase_database/firebase_database_web/lib/src/interop/database_interop.dart b/packages/firebase_database/firebase_database_web/lib/src/interop/database_interop.dart index af438b5d52d2..b48fed0f566b 100755 --- a/packages/firebase_database/firebase_database_web/lib/src/interop/database_interop.dart +++ b/packages/firebase_database/firebase_database_web/lib/src/interop/database_interop.dart @@ -24,20 +24,21 @@ external ReferenceJsImpl child(ReferenceJsImpl parentRef, JSString path); @JS() @staticInterop external void connectDatabaseEmulator( - DatabaseJsImpl database, JSString host, JSNumber port); + DatabaseJsImpl database, + JSString host, + JSNumber port, +); @JS() @staticInterop -external void enableLogging( - [JSAny /* Func message || JSBoolean enabled */ loggerOrEnabled, - JSBoolean persistent]); +external void enableLogging([ + JSAny /* Func message || JSBoolean enabled */ loggerOrEnabled, + JSBoolean persistent, +]); @JS() @staticInterop -external JSPromise update( - ReferenceJsImpl ref, - JSAny? values, -); +external JSPromise update(ReferenceJsImpl ref, JSAny? values); // TODO - new API for implementing post web v9 SDK integration @JS() @staticInterop @@ -118,9 +119,8 @@ external JSFunction onValue( QueryJsImpl query, JSFunction callback, // JSAny Function(DataSnapshotJsImpl, [JSString previousChildName]) callback, - JSFunction cancelCallback, + JSFunction cancelCallback, [ // JSAny Function(FirebaseError error) cancelCallback, - [ ListenOptions options, ]); @@ -157,16 +157,11 @@ external ReferenceJsImpl ref(DatabaseJsImpl database, [JSString path]); @JS() @staticInterop -external ReferenceJsImpl refFromURL( - DatabaseJsImpl database, - JSString url, -); +external ReferenceJsImpl refFromURL(DatabaseJsImpl database, JSString url); @JS() @staticInterop -external JSPromise remove( - ReferenceJsImpl ref, -); +external JSPromise remove(ReferenceJsImpl ref); @JS() @staticInterop @@ -188,12 +183,17 @@ external JSPromise set(ReferenceJsImpl ref, JSAny? value); @JS() @staticInterop external JSPromise setPriority( - ReferenceJsImpl ref, /* JSString | JSNumber | null */ JSAny? priority); + ReferenceJsImpl ref, + /* JSString | JSNumber | null */ JSAny? priority, +); @JS() @staticInterop -external JSPromise setWithPriority(ReferenceJsImpl ref, JSAny? value, - /* JSString | JSNumber | null */ JSAny? priority); +external JSPromise setWithPriority( + ReferenceJsImpl ref, + JSAny? value, + /* JSString | JSNumber | null */ JSAny? priority, +); @JS() @staticInterop @@ -247,14 +247,9 @@ extension type OnDisconnectJsImpl._(JSObject _) implements JSObject { //void Function(JSAny) onComplete ]); - external JSPromise setWithPriority( - JSAny? value, - JSAny? priority, - ); + external JSPromise setWithPriority(JSAny? value, JSAny? priority); - external JSPromise update( - JSAny? values, - ); + external JSPromise update(JSAny? values); } extension type ThenableReferenceJsImpl._(JSObject _) diff --git a/packages/firebase_database/firebase_database_web/lib/src/query_web.dart b/packages/firebase_database/firebase_database_web/lib/src/query_web.dart index 75febee1d05b..68b068c81a3d 100755 --- a/packages/firebase_database/firebase_database_web/lib/src/query_web.dart +++ b/packages/firebase_database/firebase_database_web/lib/src/query_web.dart @@ -11,10 +11,7 @@ class QueryWeb extends QueryPlatform { final DatabasePlatform _database; final database_interop.Query _queryDelegate; - QueryWeb( - this._database, - this._queryDelegate, - ) : super(database: _database); + QueryWeb(this._database, this._queryDelegate) : super(database: _database); database_interop.Query _getQueryDelegateInstance(QueryModifiers modifiers) { database_interop.Query instance = _queryDelegate; @@ -101,9 +98,9 @@ class QueryWeb extends QueryPlatform { hashCode = Object.hashAll([ appName, path, - ...modifiers - .toList() - .map((e) => const DeepCollectionEquality().hash(e)), + ...modifiers.toList().map( + (e) => const DeepCollectionEquality().hash(e), + ), eventType.index, ]).toString(); // Need to track as the same properties to create hash could be used multiple times @@ -123,10 +120,13 @@ class QueryWeb extends QueryPlatform { @override Stream observe( - QueryModifiers modifiers, DatabaseEventType eventType) { + QueryModifiers modifiers, + DatabaseEventType eventType, + ) { database_interop.Query instance = _getQueryDelegateInstance(modifiers); - final appName = - _database.app != null ? _database.app!.name : Firebase.app().name; + final appName = _database.app != null + ? _database.app!.name + : Firebase.app().name; // Purely for unsubscribing purposes in debug mode on "hot restart" // if not running in debug mode, hashCode won't be used @@ -136,42 +136,27 @@ class QueryWeb extends QueryPlatform { case DatabaseEventType.childAdded: return _webStreamToPlatformStream( eventType, - instance.onChildAdded( - appName, - hashCode, - ), + instance.onChildAdded(appName, hashCode), ); case DatabaseEventType.childChanged: return _webStreamToPlatformStream( eventType, - instance.onChildChanged( - appName, - hashCode, - ), + instance.onChildChanged(appName, hashCode), ); case DatabaseEventType.childMoved: return _webStreamToPlatformStream( eventType, - instance.onChildMoved( - appName, - hashCode, - ), + instance.onChildMoved(appName, hashCode), ); case DatabaseEventType.childRemoved: return _webStreamToPlatformStream( eventType, - instance.onChildRemoved( - appName, - hashCode, - ), + instance.onChildRemoved(appName, hashCode), ); case DatabaseEventType.value: return _webStreamToPlatformStream( eventType, - instance.onValue( - appName, - hashCode, - ), + instance.onValue(appName, hashCode), ); } } @@ -181,11 +166,8 @@ class QueryWeb extends QueryPlatform { Stream stream, ) { return stream.map( - (database_interop.QueryEvent event) => webEventToPlatformEvent( - ref, - eventType, - event, - ), + (database_interop.QueryEvent event) => + webEventToPlatformEvent(ref, eventType, event), ); } } diff --git a/packages/firebase_database/firebase_database_web/lib/src/transaction_result_web.dart b/packages/firebase_database/firebase_database_web/lib/src/transaction_result_web.dart index 1710158251e9..9bf828a6eb0d 100644 --- a/packages/firebase_database/firebase_database_web/lib/src/transaction_result_web.dart +++ b/packages/firebase_database/firebase_database_web/lib/src/transaction_result_web.dart @@ -6,7 +6,7 @@ part of '../firebase_database_web.dart'; class TransactionResultWeb extends TransactionResultPlatform { TransactionResultWeb._(this._ref, this._delegate) - : super(_delegate.committed); + : super(_delegate.committed); final database_interop.Transaction _delegate; diff --git a/packages/firebase_database/firebase_database_web/lib/src/utils/exception.dart b/packages/firebase_database/firebase_database_web/lib/src/utils/exception.dart index d85aced3c143..0edd90a7c86f 100644 --- a/packages/firebase_database/firebase_database_web/lib/src/utils/exception.dart +++ b/packages/firebase_database/firebase_database_web/lib/src/utils/exception.dart @@ -6,8 +6,10 @@ part of '../../firebase_database_web.dart'; // Cannot use `guardWebExceptions` since we are inferring the // exception type from the message. -FirebaseException convertFirebaseDatabaseException(Object exception, - [StackTrace? stackTrace]) { +FirebaseException convertFirebaseDatabaseException( + Object exception, [ + StackTrace? stackTrace, +]) { final castedJSObject = exception as core_interop.JSError; String code = 'unknown'; String message = castedJSObject.message?.toDart ?? ''; @@ -20,8 +22,9 @@ FirebaseException convertFirebaseDatabaseException(Object exception, } else if (lowerCaseMessage.contains('permission denied') || lowerCaseMessage.contains('permission_denied')) { code = 'permission-denied'; - } else if (lowerCaseMessage - .contains('transaction needs to be run again with current data')) { + } else if (lowerCaseMessage.contains( + 'transaction needs to be run again with current data', + )) { code = 'data-stale'; } else if (lowerCaseMessage.contains('transaction had too many retries')) { code = 'max-retries'; diff --git a/packages/firebase_database/firebase_database_web/pubspec.yaml b/packages/firebase_database/firebase_database_web/pubspec.yaml index ccc37fb9efee..545ea7e7dcd3 100644 --- a/packages/firebase_database/firebase_database_web/pubspec.yaml +++ b/packages/firebase_database/firebase_database_web/pubspec.yaml @@ -5,8 +5,8 @@ resolution: workspace homepage: https://github.com/firebase/flutterfire/tree/main/packages/firebase_database/firebase_database_web environment: - sdk: '^3.6.0' - flutter: '>=3.22.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: collection: ^1.18.0 diff --git a/packages/firebase_in_app_messaging/firebase_in_app_messaging/example/lib/firebase_options.dart b/packages/firebase_in_app_messaging/firebase_in_app_messaging/example/lib/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/firebase_in_app_messaging/firebase_in_app_messaging/example/lib/firebase_options.dart +++ b/packages/firebase_in_app_messaging/firebase_in_app_messaging/example/lib/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/firebase_in_app_messaging/firebase_in_app_messaging/example/lib/main.dart b/packages/firebase_in_app_messaging/firebase_in_app_messaging/example/lib/main.dart index 9f4286e3f005..29c283b00795 100644 --- a/packages/firebase_in_app_messaging/firebase_in_app_messaging/example/lib/main.dart +++ b/packages/firebase_in_app_messaging/firebase_in_app_messaging/example/lib/main.dart @@ -14,9 +14,7 @@ import 'firebase_options.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); + await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); runApp(MyApp()); } @@ -27,9 +25,7 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( home: Scaffold( - appBar: AppBar( - title: const Text('In-App Messaging example'), - ), + appBar: AppBar(title: const Text('In-App Messaging example')), body: Builder( builder: (BuildContext context) { return Center( @@ -58,10 +54,7 @@ class ProgrammaticTriggersExample extends StatelessWidget { children: [ const Text( 'Programmatic Trigger', - style: TextStyle( - fontStyle: FontStyle.italic, - fontSize: 18, - ), + style: TextStyle(fontStyle: FontStyle.italic, fontSize: 18), ), const SizedBox(height: 8), const Text('Manually trigger events programmatically '), @@ -80,7 +73,7 @@ class ProgrammaticTriggersExample extends StatelessWidget { 'Programmatic Triggers'.toUpperCase(), style: const TextStyle(color: Colors.white), ), - ) + ), ], ), ), @@ -107,10 +100,7 @@ class AnalyticsEventExample extends StatelessWidget { children: [ const Text( 'Log an analytics event', - style: TextStyle( - fontStyle: FontStyle.italic, - fontSize: 18, - ), + style: TextStyle(fontStyle: FontStyle.italic, fontSize: 18), ), const SizedBox(height: 8), const Text('Trigger an analytics event'), diff --git a/packages/firebase_in_app_messaging/firebase_in_app_messaging/example/pubspec.yaml b/packages/firebase_in_app_messaging/firebase_in_app_messaging/example/pubspec.yaml index 97a6d427e0d5..d2b75d6d8489 100644 --- a/packages/firebase_in_app_messaging/firebase_in_app_messaging/example/pubspec.yaml +++ b/packages/firebase_in_app_messaging/firebase_in_app_messaging/example/pubspec.yaml @@ -4,8 +4,8 @@ resolution: workspace publish_to: 'none' environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_analytics: ^12.5.0 diff --git a/packages/firebase_in_app_messaging/firebase_in_app_messaging/lib/firebase_in_app_messaging.dart b/packages/firebase_in_app_messaging/firebase_in_app_messaging/lib/firebase_in_app_messaging.dart index ef35ef27655f..2d2fa343aa43 100644 --- a/packages/firebase_in_app_messaging/firebase_in_app_messaging/lib/firebase_in_app_messaging.dart +++ b/packages/firebase_in_app_messaging/firebase_in_app_messaging/lib/firebase_in_app_messaging.dart @@ -9,7 +9,7 @@ import 'package:firebase_in_app_messaging_platform_interface/firebase_in_app_mes class FirebaseInAppMessaging extends FirebasePlugin { FirebaseInAppMessaging._({required this.app}) - : super(app.name, 'plugins.flutter.io/firebase_in_app_messaging'); + : super(app.name, 'plugins.flutter.io/firebase_in_app_messaging'); /// The [FirebaseApp] for this current [FirebaseAnalytics] instance. final FirebaseApp app; @@ -28,9 +28,7 @@ class FirebaseInAppMessaging extends FirebasePlugin { /// Returns an instance using the default [FirebaseApp]. static FirebaseInAppMessaging get instance { - return FirebaseInAppMessaging._instanceFor( - app: Firebase.app(), - ); + return FirebaseInAppMessaging._instanceFor(app: Firebase.app()); } /// Returns an instance using a specified [FirebaseApp]. diff --git a/packages/firebase_in_app_messaging/firebase_in_app_messaging/pubspec.yaml b/packages/firebase_in_app_messaging/firebase_in_app_messaging/pubspec.yaml index d045fef2f650..1319c2b07ab5 100644 --- a/packages/firebase_in_app_messaging/firebase_in_app_messaging/pubspec.yaml +++ b/packages/firebase_in_app_messaging/firebase_in_app_messaging/pubspec.yaml @@ -14,8 +14,8 @@ false_secrets: - example/** environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core: ^4.14.0 diff --git a/packages/firebase_in_app_messaging/firebase_in_app_messaging/test/firebase_in_app_messaging_test.dart b/packages/firebase_in_app_messaging/firebase_in_app_messaging/test/firebase_in_app_messaging_test.dart index 8af599eb222e..e59cf08a03b4 100644 --- a/packages/firebase_in_app_messaging/firebase_in_app_messaging/test/firebase_in_app_messaging_test.dart +++ b/packages/firebase_in_app_messaging/firebase_in_app_messaging/test/firebase_in_app_messaging_test.dart @@ -26,21 +26,17 @@ void main() { fiam = FirebaseInAppMessaging.instance; when( - mockFiam.delegateFor( - app: anyNamed('app'), - ), - ).thenAnswer( - (_) => mockFiam, - ); - when(mockFiam.triggerEvent('someEvent')).thenAnswer( - (_) => Future.value(), - ); - when(mockFiam.setMessagesSuppressed(any)).thenAnswer( - (_) => Future.value(), - ); - when(mockFiam.setAutomaticDataCollectionEnabled(any)).thenAnswer( - (_) => Future.value(), - ); + mockFiam.delegateFor(app: anyNamed('app')), + ).thenAnswer((_) => mockFiam); + when( + mockFiam.triggerEvent('someEvent'), + ).thenAnswer((_) => Future.value()); + when( + mockFiam.setMessagesSuppressed(any), + ).thenAnswer((_) => Future.value()); + when( + mockFiam.setAutomaticDataCollectionEnabled(any), + ).thenAnswer((_) => Future.value()); }); test('triggerEvent', () async { @@ -76,8 +72,7 @@ class MockFirebaseInAppMessaging extends Mock with // ignore: prefer_mixin MockPlatformInterfaceMixin - implements - TestFirebaseInAppMessagingPlatform { + implements TestFirebaseInAppMessagingPlatform { @override FirebaseInAppMessagingPlatform delegateFor({FirebaseApp? app}) { return super.noSuchMethod( diff --git a/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/lib/src/pigeon/messages.pigeon.dart b/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/lib/src/pigeon/messages.pigeon.dart index c97ea50fd503..5b1ad69b3b9b 100644 --- a/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/lib/src/pigeon/messages.pigeon.dart +++ b/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/lib/src/pigeon/messages.pigeon.dart @@ -37,8 +37,11 @@ Object? _extractReplyValueOrThrow( return replyList.firstOrNull; } -List wrapResponse( - {Object? result, PlatformException? error, bool empty = false}) { +List wrapResponse({ + Object? result, + PlatformException? error, + bool empty = false, +}) { if (empty) { return []; } @@ -73,11 +76,13 @@ class FirebaseInAppMessagingHostApi { /// Constructor for [FirebaseInAppMessagingHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - FirebaseInAppMessagingHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + FirebaseInAppMessagingHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -92,8 +97,9 @@ class FirebaseInAppMessagingHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName, eventName]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName, eventName], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -111,8 +117,9 @@ class FirebaseInAppMessagingHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName, suppress]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName, suppress], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -123,7 +130,9 @@ class FirebaseInAppMessagingHostApi { } Future setAutomaticDataCollectionEnabled( - String appName, bool enabled) async { + String appName, + bool enabled, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_in_app_messaging_platform_interface.FirebaseInAppMessagingHostApi.setAutomaticDataCollectionEnabled$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -131,8 +140,9 @@ class FirebaseInAppMessagingHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName, enabled]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName, enabled], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( diff --git a/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/pubspec.yaml b/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/pubspec.yaml index 8546439d89ab..833294da6e0f 100644 --- a/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/pubspec.yaml +++ b/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/pubspec.yaml @@ -7,8 +7,8 @@ version: 0.2.5+28 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/test/pigeon/test_api.dart b/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/test/pigeon/test_api.dart index 5c83e16f465d..00623692de06 100644 --- a/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/test/pigeon/test_api.dart +++ b/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/test/pigeon/test_api.dart @@ -50,88 +50,109 @@ abstract class TestFirebaseInAppMessagingHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_in_app_messaging_platform_interface.FirebaseInAppMessagingHostApi.triggerEvent$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_in_app_messaging_platform_interface.FirebaseInAppMessagingHostApi.triggerEvent$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_appName = args[0]! as String; - final String arg_eventName = args[1]! as String; - try { - await api.triggerEvent(arg_appName, arg_eventName); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_appName = args[0]! as String; + final String arg_eventName = args[1]! as String; + try { + await api.triggerEvent(arg_appName, arg_eventName); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_in_app_messaging_platform_interface.FirebaseInAppMessagingHostApi.setMessagesSuppressed$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_in_app_messaging_platform_interface.FirebaseInAppMessagingHostApi.setMessagesSuppressed$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_appName = args[0]! as String; - final bool arg_suppress = args[1]! as bool; - try { - await api.setMessagesSuppressed(arg_appName, arg_suppress); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_appName = args[0]! as String; + final bool arg_suppress = args[1]! as bool; + try { + await api.setMessagesSuppressed(arg_appName, arg_suppress); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_in_app_messaging_platform_interface.FirebaseInAppMessagingHostApi.setAutomaticDataCollectionEnabled$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_in_app_messaging_platform_interface.FirebaseInAppMessagingHostApi.setAutomaticDataCollectionEnabled$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_appName = args[0]! as String; - final bool arg_enabled = args[1]! as bool; - try { - await api.setAutomaticDataCollectionEnabled( - arg_appName, arg_enabled); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_appName = args[0]! as String; + final bool arg_enabled = args[1]! as bool; + try { + await api.setAutomaticDataCollectionEnabled( + arg_appName, + arg_enabled, + ); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } diff --git a/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/test/platform_interface/platform_interface_firebase_in_app_messaging_test.dart b/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/test/platform_interface/platform_interface_firebase_in_app_messaging_test.dart index 2e1f5dea92d1..5bf0e926636e 100644 --- a/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/test/platform_interface/platform_interface_firebase_in_app_messaging_test.dart +++ b/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/test/platform_interface/platform_interface_firebase_in_app_messaging_test.dart @@ -36,13 +36,15 @@ void main() { ); }); - test('setAutomaticDataCollectionEnabled throws if not implemented', - () async { - await expectLater( - () => platform!.setAutomaticDataCollectionEnabled(true), - throwsA(isA()), - ); - }); + test( + 'setAutomaticDataCollectionEnabled throws if not implemented', + () async { + await expectLater( + () => platform!.setAutomaticDataCollectionEnabled(true), + throwsA(isA()), + ); + }, + ); }); } diff --git a/packages/firebase_messaging/firebase_messaging/example/integration_test/e2e_test.dart b/packages/firebase_messaging/firebase_messaging/example/integration_test/e2e_test.dart index 66d27ca01a66..9f33e749f31e 100644 --- a/packages/firebase_messaging/firebase_messaging/example/integration_test/e2e_test.dart +++ b/packages/firebase_messaging/firebase_messaging/example/integration_test/e2e_test.dart @@ -29,8 +29,9 @@ Future androidSdkInt() async { Future grantAndroidPermission(String permission) async { try { - return await _permissionsChannel - .invokeMethod('grant', {'permission': permission}) ?? + return await _permissionsChannel.invokeMethod('grant', { + 'permission': permission, + }) ?? false; } on MissingPluginException { return false; @@ -59,270 +60,254 @@ void main() { final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized(); reportTestResultsToDriver(binding); - group( - 'firebase_messaging', - () { - late FirebaseApp app; - late FirebaseMessaging messaging; - int? sdkInt; - - setUpAll(() async { - app = await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); - messaging = FirebaseMessaging.instance; - if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) { - sdkInt = await androidSdkInt(); - } - }); - - test('instance', () { - expect(messaging, isA()); - expect(messaging.app, isA()); - expect(messaging.app.name, defaultFirebaseAppName); - }); - - test('.app accessible from messaging.app', () { - expect(messaging.app, isA()); - expect(messaging.app.name, app.name); - }); - - group('onMessage', () { - test('can listen multiple times', () async { - // regression test for https://github.com/firebase/flutterfire/issues/6009 - - StreamSubscription _onMessageSubscription; - StreamSubscription _onMessageOpenedAppSubscription; - - _onMessageSubscription = FirebaseMessaging.onMessage.listen((_) {}); - _onMessageOpenedAppSubscription = - FirebaseMessaging.onMessageOpenedApp.listen((_) {}); - - await _onMessageSubscription.cancel(); - await _onMessageOpenedAppSubscription.cancel(); - - _onMessageSubscription = FirebaseMessaging.onMessage.listen((_) {}); - _onMessageOpenedAppSubscription = - FirebaseMessaging.onMessageOpenedApp.listen((_) {}); - - await _onMessageSubscription.cancel(); - await _onMessageOpenedAppSubscription.cancel(); - }); + group('firebase_messaging', () { + late FirebaseApp app; + late FirebaseMessaging messaging; + int? sdkInt; + + setUpAll(() async { + app = await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + messaging = FirebaseMessaging.instance; + if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) { + sdkInt = await androidSdkInt(); + } + }); + + test('instance', () { + expect(messaging, isA()); + expect(messaging.app, isA()); + expect(messaging.app.name, defaultFirebaseAppName); + }); + + test('.app accessible from messaging.app', () { + expect(messaging.app, isA()); + expect(messaging.app.name, app.name); + }); + + group('onMessage', () { + test('can listen multiple times', () async { + // regression test for https://github.com/firebase/flutterfire/issues/6009 + + StreamSubscription _onMessageSubscription; + StreamSubscription _onMessageOpenedAppSubscription; + + _onMessageSubscription = FirebaseMessaging.onMessage.listen((_) {}); + _onMessageOpenedAppSubscription = FirebaseMessaging.onMessageOpenedApp + .listen((_) {}); + + await _onMessageSubscription.cancel(); + await _onMessageOpenedAppSubscription.cancel(); + + _onMessageSubscription = FirebaseMessaging.onMessage.listen((_) {}); + _onMessageOpenedAppSubscription = FirebaseMessaging.onMessageOpenedApp + .listen((_) {}); + + await _onMessageSubscription.cancel(); + await _onMessageOpenedAppSubscription.cancel(); }); - - group('setAutoInitEnabled()', () { - test( - 'sets the value', - () async { - await messaging.setAutoInitEnabled(true); - expect(messaging.isAutoInitEnabled, isTrue); - await messaging.setAutoInitEnabled(false); - expect(messaging.isAutoInitEnabled, isFalse); - }, - skip: kIsWeb, - ); + }); + + group('setAutoInitEnabled()', () { + test('sets the value', () async { + await messaging.setAutoInitEnabled(true); + expect(messaging.isAutoInitEnabled, isTrue); + await messaging.setAutoInitEnabled(false); + expect(messaging.isAutoInitEnabled, isFalse); + }, skip: kIsWeb); + }); + + group('isSupported()', () { + test('returns "true" value', () async { + final result = await messaging.isSupported(); + + expect(result, isA()); }); + }); - group('isSupported()', () { - test('returns "true" value', () async { - final result = await messaging.isSupported(); + group('getNotificationSettings', () { + bool android13Plus() => + !kIsWeb && + defaultTargetPlatform == TargetPlatform.android && + (sdkInt ?? 0) >= 33; - expect(result, isA()); - }); + setUp(() async { + if (!android13Plus()) { + return; + } + // Ensure a true "never asked" state between tests and runs. + // revoke alone leaves USER_SET flags and would look like a denial. + final reset = await resetAndroidPermission(_postNotifications); + if (!reset) { + fail('Could not reset POST_NOTIFICATIONS via UiAutomation'); + } }); - group('getNotificationSettings', () { - bool android13Plus() => - !kIsWeb && - defaultTargetPlatform == TargetPlatform.android && - (sdkInt ?? 0) >= 33; + test( + 'returns notDetermined on Android 13+ before permission is granted', + () async { + if (!android13Plus()) { + markTestSkipped('Requires Android API 33+'); + return; + } + // On Android 13+, getNotificationSettings() should return + // notDetermined when POST_NOTIFICATIONS has never been granted, + // allowing callers to decide whether to show the OS prompt or + // direct the user to app settings. + final settings = await messaging.getNotificationSettings(); + expect(settings, isA()); + expect( + settings.authorizationStatus, + AuthorizationStatus.notDetermined, + ); + }, + skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android, + ); - setUp(() async { + test( + 'returns authorized on Android 13+ after permission is granted', + () async { if (!android13Plus()) { + markTestSkipped('Requires Android API 33+'); return; } - // Ensure a true "never asked" state between tests and runs. - // revoke alone leaves USER_SET flags and would look like a denial. - final reset = await resetAndroidPermission(_postNotifications); - if (!reset) { - fail('Could not reset POST_NOTIFICATIONS via UiAutomation'); + final granted = await grantAndroidPermission(_postNotifications); + if (!granted) { + fail('Could not grant POST_NOTIFICATIONS via UiAutomation'); } - }); - test( - 'returns notDetermined on Android 13+ before permission is granted', - () async { - if (!android13Plus()) { - markTestSkipped('Requires Android API 33+'); - return; - } - // On Android 13+, getNotificationSettings() should return - // notDetermined when POST_NOTIFICATIONS has never been granted, - // allowing callers to decide whether to show the OS prompt or - // direct the user to app settings. - final settings = await messaging.getNotificationSettings(); - expect(settings, isA()); - expect( - settings.authorizationStatus, - AuthorizationStatus.notDetermined, - ); - }, - skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android, - ); - - test( - 'returns authorized on Android 13+ after permission is granted', - () async { - if (!android13Plus()) { - markTestSkipped('Requires Android API 33+'); - return; - } - final granted = await grantAndroidPermission(_postNotifications); - if (!granted) { - fail('Could not grant POST_NOTIFICATIONS via UiAutomation'); - } - - final settings = await messaging.getNotificationSettings(); - expect(settings, isA()); - expect( - settings.authorizationStatus, - AuthorizationStatus.authorized, - ); - }, - skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android, - ); - }); + final settings = await messaging.getNotificationSettings(); + expect(settings, isA()); + expect(settings.authorizationStatus, AuthorizationStatus.authorized); + }, + skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android, + ); + }); + + group('requestPermission', () { + test( + 'authorizationStatus returns AuthorizationStatus.authorized on Android 13+', + () async { + final isAndroid13Plus = + !kIsWeb && + defaultTargetPlatform == TargetPlatform.android && + (sdkInt ?? 0) >= 33; + if (!isAndroid13Plus) { + markTestSkipped('Requires Android API 33+'); + return; + } + // Pre-grant the permission so requestPermission() returns + // authorized without showing a system dialog. + final granted = await grantAndroidPermission(_postNotifications); + if (!granted) { + fail('Could not grant POST_NOTIFICATIONS via UiAutomation'); + } - group('requestPermission', () { - test( - 'authorizationStatus returns AuthorizationStatus.authorized on Android 13+', - () async { - final isAndroid13Plus = !kIsWeb && - defaultTargetPlatform == TargetPlatform.android && - (sdkInt ?? 0) >= 33; - if (!isAndroid13Plus) { - markTestSkipped('Requires Android API 33+'); - return; - } - // Pre-grant the permission so requestPermission() returns - // authorized without showing a system dialog. - final granted = await grantAndroidPermission(_postNotifications); - if (!granted) { - fail('Could not grant POST_NOTIFICATIONS via UiAutomation'); - } - - final result = await messaging.requestPermission(); - expect(result, isA()); - expect(result.authorizationStatus, AuthorizationStatus.authorized); - }, - skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android, - ); + final result = await messaging.requestPermission(); + expect(result, isA()); + expect(result.authorizationStatus, AuthorizationStatus.authorized); + }, + skip: kIsWeb || defaultTargetPlatform != TargetPlatform.android, + ); - test( - 'authorizationStatus returns AuthorizationStatus.notDetermined on Web', - () async { - final result = await messaging.requestPermission(); - - expect(result, isA()); - expect( - result.authorizationStatus, - AuthorizationStatus.notDetermined, - ); - }, - // This requires interaction with the browser's permission dialog, it no longer returns `notDetermined` on web - skip: true, - ); - }); + test( + 'authorizationStatus returns AuthorizationStatus.notDetermined on Web', + () async { + final result = await messaging.requestPermission(); - group('getAPNSToken', () { - test( - 'resolves null on android', - () async { - expect(await messaging.getAPNSToken(), null); - }, - skip: defaultTargetPlatform != TargetPlatform.android, + expect(result, isA()); + expect(result.authorizationStatus, AuthorizationStatus.notDetermined); + }, + // This requires interaction with the browser's permission dialog, it no longer returns `notDetermined` on web + skip: true, + ); + }); + + group('getAPNSToken', () { + test('resolves null on android', () async { + expect(await messaging.getAPNSToken(), null); + }, skip: defaultTargetPlatform != TargetPlatform.android); + }); + + group('getInitialMessage', () { + test('returns null when no initial message', () async { + expect( + await messaging.getInitialMessage().timeout( + const Duration(seconds: 5), + ), + null, ); }); - - group('getInitialMessage', () { - test('returns null when no initial message', () async { - expect( - await messaging - .getInitialMessage() - .timeout(const Duration(seconds: 5)), - null, - ); + }); + + group( + 'getToken()', + () { + test('returns a token', () async { + final result = await messaging.getToken(); + expect(result, isA()); }); - }); - - group( - 'getToken()', - () { - test('returns a token', () async { - final result = await messaging.getToken(); - expect(result, isA()); - }); + }, + // Skipping on Web since we cannot click on authorize notification dialog + skip: skipTestsOnCI || kIsWeb, + ); // only run for manual testing + + group('deleteToken()', () { + test( + 'generate a new token after deleting', + () async { + final token1 = await messaging.getToken(); + await Future.delayed(const Duration(seconds: 3)); + await messaging.deleteToken(); + await Future.delayed(const Duration(seconds: 3)); + final token2 = await messaging.getToken(); + expect(token1, isA()); + expect(token2, isA()); + expect(token1, isNot(token2)); }, // Skipping on Web since we cannot click on authorize notification dialog skip: skipTestsOnCI || kIsWeb, ); // only run for manual testing - - group('deleteToken()', () { - test( - 'generate a new token after deleting', - () async { - final token1 = await messaging.getToken(); - await Future.delayed(const Duration(seconds: 3)); - await messaging.deleteToken(); - await Future.delayed(const Duration(seconds: 3)); - final token2 = await messaging.getToken(); - expect(token1, isA()); - expect(token2, isA()); - expect(token1, isNot(token2)); - }, - // Skipping on Web since we cannot click on authorize notification dialog - skip: skipTestsOnCI || kIsWeb, - ); // only run for manual testing - }); - - group('subscribeToTopic()', () { - test( - 'successfully subscribes from topic', - () async { - const topic = 'test-topic'; - await messaging.subscribeToTopic(topic); - }, - // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 - // android skipped due to consistently failing, works locally: https://github.com/firebase/flutterfire/pull/11260 - // iOS fails because APNS token handler doesn't have a chance to receive token before calling this method - skip: kIsWeb || skipTestsOnCI, - ); - }); - - group('unsubscribeFromTopic()', () { - test( - 'successfully unsubscribes from topic', - () async { - const topic = 'test-topic'; - await messaging.unsubscribeFromTopic(topic); - }, - // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 - // android skipped due to consistently failing, works locally: https://github.com/firebase/flutterfire/pull/11260 - // iOS fails because APNS token handler doesn't have a chance to receive token before calling this method - skip: kIsWeb || skipTestsOnCI, - ); - }); - - group('setDeliveryMetricsExportToBigQuery()', () { - test( - 'successfully set delivery metrics export to big query', - () async { - await messaging.setDeliveryMetricsExportToBigQuery(true); - }, - // Web is skipped because it has to be setup in the service worker - skip: kIsWeb, - ); - }); - }, - ); + }); + + group('subscribeToTopic()', () { + test( + 'successfully subscribes from topic', + () async { + const topic = 'test-topic'; + await messaging.subscribeToTopic(topic); + }, + // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 + // android skipped due to consistently failing, works locally: https://github.com/firebase/flutterfire/pull/11260 + // iOS fails because APNS token handler doesn't have a chance to receive token before calling this method + skip: kIsWeb || skipTestsOnCI, + ); + }); + + group('unsubscribeFromTopic()', () { + test( + 'successfully unsubscribes from topic', + () async { + const topic = 'test-topic'; + await messaging.unsubscribeFromTopic(topic); + }, + // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 + // android skipped due to consistently failing, works locally: https://github.com/firebase/flutterfire/pull/11260 + // iOS fails because APNS token handler doesn't have a chance to receive token before calling this method + skip: kIsWeb || skipTestsOnCI, + ); + }); + + group('setDeliveryMetricsExportToBigQuery()', () { + test( + 'successfully set delivery metrics export to big query', + () async { + await messaging.setDeliveryMetricsExportToBigQuery(true); + }, + // Web is skipped because it has to be setup in the service worker + skip: kIsWeb, + ); + }); + }); } diff --git a/packages/firebase_messaging/firebase_messaging/example/integration_test/report_test_results.dart b/packages/firebase_messaging/firebase_messaging/example/integration_test/report_test_results.dart index 038d20c39931..416b8cd76dd0 100644 --- a/packages/firebase_messaging/firebase_messaging/example/integration_test/report_test_results.dart +++ b/packages/firebase_messaging/firebase_messaging/example/integration_test/report_test_results.dart @@ -26,8 +26,9 @@ void reportTestResultsToDriver(IntegrationTestWidgetsFlutterBinding binding) { for (final entry in binding.results.entries) if (entry.value is Failure) entry.key, ]; - bool didFail(String name) => failures - .any((failure) => name == failure || name.endsWith(' $failure')); + bool didFail(String name) => failures.any( + (failure) => name == failure || name.endsWith(' $failure'), + ); binding.reportData ??= {}; binding.reportData!['testResults'] = { diff --git a/packages/firebase_messaging/firebase_messaging/example/lib/firebase_options.dart b/packages/firebase_messaging/firebase_messaging/example/lib/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/firebase_messaging/firebase_messaging/example/lib/firebase_options.dart +++ b/packages/firebase_messaging/firebase_messaging/example/lib/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/firebase_messaging/firebase_messaging/example/lib/main.dart b/packages/firebase_messaging/firebase_messaging/example/lib/main.dart index 6175abd772c4..7aab4e06b803 100644 --- a/packages/firebase_messaging/firebase_messaging/example/lib/main.dart +++ b/packages/firebase_messaging/firebase_messaging/example/lib/main.dart @@ -79,7 +79,8 @@ Future setupFlutterNotifications() async { /// default FCM channel to enable heads up notifications. await flutterLocalNotificationsPlugin .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>() + AndroidFlutterLocalNotificationsPlugin + >() ?.createNotificationChannel(channel); /// Update the iOS foreground notification presentation options to allow @@ -183,13 +184,11 @@ class _Application extends State { // Delay getInitialMessage call by 3 seconds Future.delayed(const Duration(seconds: 3), () { FirebaseMessaging.instance.getInitialMessage().then( - (value) => setState( - () { - _resolved = true; - initialMessage = value?.data.toString(); - }, - ), - ); + (value) => setState(() { + _resolved = true; + initialMessage = value?.data.toString(); + }), + ); }); FirebaseMessaging.onMessage.listen(showFlutterNotification); @@ -328,9 +327,9 @@ class _Application extends State { ), ElevatedButton( onPressed: () { - FirebaseMessaging.instance - .getInitialMessage() - .then((RemoteMessage? message) { + FirebaseMessaging.instance.getInitialMessage().then(( + RemoteMessage? message, + ) { if (message != null) { Navigator.pushNamed( context, diff --git a/packages/firebase_messaging/firebase_messaging/example/lib/message.dart b/packages/firebase_messaging/firebase_messaging/example/lib/message.dart index ce2a38cf4ed3..eebb260571a5 100644 --- a/packages/firebase_messaging/firebase_messaging/example/lib/message.dart +++ b/packages/firebase_messaging/firebase_messaging/example/lib/message.dart @@ -43,121 +43,80 @@ class MessageView extends StatelessWidget { RemoteNotification? notification = message.notification; return Scaffold( - appBar: AppBar( - title: Text(message.messageId ?? 'N/A'), - ), + appBar: AppBar(title: Text(message.messageId ?? 'N/A')), body: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.all(8), - child: Column( - children: [ - row('Triggered application open', - args.openedApplication.toString()), - row('Message ID', message.messageId), - row('Sender ID', message.senderId), - row('Category', message.category), - row('Collapse Key', message.collapseKey), - row('Content Available', message.contentAvailable.toString()), - row('Data', message.data.toString()), - row('From', message.from), - row('Message ID', message.messageId), - row('Sent Time', message.sentTime?.toString()), - row('Thread ID', message.threadId), - row('Time to Live (TTL)', message.ttl?.toString()), - if (notification != null) ...[ - Padding( - padding: const EdgeInsets.only(top: 16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text( - 'Remote Notification', - style: TextStyle(fontSize: 18), - ), - row( - 'Title', - notification.title, - ), - row( - 'Body', - notification.body, - ), - if (notification.android != null) ...[ - const SizedBox(height: 16), + child: Padding( + padding: const EdgeInsets.all(8), + child: Column( + children: [ + row( + 'Triggered application open', + args.openedApplication.toString(), + ), + row('Message ID', message.messageId), + row('Sender ID', message.senderId), + row('Category', message.category), + row('Collapse Key', message.collapseKey), + row('Content Available', message.contentAvailable.toString()), + row('Data', message.data.toString()), + row('From', message.from), + row('Message ID', message.messageId), + row('Sent Time', message.sentTime?.toString()), + row('Thread ID', message.threadId), + row('Time to Live (TTL)', message.ttl?.toString()), + if (notification != null) ...[ + Padding( + padding: const EdgeInsets.only(top: 16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ const Text( - 'Android Properties', + 'Remote Notification', style: TextStyle(fontSize: 18), ), - row( - 'Channel ID', - notification.android!.channelId, - ), - row( - 'Click Action', - notification.android!.clickAction, - ), - row( - 'Color', - notification.android!.color, - ), - row( - 'Count', - notification.android!.count?.toString(), - ), - row( - 'Image URL', - notification.android!.imageUrl, - ), - row( - 'Link', - notification.android!.link, - ), - row( - 'Priority', - notification.android!.priority.toString(), - ), - row( - 'Small Icon', - notification.android!.smallIcon, - ), - row( - 'Sound', - notification.android!.sound, - ), - row( - 'Ticker', - notification.android!.ticker, - ), - row( - 'Visibility', - notification.android!.visibility.toString(), - ), + row('Title', notification.title), + row('Body', notification.body), + if (notification.android != null) ...[ + const SizedBox(height: 16), + const Text( + 'Android Properties', + style: TextStyle(fontSize: 18), + ), + row('Channel ID', notification.android!.channelId), + row('Click Action', notification.android!.clickAction), + row('Color', notification.android!.color), + row('Count', notification.android!.count?.toString()), + row('Image URL', notification.android!.imageUrl), + row('Link', notification.android!.link), + row( + 'Priority', + notification.android!.priority.toString(), + ), + row('Small Icon', notification.android!.smallIcon), + row('Sound', notification.android!.sound), + row('Ticker', notification.android!.ticker), + row( + 'Visibility', + notification.android!.visibility.toString(), + ), + ], + if (notification.apple != null) ...[ + const Text( + 'Apple Properties', + style: TextStyle(fontSize: 18), + ), + row('Subtitle', notification.apple!.subtitle), + row('Badge', notification.apple!.badge), + row('Sound', notification.apple!.sound?.name), + ], ], - if (notification.apple != null) ...[ - const Text( - 'Apple Properties', - style: TextStyle(fontSize: 18), - ), - row( - 'Subtitle', - notification.apple!.subtitle, - ), - row( - 'Badge', - notification.apple!.badge, - ), - row( - 'Sound', - notification.apple!.sound?.name, - ), - ] - ], + ), ), - ) - ] - ], + ], + ], + ), ), - )), + ), ); } } diff --git a/packages/firebase_messaging/firebase_messaging/example/lib/message_list.dart b/packages/firebase_messaging/firebase_messaging/example/lib/message_list.dart index 7411ba52c9a0..3d67b1471b3e 100644 --- a/packages/firebase_messaging/firebase_messaging/example/lib/message_list.dart +++ b/packages/firebase_messaging/firebase_messaging/example/lib/message_list.dart @@ -35,19 +35,25 @@ class _MessageList extends State { } return ListView.builder( - shrinkWrap: true, - itemCount: _messages.length, - itemBuilder: (context, index) { - RemoteMessage message = _messages[index]; - - return ListTile( - title: Text( - message.messageId ?? 'no RemoteMessage.messageId available'), - subtitle: - Text(message.sentTime?.toString() ?? DateTime.now().toString()), - onTap: () => Navigator.pushNamed(context, '/message', - arguments: MessageArguments(message, false)), - ); - }); + shrinkWrap: true, + itemCount: _messages.length, + itemBuilder: (context, index) { + RemoteMessage message = _messages[index]; + + return ListTile( + title: Text( + message.messageId ?? 'no RemoteMessage.messageId available', + ), + subtitle: Text( + message.sentTime?.toString() ?? DateTime.now().toString(), + ), + onTap: () => Navigator.pushNamed( + context, + '/message', + arguments: MessageArguments(message, false), + ), + ); + }, + ); } } diff --git a/packages/firebase_messaging/firebase_messaging/example/lib/permissions.dart b/packages/firebase_messaging/firebase_messaging/example/lib/permissions.dart index 122874ade164..ffddea309fde 100644 --- a/packages/firebase_messaging/firebase_messaging/example/lib/permissions.dart +++ b/packages/firebase_messaging/firebase_messaging/example/lib/permissions.dart @@ -24,12 +24,12 @@ class _Permissions extends State { _fetching = true; }); - NotificationSettings settings = - await FirebaseMessaging.instance.requestPermission( - announcement: true, - carPlay: true, - criticalAlert: true, - ); + NotificationSettings settings = await FirebaseMessaging.instance + .requestPermission( + announcement: true, + carPlay: true, + criticalAlert: true, + ); setState(() { _requested = true; @@ -43,8 +43,8 @@ class _Permissions extends State { _fetching = true; }); - NotificationSettings settings = - await FirebaseMessaging.instance.getNotificationSettings(); + NotificationSettings settings = await FirebaseMessaging.instance + .getNotificationSettings(); setState(() { _requested = true; @@ -78,27 +78,37 @@ class _Permissions extends State { if (!_requested) { return ElevatedButton( - onPressed: requestPermissions, - child: const Text('Request Permissions')); + onPressed: requestPermissions, + child: const Text('Request Permissions'), + ); } - return Column(children: [ - row('Authorization Status', statusMap[_settings.authorizationStatus]!), - if (defaultTargetPlatform == TargetPlatform.iOS) ...[ - row('Alert', settingsMap[_settings.alert]!), - row('Announcement', settingsMap[_settings.announcement]!), - row('Badge', settingsMap[_settings.badge]!), - row('Car Play', settingsMap[_settings.carPlay]!), - row('Lock Screen', settingsMap[_settings.lockScreen]!), - row('Notification Center', settingsMap[_settings.notificationCenter]!), - row('Show Previews', previewMap[_settings.showPreviews]!), - row('Sound', settingsMap[_settings.sound]!), - row('Provides App Notification Settings', - settingsMap[_settings.providesAppNotificationSettings]!), + return Column( + children: [ + row('Authorization Status', statusMap[_settings.authorizationStatus]!), + if (defaultTargetPlatform == TargetPlatform.iOS) ...[ + row('Alert', settingsMap[_settings.alert]!), + row('Announcement', settingsMap[_settings.announcement]!), + row('Badge', settingsMap[_settings.badge]!), + row('Car Play', settingsMap[_settings.carPlay]!), + row('Lock Screen', settingsMap[_settings.lockScreen]!), + row( + 'Notification Center', + settingsMap[_settings.notificationCenter]!, + ), + row('Show Previews', previewMap[_settings.showPreviews]!), + row('Sound', settingsMap[_settings.sound]!), + row( + 'Provides App Notification Settings', + settingsMap[_settings.providesAppNotificationSettings]!, + ), + ], + ElevatedButton( + onPressed: checkPermissions, + child: const Text('Reload Permissions'), + ), ], - ElevatedButton( - onPressed: checkPermissions, child: const Text('Reload Permissions')), - ]); + ); } } diff --git a/packages/firebase_messaging/firebase_messaging/example/lib/token_monitor.dart b/packages/firebase_messaging/firebase_messaging/example/lib/token_monitor.dart index 6fd6daf2843b..301bc6378e0a 100644 --- a/packages/firebase_messaging/firebase_messaging/example/lib/token_monitor.dart +++ b/packages/firebase_messaging/firebase_messaging/example/lib/token_monitor.dart @@ -36,8 +36,9 @@ class _TokenMonitor extends State { super.initState(); FirebaseMessaging.instance .getToken( - vapidKey: - 'BNKkaUWxyP_yC_lki1kYazgca0TNhuzt2drsOrL6WrgGbqnMnr8ZMLzg_rSPDm6HKphABS0KzjPfSqCXHXEd06Y') + vapidKey: + 'BNKkaUWxyP_yC_lki1kYazgca0TNhuzt2drsOrL6WrgGbqnMnr8ZMLzg_rSPDm6HKphABS0KzjPfSqCXHXEd06Y', + ) .then(setToken); _tokenStream = FirebaseMessaging.instance.onTokenRefresh; _tokenStream.listen(setToken); diff --git a/packages/firebase_messaging/firebase_messaging/example/pubspec.yaml b/packages/firebase_messaging/firebase_messaging/example/pubspec.yaml index 0277aa0ee9ec..da0d5e1e005c 100644 --- a/packages/firebase_messaging/firebase_messaging/example/pubspec.yaml +++ b/packages/firebase_messaging/firebase_messaging/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the firebase_messaging plugin. resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core: ^4.14.0 diff --git a/packages/firebase_messaging/firebase_messaging/example/test_driver/integration_test.dart b/packages/firebase_messaging/firebase_messaging/example/test_driver/integration_test.dart index 691723cbbfe1..9ccbcc26ab97 100644 --- a/packages/firebase_messaging/firebase_messaging/example/test_driver/integration_test.dart +++ b/packages/firebase_messaging/firebase_messaging/example/test_driver/integration_test.dart @@ -7,28 +7,32 @@ import 'dart:io'; import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver( - writeResponseOnFailure: true, - responseDataCallback: (Map? data) async { - final results = - (data?['testResults'] as Map?)?.cast() ?? - const {}; - var passed = 0; - var failed = 0; - for (final entry in results.entries) { - final ok = entry.value == 'success'; - ok ? passed++ : failed++; - // ignore: avoid_print - print('${ok ? '✅' : '❌'} ${entry.key}'); - } - // ignore: avoid_print - print('Web e2e summary: $passed passed, $failed failed, ' - '${results.length} total'); - if (results.isEmpty) { - // ignore: avoid_print - print('[E] No tests reported by the app - treating as ' - 'infrastructure failure.'); - exit(1); - } - await writeResponseData(data); - }, + writeResponseOnFailure: true, + responseDataCallback: (Map? data) async { + final results = + (data?['testResults'] as Map?)?.cast() ?? + const {}; + var passed = 0; + var failed = 0; + for (final entry in results.entries) { + final ok = entry.value == 'success'; + ok ? passed++ : failed++; + // ignore: avoid_print + print('${ok ? '✅' : '❌'} ${entry.key}'); + } + // ignore: avoid_print + print( + 'Web e2e summary: $passed passed, $failed failed, ' + '${results.length} total', ); + if (results.isEmpty) { + // ignore: avoid_print + print( + '[E] No tests reported by the app - treating as ' + 'infrastructure failure.', + ); + exit(1); + } + await writeResponseData(data); + }, +); diff --git a/packages/firebase_messaging/firebase_messaging/lib/src/messaging.dart b/packages/firebase_messaging/firebase_messaging/lib/src/messaging.dart index b9f6a0ccea45..217f5879b749 100644 --- a/packages/firebase_messaging/firebase_messaging/lib/src/messaging.dart +++ b/packages/firebase_messaging/firebase_messaging/lib/src/messaging.dart @@ -18,14 +18,16 @@ class FirebaseMessaging extends FirebasePlugin { FirebaseMessagingPlatform get _delegate { return _delegatePackingProperty ??= FirebaseMessagingPlatform.instanceFor( - app: app, pluginConstants: pluginConstants); + app: app, + pluginConstants: pluginConstants, + ); } /// The [FirebaseApp] for this current [FirebaseMessaging] instance. FirebaseApp app; FirebaseMessaging._({required this.app}) - : super(app.name, 'plugins.flutter.io/firebase_messaging'); + : super(app.name, 'plugins.flutter.io/firebase_messaging'); /// Returns an instance using the default [FirebaseApp]. static FirebaseMessaging get instance { diff --git a/packages/firebase_messaging/firebase_messaging/pubspec.yaml b/packages/firebase_messaging/firebase_messaging/pubspec.yaml index 6f3917a7c630..3dcb09249780 100644 --- a/packages/firebase_messaging/firebase_messaging/pubspec.yaml +++ b/packages/firebase_messaging/firebase_messaging/pubspec.yaml @@ -14,8 +14,8 @@ false_secrets: - example/** environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core: ^4.14.0 diff --git a/packages/firebase_messaging/firebase_messaging/test/firebase_messaging_test.dart b/packages/firebase_messaging/firebase_messaging/test/firebase_messaging_test.dart index f3e1dd4204bb..15cc7005aa8d 100644 --- a/packages/firebase_messaging/firebase_messaging/test/firebase_messaging_test.dart +++ b/packages/firebase_messaging/firebase_messaging/test/firebase_messaging_test.dart @@ -62,8 +62,9 @@ void main() { test('verify delegate method is called', () async { const senderId = 'test-notification'; RemoteMessage message = const RemoteMessage(senderId: senderId); - when(kMockMessagingPlatform.getInitialMessage()) - .thenAnswer((_) => Future.value(message)); + when( + kMockMessagingPlatform.getInitialMessage(), + ).thenAnswer((_) => Future.value(message)); final result = await messaging!.getInitialMessage(); @@ -76,8 +77,9 @@ void main() { group('deleteToken', () { test('verify delegate method is called with correct args', () async { - when(kMockMessagingPlatform.deleteToken()) - .thenAnswer((_) => Future.value()); + when( + kMockMessagingPlatform.deleteToken(), + ).thenAnswer((_) => Future.value()); await messaging!.deleteToken(); @@ -88,8 +90,9 @@ void main() { group('getAPNSToken', () { test('verify delegate method is called', () async { const apnsToken = 'test-apns'; - when(kMockMessagingPlatform.getAPNSToken()) - .thenAnswer((_) => Future.value(apnsToken)); + when( + kMockMessagingPlatform.getAPNSToken(), + ).thenAnswer((_) => Future.value(apnsToken)); await messaging!.getAPNSToken(); @@ -99,47 +102,59 @@ void main() { group('getToken', () { test('verify delegate method is called with correct args', () async { const vapidKey = 'test-vapid-key'; - when(kMockMessagingPlatform.getToken( - vapidKey: anyNamed('vapidKey'), - serviceWorkerScriptPath: anyNamed('serviceWorkerScriptPath'), - )).thenAnswer((_) => Future.value('')); + when( + kMockMessagingPlatform.getToken( + vapidKey: anyNamed('vapidKey'), + serviceWorkerScriptPath: anyNamed('serviceWorkerScriptPath'), + ), + ).thenAnswer((_) => Future.value('')); await messaging!.getToken(vapidKey: vapidKey); - verify(kMockMessagingPlatform.getToken( - vapidKey: vapidKey, - serviceWorkerScriptPath: null, - )); - }); - - test('verify delegate method is called with service worker path', - () async { - const serviceWorkerScriptPath = 'custom-messaging-sw.js'; - when(kMockMessagingPlatform.getToken( - vapidKey: anyNamed('vapidKey'), - serviceWorkerScriptPath: anyNamed('serviceWorkerScriptPath'), - )).thenAnswer((_) => Future.value('')); - - await messaging!.getToken( - serviceWorkerScriptPath: serviceWorkerScriptPath, + verify( + kMockMessagingPlatform.getToken( + vapidKey: vapidKey, + serviceWorkerScriptPath: null, + ), ); - - verify(kMockMessagingPlatform.getToken( - vapidKey: null, - serviceWorkerScriptPath: serviceWorkerScriptPath, - )); }); + + test( + 'verify delegate method is called with service worker path', + () async { + const serviceWorkerScriptPath = 'custom-messaging-sw.js'; + when( + kMockMessagingPlatform.getToken( + vapidKey: anyNamed('vapidKey'), + serviceWorkerScriptPath: anyNamed('serviceWorkerScriptPath'), + ), + ).thenAnswer((_) => Future.value('')); + + await messaging!.getToken( + serviceWorkerScriptPath: serviceWorkerScriptPath, + ); + + verify( + kMockMessagingPlatform.getToken( + vapidKey: null, + serviceWorkerScriptPath: serviceWorkerScriptPath, + ), + ); + }, + ); }); group('onTokenRefresh', () { test('verify delegate method is called', () async { const token = 'test-token'; - when(kMockMessagingPlatform.onTokenRefresh) - .thenAnswer((_) => Stream.fromIterable([token])); + when( + kMockMessagingPlatform.onTokenRefresh, + ).thenAnswer((_) => Stream.fromIterable([token])); - final StreamQueue changes = - StreamQueue(messaging!.onTokenRefresh); + final StreamQueue changes = StreamQueue( + messaging!.onTokenRefresh, + ); expect(await changes.next, isA()); verify(kMockMessagingPlatform.onTokenRefresh); @@ -147,17 +162,20 @@ void main() { }); group('requestPermission', () { test('verify delegate method is called with correct args', () async { - when(kMockMessagingPlatform.requestPermission( - alert: anyNamed('alert'), - announcement: anyNamed('announcement'), - badge: anyNamed('badge'), - carPlay: anyNamed('carPlay'), - criticalAlert: anyNamed('criticalAlert'), - provisional: anyNamed('provisional'), - sound: anyNamed('sound'), - providesAppNotificationSettings: - anyNamed('providesAppNotificationSettings'), - )).thenAnswer((_) => Future.value(defaultNotificationSettings)); + when( + kMockMessagingPlatform.requestPermission( + alert: anyNamed('alert'), + announcement: anyNamed('announcement'), + badge: anyNamed('badge'), + carPlay: anyNamed('carPlay'), + criticalAlert: anyNamed('criticalAlert'), + provisional: anyNamed('provisional'), + sound: anyNamed('sound'), + providesAppNotificationSettings: anyNamed( + 'providesAppNotificationSettings', + ), + ), + ).thenAnswer((_) => Future.value(defaultNotificationSettings)); // true values await messaging!.requestPermission( @@ -171,16 +189,18 @@ void main() { providesAppNotificationSettings: true, ); - verify(kMockMessagingPlatform.requestPermission( - alert: true, - announcement: true, - badge: true, - carPlay: true, - criticalAlert: true, - provisional: true, - sound: true, - providesAppNotificationSettings: true, - )); + verify( + kMockMessagingPlatform.requestPermission( + alert: true, + announcement: true, + badge: true, + carPlay: true, + criticalAlert: true, + provisional: true, + sound: true, + providesAppNotificationSettings: true, + ), + ); // false values await messaging!.requestPermission( @@ -194,37 +214,42 @@ void main() { providesAppNotificationSettings: false, ); - verify(kMockMessagingPlatform.requestPermission( - alert: false, - announcement: false, - badge: false, - carPlay: false, - criticalAlert: false, - provisional: false, - sound: false, - providesAppNotificationSettings: false, - )); + verify( + kMockMessagingPlatform.requestPermission( + alert: false, + announcement: false, + badge: false, + carPlay: false, + criticalAlert: false, + provisional: false, + sound: false, + providesAppNotificationSettings: false, + ), + ); // default values await messaging!.requestPermission(); - verify(kMockMessagingPlatform.requestPermission( - alert: true, - announcement: false, - badge: true, - carPlay: false, - criticalAlert: false, - provisional: false, - sound: true, - providesAppNotificationSettings: false, - )); + verify( + kMockMessagingPlatform.requestPermission( + alert: true, + announcement: false, + badge: true, + carPlay: false, + criticalAlert: false, + provisional: false, + sound: true, + providesAppNotificationSettings: false, + ), + ); }); }); group('setAutoInitEnabled', () { test('verify delegate method is called with correct args', () async { - when(kMockMessagingPlatform.setAutoInitEnabled(any)) - .thenAnswer((_) => Future.value()); + when( + kMockMessagingPlatform.setAutoInitEnabled(any), + ).thenAnswer((_) => Future.value()); await messaging!.setAutoInitEnabled(false); verify(kMockMessagingPlatform.setAutoInitEnabled(false)); @@ -242,13 +267,16 @@ void main() { test('throws AssertionError if topic is invalid', () async { const invalidTopic = 'test invalid = topic'; - expect(() => messaging!.subscribeToTopic(invalidTopic), - throwsAssertionError); + expect( + () => messaging!.subscribeToTopic(invalidTopic), + throwsAssertionError, + ); }); test('verify delegate method is called with correct args', () async { - when(kMockMessagingPlatform.subscribeToTopic(any)) - .thenAnswer((_) => Future.value()); + when( + kMockMessagingPlatform.subscribeToTopic(any), + ).thenAnswer((_) => Future.value()); const topic = 'test-topic'; @@ -257,8 +285,9 @@ void main() { }); }); group('unsubscribeFromTopic', () { - when(kMockMessagingPlatform.unsubscribeFromTopic(any)) - .thenAnswer((_) => Future.value()); + when( + kMockMessagingPlatform.unsubscribeFromTopic(any), + ).thenAnswer((_) => Future.value()); test('verify delegate method is called with correct args', () async { const topic = 'test-topic'; diff --git a/packages/firebase_messaging/firebase_messaging/test/mock.dart b/packages/firebase_messaging/firebase_messaging/test/mock.dart index 4555c8d77d30..d9d5e88c919e 100644 --- a/packages/firebase_messaging/firebase_messaging/test/mock.dart +++ b/packages/firebase_messaging/firebase_messaging/test/mock.dart @@ -31,12 +31,15 @@ void setupFirebaseMessagingMocks() { // Mock Platform Interface Methods // ignore: invalid_use_of_protected_member - when(kMockMessagingPlatform.delegateFor(app: anyNamed('app'))) - .thenReturn(kMockMessagingPlatform); + when( + kMockMessagingPlatform.delegateFor(app: anyNamed('app')), + ).thenReturn(kMockMessagingPlatform); // ignore: invalid_use_of_protected_member - when(kMockMessagingPlatform.setInitialValues( - isAutoInitEnabled: anyNamed('isAutoInitEnabled'), - )).thenReturn(kMockMessagingPlatform); + when( + kMockMessagingPlatform.setInitialValues( + isAutoInitEnabled: anyNamed('isAutoInitEnabled'), + ), + ).thenReturn(kMockMessagingPlatform); } // Platform Interface Mock Classes @@ -51,8 +54,11 @@ class MockFirebaseMessaging extends Mock @override bool get isAutoInitEnabled { - return super.noSuchMethod(Invocation.getter(#isAutoInitEnabled), - returnValue: true, returnValueForMissingStub: true); + return super.noSuchMethod( + Invocation.getter(#isAutoInitEnabled), + returnValue: true, + returnValueForMissingStub: true, + ); } @override @@ -67,8 +73,9 @@ class MockFirebaseMessaging extends Mock @override FirebaseMessagingPlatform setInitialValues({bool? isAutoInitEnabled}) { return super.noSuchMethod( - Invocation.method( - #setInitialValues, [], {#isAutoInitEnabled: isAutoInitEnabled}), + Invocation.method(#setInitialValues, [], { + #isAutoInitEnabled: isAutoInitEnabled, + }), returnValue: TestFirebaseMessagingPlatform(), returnValueForMissingStub: TestFirebaseMessagingPlatform(), ); @@ -76,41 +83,50 @@ class MockFirebaseMessaging extends Mock @override Future getInitialMessage() { - return super.noSuchMethod(Invocation.method(#getInitialMessage, []), - returnValue: neverEndingFuture(), - returnValueForMissingStub: neverEndingFuture()); + return super.noSuchMethod( + Invocation.method(#getInitialMessage, []), + returnValue: neverEndingFuture(), + returnValueForMissingStub: neverEndingFuture(), + ); } @override Future deleteToken() { - return super.noSuchMethod(Invocation.method(#deleteToken, []), - returnValue: Future.value(), - returnValueForMissingStub: Future.value()); + return super.noSuchMethod( + Invocation.method(#deleteToken, []), + returnValue: Future.value(), + returnValueForMissingStub: Future.value(), + ); } @override Future getAPNSToken() { - return super.noSuchMethod(Invocation.method(#getAPNSToken, []), - returnValue: Future.value(''), - returnValueForMissingStub: Future.value('')); + return super.noSuchMethod( + Invocation.method(#getAPNSToken, []), + returnValue: Future.value(''), + returnValueForMissingStub: Future.value(''), + ); } @override Future getToken({String? vapidKey, String? serviceWorkerScriptPath}) { return super.noSuchMethod( - Invocation.method(#getToken, [], { - #vapidKey: vapidKey, - #serviceWorkerScriptPath: serviceWorkerScriptPath - }), - returnValue: Future.value(''), - returnValueForMissingStub: Future.value('')); + Invocation.method(#getToken, [], { + #vapidKey: vapidKey, + #serviceWorkerScriptPath: serviceWorkerScriptPath, + }), + returnValue: Future.value(''), + returnValueForMissingStub: Future.value(''), + ); } @override Future setAutoInitEnabled(bool? enabled) { - return super.noSuchMethod(Invocation.method(#setAutoInitEnabled, [enabled]), - returnValue: Future.value(), - returnValueForMissingStub: Future.value()); + return super.noSuchMethod( + Invocation.method(#setAutoInitEnabled, [enabled]), + returnValue: Future.value(), + returnValueForMissingStub: Future.value(), + ); } @override @@ -134,32 +150,37 @@ class MockFirebaseMessaging extends Mock bool? providesAppNotificationSettings = false, }) { return super.noSuchMethod( - Invocation.method(#requestPermission, [], { - #alert: alert, - #announcement: announcement, - #badge: badge, - #carPlay: carPlay, - #criticalAlert: criticalAlert, - #provisional: provisional, - #sound: sound, - #providesAppNotificationSettings: providesAppNotificationSettings, - }), - returnValue: neverEndingFuture(), - returnValueForMissingStub: neverEndingFuture()); + Invocation.method(#requestPermission, [], { + #alert: alert, + #announcement: announcement, + #badge: badge, + #carPlay: carPlay, + #criticalAlert: criticalAlert, + #provisional: provisional, + #sound: sound, + #providesAppNotificationSettings: providesAppNotificationSettings, + }), + returnValue: neverEndingFuture(), + returnValueForMissingStub: neverEndingFuture(), + ); } @override Future subscribeToTopic(String? topic) { - return super.noSuchMethod(Invocation.method(#subscribeToTopic, [topic]), - returnValue: Future.value(), - returnValueForMissingStub: Future.value()); + return super.noSuchMethod( + Invocation.method(#subscribeToTopic, [topic]), + returnValue: Future.value(), + returnValueForMissingStub: Future.value(), + ); } @override Future unsubscribeFromTopic(String? topic) { - return super.noSuchMethod(Invocation.method(#unsubscribeFromTopic, [topic]), - returnValue: Future.value(), - returnValueForMissingStub: Future.value()); + return super.noSuchMethod( + Invocation.method(#unsubscribeFromTopic, [topic]), + returnValue: Future.value(), + returnValueForMissingStub: Future.value(), + ); } } diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/method_channel_messaging.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/method_channel_messaging.dart index 73788d05c3de..ead88b3eb39e 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/method_channel_messaging.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/method_channel_messaging.dart @@ -32,23 +32,27 @@ void _firebaseMessagingCallbackDispatcher() { // This is where we handle background events from the native portion of the plugin. _channel.setMethodCallHandler((MethodCall call) async { if (call.method == 'MessagingBackground#onMessage') { - final CallbackHandle handle = - CallbackHandle.fromRawHandle(call.arguments['userCallbackHandle']); + final CallbackHandle handle = CallbackHandle.fromRawHandle( + call.arguments['userCallbackHandle'], + ); // PluginUtilities.getCallbackFromHandle performs a lookup based on the // callback handle and returns a tear-off of the original callback. - final closure = PluginUtilities.getCallbackFromHandle(handle)! - as Future Function(RemoteMessage); + final closure = + PluginUtilities.getCallbackFromHandle(handle)! + as Future Function(RemoteMessage); try { - Map messageMap = - Map.from(call.arguments['message']); + Map messageMap = Map.from( + call.arguments['message'], + ); final RemoteMessage remoteMessage = RemoteMessage.fromMap(messageMap); await closure(remoteMessage); } catch (e) { // ignore: avoid_print print( - 'FlutterFire Messaging: An error occurred in your background messaging handler:'); + 'FlutterFire Messaging: An error occurred in your background messaging handler:', + ); // ignore: avoid_print print(e); } @@ -68,7 +72,7 @@ void _firebaseMessagingCallbackDispatcher() { class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { /// Create an instance of [MethodChannelFirebaseMessaging] with optional [FirebaseApp] MethodChannelFirebaseMessaging({required FirebaseApp app}) - : super(appInstance: app); + : super(appInstance: app); late bool _autoInitEnabled; @@ -87,31 +91,39 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { MethodChannelFirebaseMessaging._() : super(appInstance: null); static void setMethodCallHandlers() { - MethodChannelFirebaseMessaging.channel - .setMethodCallHandler((MethodCall call) async { + MethodChannelFirebaseMessaging.channel.setMethodCallHandler(( + MethodCall call, + ) async { switch (call.method) { case 'Messaging#onTokenRefresh': - MethodChannelFirebaseMessaging.tokenStreamController - .add(call.arguments as String); + MethodChannelFirebaseMessaging.tokenStreamController.add( + call.arguments as String, + ); break; case 'Messaging#onMessage': - Map messageMap = - Map.from(call.arguments); - FirebaseMessagingPlatform.onMessage - .add(RemoteMessage.fromMap(messageMap)); + Map messageMap = Map.from( + call.arguments, + ); + FirebaseMessagingPlatform.onMessage.add( + RemoteMessage.fromMap(messageMap), + ); break; case 'Messaging#onMessageOpenedApp': - Map messageMap = - Map.from(call.arguments); - FirebaseMessagingPlatform.onMessageOpenedApp - .add(RemoteMessage.fromMap(messageMap)); + Map messageMap = Map.from( + call.arguments, + ); + FirebaseMessagingPlatform.onMessageOpenedApp.add( + RemoteMessage.fromMap(messageMap), + ); break; case 'Messaging#onBackgroundMessage': // Apple only. Android calls via separate background channel. - Map messageMap = - Map.from(call.arguments); - return FirebaseMessagingPlatform.onBackgroundMessage - ?.call(RemoteMessage.fromMap(messageMap)); + Map messageMap = Map.from( + call.arguments, + ); + return FirebaseMessagingPlatform.onBackgroundMessage?.call( + RemoteMessage.fromMap(messageMap), + ); default: throw UnimplementedError('${call.method} has not been implemented'); } @@ -172,8 +184,8 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { try { Map? remoteMessageMap = await channel .invokeMapMethod('Messaging#getInitialMessage', { - 'appName': app.name, - }); + 'appName': app.name, + }); if (remoteMessageMap == null) { return null; @@ -187,7 +199,8 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { @override Future registerBackgroundMessageHandler( - BackgroundMessageHandler handler) async { + BackgroundMessageHandler handler, + ) async { if (defaultTargetPlatform != TargetPlatform.android) { return; } @@ -197,8 +210,9 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { final CallbackHandle bgHandle = PluginUtilities.getCallbackHandle( _firebaseMessagingCallbackDispatcher, )!; - final CallbackHandle userHandle = - PluginUtilities.getCallbackHandle(handler)!; + final CallbackHandle userHandle = PluginUtilities.getCallbackHandle( + handler, + )!; await channel.invokeMapMethod('Messaging#startBackgroundIsolate', { 'pluginCallbackHandle': bgHandle.toRawHandle(), 'userCallbackHandle': userHandle.toRawHandle(), @@ -211,8 +225,9 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { await _APNSTokenCheck(); try { - await channel - .invokeMapMethod('Messaging#deleteToken', {'appName': app.name}); + await channel.invokeMapMethod('Messaging#deleteToken', { + 'appName': app.name, + }); } catch (e, stack) { convertPlatformException(e, stack); } @@ -228,8 +243,8 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { try { Map? data = await channel .invokeMapMethod('Messaging#getAPNSToken', { - 'appName': app.name, - }); + 'appName': app.name, + }); return data!['token']; } catch (e, stack) { @@ -245,10 +260,10 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { await _APNSTokenCheck(); try { - Map? data = - await channel.invokeMapMethod('Messaging#getToken', { - 'appName': app.name, - }); + Map? data = await channel + .invokeMapMethod('Messaging#getToken', { + 'appName': app.name, + }); return data!['token']; } catch (e, stack) { @@ -265,10 +280,10 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { } try { - Map? response = await channel - .invokeMapMethod('Messaging#getNotificationSettings', { - 'appName': app.name, - }); + Map? response = await channel.invokeMapMethod( + 'Messaging#getNotificationSettings', + {'appName': app.name}, + ); return convertToNotificationSettings(response!); } catch (e, stack) { @@ -294,20 +309,22 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { } try { - Map? response = await channel - .invokeMapMethod('Messaging#requestPermission', { - 'appName': app.name, - 'permissions': { - 'alert': alert, - 'announcement': announcement, - 'badge': badge, - 'carPlay': carPlay, - 'criticalAlert': criticalAlert, - 'provisional': provisional, - 'sound': sound, - 'providesAppNotificationSettings': providesAppNotificationSettings, - } - }); + Map? response = await channel.invokeMapMethod( + 'Messaging#requestPermission', + { + 'appName': app.name, + 'permissions': { + 'alert': alert, + 'announcement': announcement, + 'badge': badge, + 'carPlay': carPlay, + 'criticalAlert': criticalAlert, + 'provisional': provisional, + 'sound': sound, + 'providesAppNotificationSettings': providesAppNotificationSettings, + }, + }, + ); return convertToNotificationSettings(response!); } catch (e, stack) { @@ -320,9 +337,9 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { try { Map? data = await channel .invokeMapMethod('Messaging#setAutoInitEnabled', { - 'appName': app.name, - 'enabled': enabled, - }); + 'appName': app.name, + 'enabled': enabled, + }); _autoInitEnabled = data!['isAutoInitEnabled'] as bool; } catch (e, stack) { @@ -348,12 +365,9 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { try { await channel.invokeMapMethod( - 'Messaging#setForegroundNotificationPresentationOptions', { - 'appName': app.name, - 'alert': alert, - 'badge': badge, - 'sound': sound, - }); + 'Messaging#setForegroundNotificationPresentationOptions', + {'appName': app.name, 'alert': alert, 'badge': badge, 'sound': sound}, + ); } catch (e, stack) { convertPlatformException(e, stack); } @@ -394,11 +408,10 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { return; } try { - await channel - .invokeMapMethod('Messaging#setDeliveryMetricsExportToBigQuery', { - 'appName': app.name, - 'enabled': enabled, - }); + await channel.invokeMapMethod( + 'Messaging#setDeliveryMetricsExportToBigQuery', + {'appName': app.name, 'enabled': enabled}, + ); } catch (e, stack) { convertPlatformException(e, stack); } diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/platform_interface/platform_interface_messaging.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/platform_interface/platform_interface_messaging.dart index 44d20d32ed5b..8e523c08f96b 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/platform_interface/platform_interface_messaging.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/platform_interface/platform_interface_messaging.dart @@ -121,9 +121,7 @@ abstract class FirebaseMessagingPlatform extends PlatformInterface { /// before the instance has initialized to prevent any unnecessary async /// calls. @protected - FirebaseMessagingPlatform setInitialValues({ - bool? isAutoInitEnabled, - }) { + FirebaseMessagingPlatform setInitialValues({bool? isAutoInitEnabled}) { throw UnimplementedError('setInitialValues() is not implemented'); } @@ -154,7 +152,8 @@ abstract class FirebaseMessagingPlatform extends PlatformInterface { /// on web a service worker can be registered. void registerBackgroundMessageHandler(BackgroundMessageHandler handler) { throw UnimplementedError( - 'registerBackgroundMessageHandler() is not implemented'); + 'registerBackgroundMessageHandler() is not implemented', + ); } /// Removes access to an FCM token previously authorized with optional [senderId]. @@ -293,7 +292,8 @@ abstract class FirebaseMessagingPlatform extends PlatformInterface { required bool sound, }) { throw UnimplementedError( - 'setForegroundNotificationPresentationOptions() is not implemented'); + 'setForegroundNotificationPresentationOptions() is not implemented', + ); } /// Subscribe to topic in background. diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/remote_message.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/remote_message.dart index 1b39fad8d387..c0ec5aefaaf0 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/remote_message.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/remote_message.dart @@ -8,21 +8,22 @@ import 'package:firebase_messaging_platform_interface/firebase_messaging_platfor /// A class representing a message sent from Firebase Cloud Messaging. class RemoteMessage { // ignore: public_member_api_docs - const RemoteMessage( - {this.senderId, - this.category, - this.actionIdentifier, - this.collapseKey, - this.contentAvailable = false, - this.data = const {}, - this.from, - this.messageId, - this.messageType, - this.mutableContent = false, - this.notification, - this.sentTime, - this.threadId, - this.ttl}); + const RemoteMessage({ + this.senderId, + this.category, + this.actionIdentifier, + this.collapseKey, + this.contentAvailable = false, + this.data = const {}, + this.from, + this.messageId, + this.messageType, + this.mutableContent = false, + this.notification, + this.sentTime, + this.threadId, + this.ttl, + }); /// Constructs a [RemoteMessage] from a raw Map. factory RemoteMessage.fromMap(Map map) { @@ -43,12 +44,14 @@ class RemoteMessage { notification: map['notification'] == null ? null : RemoteNotification.fromMap( - Map.from(map['notification'])), + Map.from(map['notification']), + ), // Note: using toString on sentTime as it can be an int or string when being sent from native. sentTime: map['sentTime'] == null ? null : DateTime.fromMillisecondsSinceEpoch( - int.parse(map['sentTime'].toString())), + int.parse(map['sentTime'].toString()), + ), threadId: map['threadId'], ttl: map['ttl'], ); diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/remote_notification.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/remote_notification.dart index b800c62b4ab1..1fbe146d4ecf 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/remote_notification.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/remote_notification.dart @@ -36,7 +36,8 @@ class RemoteNotification { bodyLocKey: map['bodyLocKey'], android: map['android'] != null ? AndroidNotification.fromMap( - Map.from(map['android'])) + Map.from(map['android']), + ) : null, apple: map['apple'] != null ? AppleNotification.fromMap(Map.from(map['apple'])) @@ -215,7 +216,8 @@ class AppleNotification { sound: map['sound'] == null ? null : AppleNotificationSound.fromMap( - Map.from(map['sound'])), + Map.from(map['sound']), + ), ); } @@ -302,11 +304,7 @@ List _toList(dynamic value) { /// Web specific properties of a [RemoteNotification]. class WebNotification { - const WebNotification({ - this.analyticsLabel, - this.image, - this.link, - }); + const WebNotification({this.analyticsLabel, this.image, this.link}); /// Constructs a [WebNotification] from a raw Map. factory WebNotification.fromMap(Map map) { diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/utils.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/utils.dart index eb4a4fc54271..a882899b40e7 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/utils.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/utils.dart @@ -7,7 +7,8 @@ import 'package:firebase_messaging_platform_interface/firebase_messaging_platfor /// Converts an [int] into it's [AndroidNotificationPriority] representation. AndroidNotificationPriority convertToAndroidNotificationPriority( - int? priority) { + int? priority, +) { switch (priority) { case -2: return AndroidNotificationPriority.minimumPriority; @@ -26,7 +27,8 @@ AndroidNotificationPriority convertToAndroidNotificationPriority( /// Converts an [AndroidNotificationPriority] into it's [int] representation. int convertAndroidNotificationPriorityToInt( - AndroidNotificationPriority? priority) { + AndroidNotificationPriority? priority, +) { switch (priority) { case AndroidNotificationPriority.minimumPriority: return -2; @@ -45,7 +47,8 @@ int convertAndroidNotificationPriorityToInt( /// Converts an [int] into it's [AndroidNotificationVisibility] representation. AndroidNotificationVisibility convertToAndroidNotificationVisibility( - int? visibility) { + int? visibility, +) { switch (visibility) { case -1: return AndroidNotificationVisibility.secret; @@ -60,7 +63,8 @@ AndroidNotificationVisibility convertToAndroidNotificationVisibility( /// Converts an [AndroidNotificationVisibility] into it's [int] representation. int convertAndroidNotificationVisibilityToInt( - AndroidNotificationVisibility? visibility) { + AndroidNotificationVisibility? visibility, +) { switch (visibility) { case AndroidNotificationVisibility.secret: return -1; @@ -132,8 +136,9 @@ AppleShowPreviewSetting convertToAppleShowPreviewSetting(int? status) { /// Converts a [Map] into it's [NotificationSettings] representation. NotificationSettings convertToNotificationSettings(Map map) { return NotificationSettings( - authorizationStatus: - convertToAuthorizationStatus(map['authorizationStatus']), + authorizationStatus: convertToAuthorizationStatus( + map['authorizationStatus'], + ), timeSensitive: convertToAppleNotificationSetting(map['timeSensitive']), criticalAlert: convertToAppleNotificationSetting(map['criticalAlert']), alert: convertToAppleNotificationSetting(map['alert']), @@ -141,12 +146,14 @@ NotificationSettings convertToNotificationSettings(Map map) { badge: convertToAppleNotificationSetting(map['badge']), carPlay: convertToAppleNotificationSetting(map['carPlay']), lockScreen: convertToAppleNotificationSetting(map['lockScreen']), - notificationCenter: - convertToAppleNotificationSetting(map['notificationCenter']), + notificationCenter: convertToAppleNotificationSetting( + map['notificationCenter'], + ), showPreviews: convertToAppleShowPreviewSetting(map['showPreviews']), sound: convertToAppleNotificationSetting(map['sound']), providesAppNotificationSettings: convertToAppleNotificationSetting( - map['providesAppNotificationSettings']), + map['providesAppNotificationSettings'], + ), ); } diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/pubspec.yaml b/packages/firebase_messaging/firebase_messaging_platform_interface/pubspec.yaml index bffd269232f9..3dfcd69826e5 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/pubspec.yaml +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/pubspec.yaml @@ -6,8 +6,8 @@ homepage: https://github.com/firebase/flutterfire/tree/main/packages/firebase_me repository: https://github.com/firebase/flutterfire/tree/main/packages/firebase_messaging/firebase_messaging_platform_interface environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/test/method_channel_tests/method_channel_messaging_test.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/test/method_channel_tests/method_channel_messaging_test.dart index 87755024f8f1..7c7e78eb7df8 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/test/method_channel_tests/method_channel_messaging_test.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/test/method_channel_tests/method_channel_messaging_test.dart @@ -34,9 +34,7 @@ void main() { return null; case 'Messaging#getAPNSToken': case 'Messaging#getToken': - return { - 'token': 'test_token', - }; + return {'token': 'test_token'}; case 'Messaging#hasPermission': case 'Messaging#requestPermission': case 'Messaging#getNotificationSettings': @@ -52,9 +50,7 @@ void main() { 'providesAppNotificationSettings': 0, }; case 'Messaging#setAutoInitEnabled': - return { - 'isAutoInitEnabled': call.arguments['enabled'], - }; + return {'isAutoInitEnabled': call.arguments['enabled']}; case 'Messaging#deleteInstanceID': return true; default: @@ -72,8 +68,10 @@ void main() { group('$FirebaseMessagingPlatform()', () { test('$MethodChannelFirebaseMessaging is the default instance', () { - expect(FirebaseMessagingPlatform.instance, - isA()); + expect( + FirebaseMessagingPlatform.instance, + isA(), + ); }); test('Cannot be implemented with `implements`', () { @@ -103,16 +101,18 @@ void main() { group('setInitialValues()', () { test('when isAutoInitEnabled is false', () { - final testMessaging = - TestMethodChannelFirebaseMessaging(Firebase.app()); + final testMessaging = TestMethodChannelFirebaseMessaging( + Firebase.app(), + ); final result = testMessaging.setInitialValues(isAutoInitEnabled: false); expect(result, isA()); expect(result.isAutoInitEnabled, isFalse); }); test('when isAutoInitEnabled is true', () { - final testMessaging = - TestMethodChannelFirebaseMessaging(Firebase.app()); + final testMessaging = TestMethodChannelFirebaseMessaging( + Firebase.app(), + ); final result = testMessaging.setInitialValues(isAutoInitEnabled: true); expect(result, isA()); expect(result.isAutoInitEnabled, isTrue); @@ -132,9 +132,7 @@ void main() { expect(log, [ isMethodCall( 'Messaging#deleteToken', - arguments: { - 'appName': defaultFirebaseAppName, - }, + arguments: {'appName': defaultFirebaseAppName}, ), ]); }); @@ -148,9 +146,7 @@ void main() { expect(log, [ isMethodCall( 'Messaging#getAPNSToken', - arguments: { - 'appName': defaultFirebaseAppName, - }, + arguments: {'appName': defaultFirebaseAppName}, ), ]); }); @@ -162,9 +158,7 @@ void main() { expect(log, [ isMethodCall( 'Messaging#getToken', - arguments: { - 'appName': defaultFirebaseAppName, - }, + arguments: {'appName': defaultFirebaseAppName}, ), ]); }); @@ -173,157 +167,159 @@ void main() { final settings = await messaging.getNotificationSettings(); expect(settings, isA()); expect( - settings.authorizationStatus, equals(AuthorizationStatus.authorized)); + settings.authorizationStatus, + equals(AuthorizationStatus.authorized), + ); // check native method was called expect(log, [ isMethodCall( 'Messaging#getNotificationSettings', - arguments: { - 'appName': defaultFirebaseAppName, - }, + arguments: {'appName': defaultFirebaseAppName}, ), ]); }); test( - 'getNotificationSettings returns notDetermined when authorizationStatus is -1', - () async { - // Override the method handler to return notDetermined (-1) - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(MethodChannelFirebaseMessaging.channel, - (call) async { - log.add(call); - if (call.method == 'Messaging#getNotificationSettings') { - return { - 'authorizationStatus': -1, - 'alert': -1, - 'announcement': -1, - 'badge': -1, - 'carPlay': -1, - 'criticalAlert': -1, - 'provisional': -1, - 'sound': -1, - 'providesAppNotificationSettings': -1, - }; - } - return {}; - }); - - final settings = await messaging.getNotificationSettings(); - expect(settings.authorizationStatus, - equals(AuthorizationStatus.notDetermined)); - - // Restore original handler - handleMethodCall((call) async { - log.add(call); - switch (call.method) { - case 'Messaging#deleteToken': - case 'Messaging#subscribeToTopic': - case 'Messaging#unsubscribeFromTopic': - return null; - case 'Messaging#getAPNSToken': - case 'Messaging#getToken': - return { - 'token': 'test_token', - }; - case 'Messaging#hasPermission': - case 'Messaging#requestPermission': - case 'Messaging#getNotificationSettings': - return { - 'authorizationStatus': 1, - 'alert': 1, - 'announcement': 0, - 'badge': 1, - 'carPlay': 0, - 'criticalAlert': 0, - 'provisional': 0, - 'sound': 1, - 'providesAppNotificationSettings': 0, - }; - case 'Messaging#setAutoInitEnabled': - return { - 'isAutoInitEnabled': call.arguments['enabled'], - }; - case 'Messaging#deleteInstanceID': - return true; - default: - return {}; - } - }); - }); + 'getNotificationSettings returns notDetermined when authorizationStatus is -1', + () async { + // Override the method handler to return notDetermined (-1) + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(MethodChannelFirebaseMessaging.channel, ( + call, + ) async { + log.add(call); + if (call.method == 'Messaging#getNotificationSettings') { + return { + 'authorizationStatus': -1, + 'alert': -1, + 'announcement': -1, + 'badge': -1, + 'carPlay': -1, + 'criticalAlert': -1, + 'provisional': -1, + 'sound': -1, + 'providesAppNotificationSettings': -1, + }; + } + return {}; + }); + + final settings = await messaging.getNotificationSettings(); + expect( + settings.authorizationStatus, + equals(AuthorizationStatus.notDetermined), + ); + + // Restore original handler + handleMethodCall((call) async { + log.add(call); + switch (call.method) { + case 'Messaging#deleteToken': + case 'Messaging#subscribeToTopic': + case 'Messaging#unsubscribeFromTopic': + return null; + case 'Messaging#getAPNSToken': + case 'Messaging#getToken': + return {'token': 'test_token'}; + case 'Messaging#hasPermission': + case 'Messaging#requestPermission': + case 'Messaging#getNotificationSettings': + return { + 'authorizationStatus': 1, + 'alert': 1, + 'announcement': 0, + 'badge': 1, + 'carPlay': 0, + 'criticalAlert': 0, + 'provisional': 0, + 'sound': 1, + 'providesAppNotificationSettings': 0, + }; + case 'Messaging#setAutoInitEnabled': + return {'isAutoInitEnabled': call.arguments['enabled']}; + case 'Messaging#deleteInstanceID': + return true; + default: + return {}; + } + }); + }, + ); test( - 'getNotificationSettings returns deniedPermanently when authorizationStatus is 3', - () async { - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(MethodChannelFirebaseMessaging.channel, - (call) async { - log.add(call); - if (call.method == 'Messaging#getNotificationSettings') { - return { - 'authorizationStatus': 3, - 'alert': 0, - 'announcement': 0, - 'badge': 0, - 'carPlay': 0, - 'criticalAlert': 0, - 'provisional': 0, - 'sound': 0, - 'providesAppNotificationSettings': 0, - }; - } - return {}; - }); - - final settings = await messaging.getNotificationSettings(); - expect(settings.authorizationStatus, - equals(AuthorizationStatus.deniedPermanently)); - - // Restore original handler - handleMethodCall((call) async { - log.add(call); - switch (call.method) { - case 'Messaging#deleteToken': - case 'Messaging#subscribeToTopic': - case 'Messaging#unsubscribeFromTopic': - return null; - case 'Messaging#getAPNSToken': - case 'Messaging#getToken': - return { - 'token': 'test_token', - }; - case 'Messaging#hasPermission': - case 'Messaging#requestPermission': - case 'Messaging#getNotificationSettings': - return { - 'authorizationStatus': 1, - 'alert': 1, - 'announcement': 0, - 'badge': 1, - 'carPlay': 0, - 'criticalAlert': 0, - 'provisional': 0, - 'sound': 1, - 'providesAppNotificationSettings': 0, - }; - case 'Messaging#setAutoInitEnabled': - return { - 'isAutoInitEnabled': call.arguments['enabled'], - }; - case 'Messaging#deleteInstanceID': - return true; - default: - return {}; - } - }); - }); + 'getNotificationSettings returns deniedPermanently when authorizationStatus is 3', + () async { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(MethodChannelFirebaseMessaging.channel, ( + call, + ) async { + log.add(call); + if (call.method == 'Messaging#getNotificationSettings') { + return { + 'authorizationStatus': 3, + 'alert': 0, + 'announcement': 0, + 'badge': 0, + 'carPlay': 0, + 'criticalAlert': 0, + 'provisional': 0, + 'sound': 0, + 'providesAppNotificationSettings': 0, + }; + } + return {}; + }); + + final settings = await messaging.getNotificationSettings(); + expect( + settings.authorizationStatus, + equals(AuthorizationStatus.deniedPermanently), + ); + + // Restore original handler + handleMethodCall((call) async { + log.add(call); + switch (call.method) { + case 'Messaging#deleteToken': + case 'Messaging#subscribeToTopic': + case 'Messaging#unsubscribeFromTopic': + return null; + case 'Messaging#getAPNSToken': + case 'Messaging#getToken': + return {'token': 'test_token'}; + case 'Messaging#hasPermission': + case 'Messaging#requestPermission': + case 'Messaging#getNotificationSettings': + return { + 'authorizationStatus': 1, + 'alert': 1, + 'announcement': 0, + 'badge': 1, + 'carPlay': 0, + 'criticalAlert': 0, + 'provisional': 0, + 'sound': 1, + 'providesAppNotificationSettings': 0, + }; + case 'Messaging#setAutoInitEnabled': + return {'isAutoInitEnabled': call.arguments['enabled']}; + case 'Messaging#deleteInstanceID': + return true; + default: + return {}; + } + }); + }, + ); test('requestPermission', () async { // test android response final androidPermissions = await messaging.requestPermission(); - expect(androidPermissions.authorizationStatus, - equals(AuthorizationStatus.authorized)); + expect( + androidPermissions.authorizationStatus, + equals(AuthorizationStatus.authorized), + ); // clear log log.clear(); @@ -331,8 +327,10 @@ void main() { debugDefaultTargetPlatformOverride = TargetPlatform.iOS; final iosStatus = await messaging.requestPermission(); expect(iosStatus.authorizationStatus, isA()); - expect(iosStatus.authorizationStatus, - equals(AuthorizationStatus.authorized)); + expect( + iosStatus.authorizationStatus, + equals(AuthorizationStatus.authorized), + ); // check native method was called expect(log, [ @@ -349,7 +347,7 @@ void main() { 'provisional': false, 'sound': true, 'providesAppNotificationSettings': false, - } + }, }, ), ]); @@ -365,7 +363,7 @@ void main() { 'Messaging#setAutoInitEnabled', arguments: { 'appName': defaultFirebaseAppName, - 'enabled': true + 'enabled': true, }, ), ]); @@ -381,7 +379,7 @@ void main() { 'Messaging#setAutoInitEnabled', arguments: { 'appName': defaultFirebaseAppName, - 'enabled': false + 'enabled': false, }, ), ]); diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/test/mock.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/test/mock.dart index b2b47fb88295..77add1a94107 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/test/mock.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/test/mock.dart @@ -19,10 +19,11 @@ void setupFirebaseMessagingMocks([Callback? customHandlers]) { void handleMethodCall(MethodCallCallback methodCallCallback) => TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(MethodChannelFirebaseMessaging.channel, - (call) async { - return await methodCallCallback(call); - }); + .setMockMethodCallHandler(MethodChannelFirebaseMessaging.channel, ( + call, + ) async { + return await methodCallCallback(call); + }); Future testExceptionHandling(String type, Function testMethod) async { try { @@ -32,7 +33,8 @@ Future testExceptionHandling(String type, Function testMethod) async { return; } fail( - 'testExceptionHandling: $testMethod threw unexpected FirebaseException'); + 'testExceptionHandling: $testMethod threw unexpected FirebaseException', + ); } catch (e) { fail('testExceptionHandling: $testMethod threw invalid exception $e'); } diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/test/notification_test.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/test/notification_test.dart index 7f49a4d27182..defac9b77995 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/test/notification_test.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/test/notification_test.dart @@ -22,15 +22,16 @@ void main() { }; RemoteNotification notification = RemoteNotification( - android: const AndroidNotification(), - apple: const AppleNotification(), - web: const WebNotification(), - title: mockNotificationMap['title'], - titleLocArgs: mockNotificationMap['titleLocArgs'], - titleLocKey: mockNotificationMap['titleLocKey'], - body: mockNotificationMap['body'], - bodyLocArgs: mockNotificationMap['bodyLocArgs'], - bodyLocKey: mockNotificationMap['bodyLocKey']); + android: const AndroidNotification(), + apple: const AppleNotification(), + web: const WebNotification(), + title: mockNotificationMap['title'], + titleLocArgs: mockNotificationMap['titleLocArgs'], + titleLocKey: mockNotificationMap['titleLocKey'], + body: mockNotificationMap['body'], + bodyLocArgs: mockNotificationMap['bodyLocArgs'], + bodyLocKey: mockNotificationMap['bodyLocKey'], + ); expect(notification.title, mockNotificationMap['title']); expect(notification.titleLocArgs, mockNotificationMap['titleLocArgs']); @@ -57,79 +58,85 @@ void main() { expect(notification.web, null); }); - test('"RemoteNotification.fromMap" with every possible property expected', - () { - Map mockNotificationMap = { - 'title': 'title', - 'titleLocArgs': ['titleLocArgs'], - 'titleLocKey': 'titleLocKey', - 'body': 'body', - 'bodyLocArgs': ['bodyLocArgs'], - 'bodyLocKey': 'bodyLocKey', - 'android': {}, - 'apple': {}, - 'web': {}, - }; - - RemoteNotification notification = - RemoteNotification.fromMap(mockNotificationMap); - - expect(notification.title, mockNotificationMap['title']); - expect(notification.titleLocArgs, mockNotificationMap['titleLocArgs']); - expect(notification.titleLocKey, mockNotificationMap['titleLocKey']); - expect(notification.body, mockNotificationMap['body']); - expect(notification.bodyLocArgs, mockNotificationMap['bodyLocArgs']); - expect(notification.bodyLocKey, mockNotificationMap['bodyLocKey']); - expect(notification.android, isA()); - expect(notification.apple, isA()); - expect(notification.web, isA()); - }); + test( + '"RemoteNotification.fromMap" with every possible property expected', + () { + Map mockNotificationMap = { + 'title': 'title', + 'titleLocArgs': ['titleLocArgs'], + 'titleLocKey': 'titleLocKey', + 'body': 'body', + 'bodyLocArgs': ['bodyLocArgs'], + 'bodyLocKey': 'bodyLocKey', + 'android': {}, + 'apple': {}, + 'web': {}, + }; + + RemoteNotification notification = RemoteNotification.fromMap( + mockNotificationMap, + ); + + expect(notification.title, mockNotificationMap['title']); + expect(notification.titleLocArgs, mockNotificationMap['titleLocArgs']); + expect(notification.titleLocKey, mockNotificationMap['titleLocKey']); + expect(notification.body, mockNotificationMap['body']); + expect(notification.bodyLocArgs, mockNotificationMap['bodyLocArgs']); + expect(notification.bodyLocKey, mockNotificationMap['bodyLocKey']); + expect(notification.android, isA()); + expect(notification.apple, isA()); + expect(notification.web, isA()); + }, + ); test( - '"RemoteNotification.fromMap" with nullable properties mapped as null & default values invoked', - () { - Map mockNullNotificationMap = { - 'title': null, - 'titleLocKey': null, - 'body': null, - 'bodyLocKey': null, - 'android': null, - 'apple': null, - 'web': null, - }; - RemoteNotification notification = - RemoteNotification.fromMap(mockNullNotificationMap); - - RemoteNotification defaultNotification = const RemoteNotification(); - - expect(notification.title, defaultNotification.title); - expect(notification.titleLocArgs, defaultNotification.titleLocArgs); - expect(notification.titleLocKey, defaultNotification.titleLocKey); - expect(notification.body, defaultNotification.body); - expect(notification.bodyLocArgs, defaultNotification.bodyLocArgs); - expect(notification.bodyLocKey, defaultNotification.bodyLocKey); - expect(notification.android, defaultNotification.android); - expect(notification.apple, defaultNotification.apple); - expect(notification.web, defaultNotification.web); - }); + '"RemoteNotification.fromMap" with nullable properties mapped as null & default values invoked', + () { + Map mockNullNotificationMap = { + 'title': null, + 'titleLocKey': null, + 'body': null, + 'bodyLocKey': null, + 'android': null, + 'apple': null, + 'web': null, + }; + RemoteNotification notification = RemoteNotification.fromMap( + mockNullNotificationMap, + ); + + RemoteNotification defaultNotification = const RemoteNotification(); + + expect(notification.title, defaultNotification.title); + expect(notification.titleLocArgs, defaultNotification.titleLocArgs); + expect(notification.titleLocKey, defaultNotification.titleLocKey); + expect(notification.body, defaultNotification.body); + expect(notification.bodyLocArgs, defaultNotification.bodyLocArgs); + expect(notification.bodyLocKey, defaultNotification.bodyLocKey); + expect(notification.android, defaultNotification.android); + expect(notification.apple, defaultNotification.apple); + expect(notification.web, defaultNotification.web); + }, + ); test( - '"RemoteNotification.fromMap" with no properties & default values invoked', - () { - RemoteNotification notification = RemoteNotification.fromMap({}); - - RemoteNotification defaultNotification = const RemoteNotification(); - - expect(notification.title, defaultNotification.title); - expect(notification.titleLocArgs, defaultNotification.titleLocArgs); - expect(notification.titleLocKey, defaultNotification.titleLocKey); - expect(notification.body, defaultNotification.body); - expect(notification.bodyLocArgs, defaultNotification.bodyLocArgs); - expect(notification.bodyLocKey, defaultNotification.bodyLocKey); - expect(notification.android, defaultNotification.android); - expect(notification.apple, defaultNotification.apple); - expect(notification.web, defaultNotification.web); - }); + '"RemoteNotification.fromMap" with no properties & default values invoked', + () { + RemoteNotification notification = RemoteNotification.fromMap({}); + + RemoteNotification defaultNotification = const RemoteNotification(); + + expect(notification.title, defaultNotification.title); + expect(notification.titleLocArgs, defaultNotification.titleLocArgs); + expect(notification.titleLocKey, defaultNotification.titleLocKey); + expect(notification.body, defaultNotification.body); + expect(notification.bodyLocArgs, defaultNotification.bodyLocArgs); + expect(notification.bodyLocKey, defaultNotification.bodyLocKey); + expect(notification.android, defaultNotification.android); + expect(notification.apple, defaultNotification.apple); + expect(notification.web, defaultNotification.web); + }, + ); test('RemoteNotification.toMap returns "RemoteNotification" as Map', () { RemoteNotification notification = const RemoteNotification( @@ -215,105 +222,117 @@ void main() { expect(notification.imageUrl, null); expect(notification.link, null); expect( - notification.priority, AndroidNotificationPriority.defaultPriority); + notification.priority, + AndroidNotificationPriority.defaultPriority, + ); expect(notification.smallIcon, null); expect(notification.sound, null); expect(notification.ticker, null); expect(notification.visibility, AndroidNotificationVisibility.private); }); - test('"AndroidNotification.fromMap" with every possible property expected', - () { - Map? androidNotificationMap = { - 'channelId': 'channelId', - 'clickAction': 'clickAction', - 'color': 'color', - 'count': 5, - 'imageUrl': 'imageUrl', - 'link': 'link', - 'priority': 2, - 'smallIcon': 'smallIcon', - 'sound': 'sound', - 'ticker': 'ticker', - 'tag': 'tag', - 'visibility': -1, - }; - - final AndroidNotification notification = - AndroidNotification.fromMap(androidNotificationMap); - - expect(notification.channelId, androidNotificationMap['channelId']); - expect(notification.clickAction, androidNotificationMap['clickAction']); - expect(notification.color, androidNotificationMap['color']); - expect(notification.count, androidNotificationMap['count']); - expect(notification.imageUrl, androidNotificationMap['imageUrl']); - expect(notification.link, androidNotificationMap['link']); - expect( - notification.priority, AndroidNotificationPriority.maximumPriority); - expect(notification.smallIcon, androidNotificationMap['smallIcon']); - expect(notification.sound, androidNotificationMap['sound']); - expect(notification.ticker, androidNotificationMap['ticker']); - expect(notification.tag, androidNotificationMap['tag']); - expect(notification.visibility, AndroidNotificationVisibility.secret); - }); - test( - '"AndroidNotification.fromMap" with nullable properties mapped as null & default values invoked', - () { - Map? androidNotificationMap = { - 'channelId': null, - 'clickAction': null, - 'color': null, - 'count': null, - 'imageUrl': null, - 'link': null, - 'priority': null, - 'smallIcon': null, - 'sound': null, - 'ticker': null, - 'tag': null, - 'visibility': null, - }; + '"AndroidNotification.fromMap" with every possible property expected', + () { + Map? androidNotificationMap = { + 'channelId': 'channelId', + 'clickAction': 'clickAction', + 'color': 'color', + 'count': 5, + 'imageUrl': 'imageUrl', + 'link': 'link', + 'priority': 2, + 'smallIcon': 'smallIcon', + 'sound': 'sound', + 'ticker': 'ticker', + 'tag': 'tag', + 'visibility': -1, + }; + + final AndroidNotification notification = AndroidNotification.fromMap( + androidNotificationMap, + ); + + expect(notification.channelId, androidNotificationMap['channelId']); + expect(notification.clickAction, androidNotificationMap['clickAction']); + expect(notification.color, androidNotificationMap['color']); + expect(notification.count, androidNotificationMap['count']); + expect(notification.imageUrl, androidNotificationMap['imageUrl']); + expect(notification.link, androidNotificationMap['link']); + expect( + notification.priority, + AndroidNotificationPriority.maximumPriority, + ); + expect(notification.smallIcon, androidNotificationMap['smallIcon']); + expect(notification.sound, androidNotificationMap['sound']); + expect(notification.ticker, androidNotificationMap['ticker']); + expect(notification.tag, androidNotificationMap['tag']); + expect(notification.visibility, AndroidNotificationVisibility.secret); + }, + ); - final AndroidNotification notification = - AndroidNotification.fromMap(androidNotificationMap); - - const AndroidNotification defaultNotification = AndroidNotification(); - - expect(notification.channelId, defaultNotification.channelId); - expect(notification.clickAction, defaultNotification.clickAction); - expect(notification.color, defaultNotification.color); - expect(notification.count, defaultNotification.count); - expect(notification.imageUrl, defaultNotification.imageUrl); - expect(notification.link, defaultNotification.link); - expect(notification.priority, defaultNotification.priority); - expect(notification.smallIcon, defaultNotification.smallIcon); - expect(notification.sound, defaultNotification.sound); - expect(notification.ticker, defaultNotification.ticker); - expect(notification.tag, defaultNotification.tag); - expect(notification.visibility, defaultNotification.visibility); - }); + test( + '"AndroidNotification.fromMap" with nullable properties mapped as null & default values invoked', + () { + Map? androidNotificationMap = { + 'channelId': null, + 'clickAction': null, + 'color': null, + 'count': null, + 'imageUrl': null, + 'link': null, + 'priority': null, + 'smallIcon': null, + 'sound': null, + 'ticker': null, + 'tag': null, + 'visibility': null, + }; + + final AndroidNotification notification = AndroidNotification.fromMap( + androidNotificationMap, + ); + + const AndroidNotification defaultNotification = AndroidNotification(); + + expect(notification.channelId, defaultNotification.channelId); + expect(notification.clickAction, defaultNotification.clickAction); + expect(notification.color, defaultNotification.color); + expect(notification.count, defaultNotification.count); + expect(notification.imageUrl, defaultNotification.imageUrl); + expect(notification.link, defaultNotification.link); + expect(notification.priority, defaultNotification.priority); + expect(notification.smallIcon, defaultNotification.smallIcon); + expect(notification.sound, defaultNotification.sound); + expect(notification.ticker, defaultNotification.ticker); + expect(notification.tag, defaultNotification.tag); + expect(notification.visibility, defaultNotification.visibility); + }, + ); test( - '"AndroidNotification.fromMap" with no properties & default values invoked', - () { - final AndroidNotification notification = AndroidNotification.fromMap({}); - - const AndroidNotification defaultNotification = AndroidNotification(); - - expect(notification.channelId, defaultNotification.channelId); - expect(notification.clickAction, defaultNotification.clickAction); - expect(notification.color, defaultNotification.color); - expect(notification.count, defaultNotification.count); - expect(notification.imageUrl, defaultNotification.imageUrl); - expect(notification.link, defaultNotification.link); - expect(notification.priority, defaultNotification.priority); - expect(notification.smallIcon, defaultNotification.smallIcon); - expect(notification.sound, defaultNotification.sound); - expect(notification.ticker, defaultNotification.ticker); - expect(notification.tag, defaultNotification.tag); - expect(notification.visibility, defaultNotification.visibility); - }); + '"AndroidNotification.fromMap" with no properties & default values invoked', + () { + final AndroidNotification notification = AndroidNotification.fromMap( + {}, + ); + + const AndroidNotification defaultNotification = AndroidNotification(); + + expect(notification.channelId, defaultNotification.channelId); + expect(notification.clickAction, defaultNotification.clickAction); + expect(notification.color, defaultNotification.color); + expect(notification.count, defaultNotification.count); + expect(notification.imageUrl, defaultNotification.imageUrl); + expect(notification.link, defaultNotification.link); + expect(notification.priority, defaultNotification.priority); + expect(notification.smallIcon, defaultNotification.smallIcon); + expect(notification.sound, defaultNotification.sound); + expect(notification.ticker, defaultNotification.ticker); + expect(notification.tag, defaultNotification.tag); + expect(notification.visibility, defaultNotification.visibility); + }, + ); test('AndroidNotification.toMap returns "AndroidNotification" as Map', () { const AndroidNotification notification = AndroidNotification( @@ -356,25 +375,30 @@ void main() { 'imageUrl': 'imageUrl', 'subtitle': 'subtitle', 'subtitleLocArgs': ['subtitleLocArgs'], - 'subtitleLocKey': 'subtitleLocKey' + 'subtitleLocKey': 'subtitleLocKey', }; AppleNotification notification = AppleNotification( - badge: appleNotificationMap['badge'], - sound: appleNotificationMap['sound'], - imageUrl: appleNotificationMap['imageUrl'], - subtitle: appleNotificationMap['subtitle'], - subtitleLocArgs: appleNotificationMap['subtitleLocArgs'], - subtitleLocKey: appleNotificationMap['subtitleLocKey']); + badge: appleNotificationMap['badge'], + sound: appleNotificationMap['sound'], + imageUrl: appleNotificationMap['imageUrl'], + subtitle: appleNotificationMap['subtitle'], + subtitleLocArgs: appleNotificationMap['subtitleLocArgs'], + subtitleLocKey: appleNotificationMap['subtitleLocKey'], + ); expect(notification.sound, appleNotificationMap['sound']); expect(notification.badge, appleNotificationMap['badge']); expect(notification.imageUrl, appleNotificationMap['imageUrl']); expect(notification.subtitle, appleNotificationMap['subtitle']); - expect(notification.subtitleLocArgs, - appleNotificationMap['subtitleLocArgs']); expect( - notification.subtitleLocKey, appleNotificationMap['subtitleLocKey']); + notification.subtitleLocArgs, + appleNotificationMap['subtitleLocArgs'], + ); + expect( + notification.subtitleLocKey, + appleNotificationMap['subtitleLocKey'], + ); }); test('Provide no arguments', () { @@ -388,67 +412,79 @@ void main() { expect(notification.subtitleLocKey, null); }); - test('"AppleNotification.fromMap" with every possible property expected', - () { - Map appleNotificationMap = { - 'badge': 'badge', - 'sound': {}, - 'imageUrl': 'imageUrl', - 'subtitle': 'subtitle', - 'subtitleLocArgs': ['subtitleLocArgs'], - 'subtitleLocKey': 'subtitleLocKey' - }; - - AppleNotification notification = - AppleNotification.fromMap(appleNotificationMap); - - expect(notification.badge, 'badge'); - expect(notification.sound, isA()); - expect(notification.imageUrl, 'imageUrl'); - expect(notification.subtitle, 'subtitle'); - expect(notification.subtitleLocArgs, ['subtitleLocArgs']); - expect(notification.subtitleLocKey, 'subtitleLocKey'); - }); - test( - '"AppleNotification.fromMap" with nullable properties mapped as null & default values invoked', - () { - Map appleNotificationMap = { - 'badge': null, - 'sound': null, - 'imageUrl': null, - 'subtitle': null, - 'subtitleLocArgs': null, - 'subtitleLocKey': null - }; - - AppleNotification notification = - AppleNotification.fromMap(appleNotificationMap); - - const AppleNotification defaultNotification = AppleNotification(); + '"AppleNotification.fromMap" with every possible property expected', + () { + Map appleNotificationMap = { + 'badge': 'badge', + 'sound': {}, + 'imageUrl': 'imageUrl', + 'subtitle': 'subtitle', + 'subtitleLocArgs': ['subtitleLocArgs'], + 'subtitleLocKey': 'subtitleLocKey', + }; + + AppleNotification notification = AppleNotification.fromMap( + appleNotificationMap, + ); + + expect(notification.badge, 'badge'); + expect(notification.sound, isA()); + expect(notification.imageUrl, 'imageUrl'); + expect(notification.subtitle, 'subtitle'); + expect(notification.subtitleLocArgs, ['subtitleLocArgs']); + expect(notification.subtitleLocKey, 'subtitleLocKey'); + }, + ); - expect(notification.badge, defaultNotification.badge); - expect(notification.sound, defaultNotification.sound); - expect(notification.imageUrl, defaultNotification.imageUrl); - expect(notification.subtitle, defaultNotification.subtitle); - expect(notification.subtitleLocArgs, defaultNotification.subtitleLocArgs); - expect(notification.subtitleLocKey, defaultNotification.subtitleLocKey); - }); + test( + '"AppleNotification.fromMap" with nullable properties mapped as null & default values invoked', + () { + Map appleNotificationMap = { + 'badge': null, + 'sound': null, + 'imageUrl': null, + 'subtitle': null, + 'subtitleLocArgs': null, + 'subtitleLocKey': null, + }; + + AppleNotification notification = AppleNotification.fromMap( + appleNotificationMap, + ); + + const AppleNotification defaultNotification = AppleNotification(); + + expect(notification.badge, defaultNotification.badge); + expect(notification.sound, defaultNotification.sound); + expect(notification.imageUrl, defaultNotification.imageUrl); + expect(notification.subtitle, defaultNotification.subtitle); + expect( + notification.subtitleLocArgs, + defaultNotification.subtitleLocArgs, + ); + expect(notification.subtitleLocKey, defaultNotification.subtitleLocKey); + }, + ); test( - '"AppleNotification.fromMap" with no properties & default values invoked', - () { - AppleNotification notification = AppleNotification.fromMap({}); - - const AppleNotification defaultNotification = AppleNotification(); - - expect(notification.badge, defaultNotification.badge); - expect(notification.sound, defaultNotification.sound); - expect(notification.imageUrl, defaultNotification.imageUrl); - expect(notification.subtitle, defaultNotification.subtitle); - expect(notification.subtitleLocArgs, defaultNotification.subtitleLocArgs); - expect(notification.subtitleLocKey, defaultNotification.subtitleLocKey); - }); + '"AppleNotification.fromMap" with no properties & default values invoked', + () { + AppleNotification notification = AppleNotification.fromMap({}); + + const AppleNotification defaultNotification = AppleNotification(); + + expect(notification.badge, defaultNotification.badge); + expect(notification.sound, defaultNotification.sound); + expect(notification.imageUrl, defaultNotification.imageUrl); + expect(notification.subtitle, defaultNotification.subtitle); + expect( + notification.subtitleLocArgs, + defaultNotification.subtitleLocArgs, + ); + expect(notification.subtitleLocKey, defaultNotification.subtitleLocKey); + }, + ); test('AppleNotification.toMap returns "AppleNotification" as Map', () { const AppleNotificationSound appleSound = AppleNotificationSound( @@ -482,13 +518,14 @@ void main() { Map appleSoundMap = { 'critical': true, 'name': 'name', - 'volume': 0.5 + 'volume': 0.5, }; AppleNotificationSound appleSound = AppleNotificationSound( - critical: appleSoundMap['critical'], - name: appleSoundMap['name'], - volume: appleSoundMap['volume']); + critical: appleSoundMap['critical'], + name: appleSoundMap['name'], + volume: appleSoundMap['volume'], + ); expect(appleSound.critical, appleSoundMap['critical']); expect(appleSound.name, appleSoundMap['name']); expect(appleSound.volume, appleSoundMap['volume']); @@ -503,68 +540,75 @@ void main() { }); test( - '"AppleNotificationSound.fromMap" with every possible property expected', - () { - Map appleSoundMap = { - 'critical': true, - 'name': 'name', - 'volume': 0.57, - }; - - final AppleNotificationSound appleSound = - AppleNotificationSound.fromMap(appleSoundMap); - - expect(appleSound.critical, appleSoundMap['critical']); - expect(appleSound.name, appleSoundMap['name']); - expect(appleSound.volume, appleSoundMap['volume']); - }); + '"AppleNotificationSound.fromMap" with every possible property expected', + () { + Map appleSoundMap = { + 'critical': true, + 'name': 'name', + 'volume': 0.57, + }; + + final AppleNotificationSound appleSound = + AppleNotificationSound.fromMap(appleSoundMap); + + expect(appleSound.critical, appleSoundMap['critical']); + expect(appleSound.name, appleSoundMap['name']); + expect(appleSound.volume, appleSoundMap['volume']); + }, + ); test( - '"AppleNotificationSound.fromMap" with nullable properties mapped as null & default values invoked', - () { - Map webNotificationMap = { - 'critical': null, - 'name': null, - 'volume': null, - }; - - final AppleNotificationSound appleSound = - AppleNotificationSound.fromMap(webNotificationMap); - - const AppleNotificationSound defaultAppleSound = AppleNotificationSound(); - - expect(appleSound.critical, defaultAppleSound.critical); - expect(appleSound.name, defaultAppleSound.name); - expect(appleSound.volume, defaultAppleSound.volume); - }); + '"AppleNotificationSound.fromMap" with nullable properties mapped as null & default values invoked', + () { + Map webNotificationMap = { + 'critical': null, + 'name': null, + 'volume': null, + }; + + final AppleNotificationSound appleSound = + AppleNotificationSound.fromMap(webNotificationMap); + + const AppleNotificationSound defaultAppleSound = + AppleNotificationSound(); + + expect(appleSound.critical, defaultAppleSound.critical); + expect(appleSound.name, defaultAppleSound.name); + expect(appleSound.volume, defaultAppleSound.volume); + }, + ); test( - '"AppleNotificationSound.fromMap" with no properties & default values invoked', - () { - final AppleNotificationSound appleSound = - AppleNotificationSound.fromMap({}); + '"AppleNotificationSound.fromMap" with no properties & default values invoked', + () { + final AppleNotificationSound appleSound = + AppleNotificationSound.fromMap({}); - const AppleNotificationSound defaultAppleSound = AppleNotificationSound(); + const AppleNotificationSound defaultAppleSound = + AppleNotificationSound(); - expect(appleSound.critical, defaultAppleSound.critical); - expect(appleSound.name, defaultAppleSound.name); - expect(appleSound.volume, defaultAppleSound.volume); - }); + expect(appleSound.critical, defaultAppleSound.critical); + expect(appleSound.name, defaultAppleSound.name); + expect(appleSound.volume, defaultAppleSound.volume); + }, + ); - test('AppleNotificationSound.toMap returns "AppleNotificationSound" as Map', - () { - const appleSound = AppleNotificationSound( - critical: true, - name: 'name', - volume: 0.9, - ); - - final Map appleSoundMap = appleSound.toMap(); - - expect(appleSoundMap['critical'], appleSound.critical); - expect(appleSoundMap['name'], appleSound.name); - expect(appleSoundMap['volume'], appleSound.volume); - }); + test( + 'AppleNotificationSound.toMap returns "AppleNotificationSound" as Map', + () { + const appleSound = AppleNotificationSound( + critical: true, + name: 'name', + volume: 0.9, + ); + + final Map appleSoundMap = appleSound.toMap(); + + expect(appleSoundMap['critical'], appleSound.critical); + expect(appleSoundMap['name'], appleSound.name); + expect(appleSoundMap['volume'], appleSound.volume); + }, + ); }); group('WebNotification', () { @@ -601,8 +645,9 @@ void main() { 'link': 'httpLink', }; - final WebNotification notification = - WebNotification.fromMap(webNotificationMap); + final WebNotification notification = WebNotification.fromMap( + webNotificationMap, + ); expect(notification.analyticsLabel, webNotificationMap['analyticsLabel']); expect(notification.image, webNotificationMap['image']); @@ -610,36 +655,43 @@ void main() { }); test( - '"WebNotification.fromMap" with nullable properties mapped as null & default values invoked', - () { - Map? webNotificationMap = { - 'analyticsLabel': null, - 'image': null, - 'link': null, - }; - - final WebNotification notification = - WebNotification.fromMap(webNotificationMap); - - const WebNotification defaultWebNotification = WebNotification(); - - expect( - notification.analyticsLabel, defaultWebNotification.analyticsLabel); - expect(notification.image, defaultWebNotification.image); - expect(notification.link, defaultWebNotification.link); - }); + '"WebNotification.fromMap" with nullable properties mapped as null & default values invoked', + () { + Map? webNotificationMap = { + 'analyticsLabel': null, + 'image': null, + 'link': null, + }; + + final WebNotification notification = WebNotification.fromMap( + webNotificationMap, + ); + + const WebNotification defaultWebNotification = WebNotification(); + + expect( + notification.analyticsLabel, + defaultWebNotification.analyticsLabel, + ); + expect(notification.image, defaultWebNotification.image); + expect(notification.link, defaultWebNotification.link); + }, + ); test( - '"WebNotification.fromMap" with no properties & default values invoked', - () { - final WebNotification notification = WebNotification.fromMap({}); - const WebNotification defaultWebNotification = WebNotification(); - - expect( - notification.analyticsLabel, defaultWebNotification.analyticsLabel); - expect(notification.image, defaultWebNotification.image); - expect(notification.link, defaultWebNotification.link); - }); + '"WebNotification.fromMap" with no properties & default values invoked', + () { + final WebNotification notification = WebNotification.fromMap({}); + const WebNotification defaultWebNotification = WebNotification(); + + expect( + notification.analyticsLabel, + defaultWebNotification.analyticsLabel, + ); + expect(notification.image, defaultWebNotification.image); + expect(notification.link, defaultWebNotification.link); + }, + ); test('WebNotification.toMap returns "WebNotification" as Map', () { const WebNotification notification = WebNotification( diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/test/platform_interface_tests/platform_interface_messaging_test.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/test/platform_interface_tests/platform_interface_messaging_test.dart index 54c959be7eeb..49a1d662aa60 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/test/platform_interface_tests/platform_interface_messaging_test.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/test/platform_interface_tests/platform_interface_messaging_test.dart @@ -31,9 +31,7 @@ void main() { ), ); - firebaseMessagingPlatform = TestFirebaseMessagingPlatform( - app, - ); + firebaseMessagingPlatform = TestFirebaseMessagingPlatform(app); handleMethodCall((call) async { switch (call.method) { @@ -50,28 +48,34 @@ void main() { test('instanceFor', () { final result = FirebaseMessagingPlatform.instanceFor( - app: app, - pluginConstants: { - 'AUTO_INIT_ENABLED': true, - }); + app: app, + pluginConstants: {'AUTO_INIT_ENABLED': true}, + ); expect(result, isA()); expect(result.isAutoInitEnabled, isA()); }); test('get.instance', () { expect( - FirebaseMessagingPlatform.instance, isA()); - expect(FirebaseMessagingPlatform.instance.app.name, - equals(defaultFirebaseAppName)); + FirebaseMessagingPlatform.instance, + isA(), + ); + expect( + FirebaseMessagingPlatform.instance.app.name, + equals(defaultFirebaseAppName), + ); }); group('set.instance', () { test('sets the current instance', () { - FirebaseMessagingPlatform.instance = - TestFirebaseMessagingPlatform(secondaryApp); - - expect(FirebaseMessagingPlatform.instance, - isA()); + FirebaseMessagingPlatform.instance = TestFirebaseMessagingPlatform( + secondaryApp, + ); + + expect( + FirebaseMessagingPlatform.instance, + isA(), + ); expect(FirebaseMessagingPlatform.instance.app.name, equals('testApp2')); }); }); diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/test/remote_message_test.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/test/remote_message_test.dart index b676e3c1ea0a..a855a99a6804 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/test/remote_message_test.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/test/remote_message_test.dart @@ -19,10 +19,7 @@ void main() { 'actionIdentifier': 'actionIdentifier', 'collapseKey': 'collapseKey', 'contentAvailable': true, - 'data': { - 'via': 'FlutterFire Cloud Messaging!!!', - 'count': 1, - }, + 'data': {'via': 'FlutterFire Cloud Messaging!!!', 'count': 1}, 'from': 'from', 'messageId': 'messageId', 'messageType': 'messageType', @@ -33,7 +30,7 @@ void main() { }, 'sentTime': DateTime.now().millisecondsSinceEpoch, 'threadId': 'threadId', - 'ttl': 30000 + 'ttl': 30000, }; mockNullableMessageMap = { @@ -48,7 +45,7 @@ void main() { 'notification': null, 'sentTime': null, 'threadId': null, - 'ttl': null + 'ttl': null, }; }); @@ -82,102 +79,110 @@ void main() { }); test( - '"RemoteMessage.fromMap" with nullable properties mapped as null & default values invoked', - () { - final message = RemoteMessage.fromMap(mockNullableMessageMap); - - expect(message.senderId, mockNullableMessageMap['senderId']); - expect(message.category, mockNullableMessageMap['category']); - expect( - message.actionIdentifier, mockNullableMessageMap['actionIdentifier']); - expect(message.collapseKey, mockNullableMessageMap['collapseKey']); - expect(message.contentAvailable, false); - expect(message.data, {}); - expect(message.from, mockNullableMessageMap['from']); - expect(message.messageId, mockNullableMessageMap['messageId']); - expect(message.messageType, mockNullableMessageMap['messageType']); - expect(message.mutableContent, false); - expect(message.notification, mockNullableMessageMap['notification']); - expect(message.sentTime, null); - expect(message.threadId, mockNullableMessageMap['threadId']); - expect(message.ttl, mockNullableMessageMap['ttl']); - }); - - test('Use RemoteMessage constructor to create every available property', - () { - DateTime date = DateTime.now(); - - final message = RemoteMessage( - senderId: mockMessageMap!['senderId'], - category: mockMessageMap!['category'], - actionIdentifier: mockMessageMap!['actionIdentifier'], - collapseKey: mockMessageMap!['collapseKey'], - contentAvailable: mockMessageMap!['contentAvailable'], - data: mockMessageMap!['data'], - from: mockMessageMap!['from'], - messageId: mockMessageMap!['messageId'], - messageType: mockMessageMap!['messageType'], - mutableContent: mockMessageMap!['mutableContent'], - notification: RemoteNotification.fromMap({}), - sentTime: date, - threadId: mockMessageMap!['threadId'], - ttl: mockMessageMap!['ttl'], - ); - - expect(message.senderId, mockMessageMap!['senderId']); - expect(message.category, mockMessageMap!['category']); - expect(message.actionIdentifier, mockMessageMap!['actionIdentifier']); - expect(message.collapseKey, mockMessageMap!['collapseKey']); - expect(message.contentAvailable, mockMessageMap!['contentAvailable']); - expect(message.data, mockMessageMap!['data']); - expect(message.from, mockMessageMap!['from']); - expect(message.messageId, mockMessageMap!['messageId']); - expect(message.messageType, mockMessageMap!['messageType']); - expect(message.mutableContent, mockMessageMap!['mutableContent']); - - expect(message.notification, isA()); - - expect(message.sentTime, date); - expect(message.threadId, mockMessageMap!['threadId']); - expect(message.ttl, mockMessageMap!['ttl']); - }); + '"RemoteMessage.fromMap" with nullable properties mapped as null & default values invoked', + () { + final message = RemoteMessage.fromMap(mockNullableMessageMap); + + expect(message.senderId, mockNullableMessageMap['senderId']); + expect(message.category, mockNullableMessageMap['category']); + expect( + message.actionIdentifier, + mockNullableMessageMap['actionIdentifier'], + ); + expect(message.collapseKey, mockNullableMessageMap['collapseKey']); + expect(message.contentAvailable, false); + expect(message.data, {}); + expect(message.from, mockNullableMessageMap['from']); + expect(message.messageId, mockNullableMessageMap['messageId']); + expect(message.messageType, mockNullableMessageMap['messageType']); + expect(message.mutableContent, false); + expect(message.notification, mockNullableMessageMap['notification']); + expect(message.sentTime, null); + expect(message.threadId, mockNullableMessageMap['threadId']); + expect(message.ttl, mockNullableMessageMap['ttl']); + }, + ); test( - 'Use RemoteMessage constructor with nullable properties passed as null & default values invoked', - () { - mockNullableMessageMap = { - 'senderId': null, - 'category': null, - 'actionIdentifier': null, - 'collapseKey': null, - 'data': null, - 'from': null, - 'messageId': null, - 'messageType': null, - 'notification': null, - 'sentTime': null, - 'threadId': null, - 'ttl': null - }; + 'Use RemoteMessage constructor to create every available property', + () { + DateTime date = DateTime.now(); + + final message = RemoteMessage( + senderId: mockMessageMap!['senderId'], + category: mockMessageMap!['category'], + actionIdentifier: mockMessageMap!['actionIdentifier'], + collapseKey: mockMessageMap!['collapseKey'], + contentAvailable: mockMessageMap!['contentAvailable'], + data: mockMessageMap!['data'], + from: mockMessageMap!['from'], + messageId: mockMessageMap!['messageId'], + messageType: mockMessageMap!['messageType'], + mutableContent: mockMessageMap!['mutableContent'], + notification: RemoteNotification.fromMap({}), + sentTime: date, + threadId: mockMessageMap!['threadId'], + ttl: mockMessageMap!['ttl'], + ); + + expect(message.senderId, mockMessageMap!['senderId']); + expect(message.category, mockMessageMap!['category']); + expect(message.actionIdentifier, mockMessageMap!['actionIdentifier']); + expect(message.collapseKey, mockMessageMap!['collapseKey']); + expect(message.contentAvailable, mockMessageMap!['contentAvailable']); + expect(message.data, mockMessageMap!['data']); + expect(message.from, mockMessageMap!['from']); + expect(message.messageId, mockMessageMap!['messageId']); + expect(message.messageType, mockMessageMap!['messageType']); + expect(message.mutableContent, mockMessageMap!['mutableContent']); + + expect(message.notification, isA()); + + expect(message.sentTime, date); + expect(message.threadId, mockMessageMap!['threadId']); + expect(message.ttl, mockMessageMap!['ttl']); + }, + ); - RemoteMessage message = const RemoteMessage(); - - expect(message.senderId, mockNullableMessageMap['senderId']); - expect(message.category, mockNullableMessageMap['category']); - expect( - message.actionIdentifier, mockNullableMessageMap['actionIdentifier']); - expect(message.collapseKey, mockNullableMessageMap['collapseKey']); - expect(message.contentAvailable, false); - expect(message.data, {}); - expect(message.from, mockNullableMessageMap['from']); - expect(message.messageId, mockNullableMessageMap['messageId']); - expect(message.messageType, mockNullableMessageMap['messageType']); - expect(message.mutableContent, false); - expect(message.notification, mockNullableMessageMap['notification']); - expect(message.sentTime, null); - expect(message.threadId, mockNullableMessageMap['threadId']); - expect(message.ttl, mockNullableMessageMap['ttl']); - }); + test( + 'Use RemoteMessage constructor with nullable properties passed as null & default values invoked', + () { + mockNullableMessageMap = { + 'senderId': null, + 'category': null, + 'actionIdentifier': null, + 'collapseKey': null, + 'data': null, + 'from': null, + 'messageId': null, + 'messageType': null, + 'notification': null, + 'sentTime': null, + 'threadId': null, + 'ttl': null, + }; + + RemoteMessage message = const RemoteMessage(); + + expect(message.senderId, mockNullableMessageMap['senderId']); + expect(message.category, mockNullableMessageMap['category']); + expect( + message.actionIdentifier, + mockNullableMessageMap['actionIdentifier'], + ); + expect(message.collapseKey, mockNullableMessageMap['collapseKey']); + expect(message.contentAvailable, false); + expect(message.data, {}); + expect(message.from, mockNullableMessageMap['from']); + expect(message.messageId, mockNullableMessageMap['messageId']); + expect(message.messageType, mockNullableMessageMap['messageType']); + expect(message.mutableContent, false); + expect(message.notification, mockNullableMessageMap['notification']); + expect(message.sentTime, null); + expect(message.threadId, mockNullableMessageMap['threadId']); + expect(message.ttl, mockNullableMessageMap['ttl']); + }, + ); test('"RemoteMessage.toMap" returns "RemoteMessage" as Map', () { final RemoteMessage remoteMessage = RemoteMessage( @@ -214,11 +219,12 @@ void main() { expect(map['mutableContent'], remoteMessage.mutableContent); expect( - map['notification'], - RemoteNotification( - title: remoteMessage.notification!.title, - body: remoteMessage.notification!.body, - ).toMap()); + map['notification'], + RemoteNotification( + title: remoteMessage.notification!.title, + body: remoteMessage.notification!.body, + ).toMap(), + ); expect(map['sentTime'], remoteMessage.sentTime!.millisecondsSinceEpoch); expect(map['threadId'], remoteMessage.threadId); diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/test/utils_test.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/test/utils_test.dart index 1677b5056d21..9b09381d1fe2 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/test/utils_test.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/test/utils_test.dart @@ -10,64 +10,91 @@ import 'package:flutter_test/flutter_test.dart'; void main() { group('Utilities', () { group('convertToAndroidNotificationPriority', () { - test('returns correct AndroidNotificationPriority for priority value', - () { - expect(convertToAndroidNotificationPriority(-2), - AndroidNotificationPriority.minimumPriority); - expect(convertToAndroidNotificationPriority(-1), - AndroidNotificationPriority.lowPriority); - expect(convertToAndroidNotificationPriority(0), - AndroidNotificationPriority.defaultPriority); - expect(convertToAndroidNotificationPriority(1), - AndroidNotificationPriority.highPriority); - expect(convertToAndroidNotificationPriority(2), - AndroidNotificationPriority.maximumPriority); - }); - test( - 'returns AndroidNotificationPriority.defaultPriority ' + 'returns correct AndroidNotificationPriority for priority value', + () { + expect( + convertToAndroidNotificationPriority(-2), + AndroidNotificationPriority.minimumPriority, + ); + expect( + convertToAndroidNotificationPriority(-1), + AndroidNotificationPriority.lowPriority, + ); + expect( + convertToAndroidNotificationPriority(0), + AndroidNotificationPriority.defaultPriority, + ); + expect( + convertToAndroidNotificationPriority(1), + AndroidNotificationPriority.highPriority, + ); + expect( + convertToAndroidNotificationPriority(2), + AndroidNotificationPriority.maximumPriority, + ); + }, + ); + + test('returns AndroidNotificationPriority.defaultPriority ' 'if priority is not a possible value', () { - expect(convertToAndroidNotificationPriority(-3), - AndroidNotificationPriority.defaultPriority); - expect(convertToAndroidNotificationPriority(3), - AndroidNotificationPriority.defaultPriority); + expect( + convertToAndroidNotificationPriority(-3), + AndroidNotificationPriority.defaultPriority, + ); + expect( + convertToAndroidNotificationPriority(3), + AndroidNotificationPriority.defaultPriority, + ); }); - test( - 'returns AndroidNotificationPriority.defaultPriority ' + test('returns AndroidNotificationPriority.defaultPriority ' 'if priority is null', () { - expect(convertToAndroidNotificationPriority(null), - AndroidNotificationPriority.defaultPriority); + expect( + convertToAndroidNotificationPriority(null), + AndroidNotificationPriority.defaultPriority, + ); }); }); group('convertAndroidNotificationPriorityToInt', () { - test('returns correct priority value for AndroidNotificationPriority', - () { - expect( + test( + 'returns correct priority value for AndroidNotificationPriority', + () { + expect( convertAndroidNotificationPriorityToInt( - AndroidNotificationPriority.minimumPriority), - -2); - expect( + AndroidNotificationPriority.minimumPriority, + ), + -2, + ); + expect( convertAndroidNotificationPriorityToInt( - AndroidNotificationPriority.lowPriority), - -1); - expect( + AndroidNotificationPriority.lowPriority, + ), + -1, + ); + expect( convertAndroidNotificationPriorityToInt( - AndroidNotificationPriority.defaultPriority), - 0); - expect( + AndroidNotificationPriority.defaultPriority, + ), + 0, + ); + expect( convertAndroidNotificationPriorityToInt( - AndroidNotificationPriority.highPriority), - 1); - expect( + AndroidNotificationPriority.highPriority, + ), + 1, + ); + expect( convertAndroidNotificationPriorityToInt( - AndroidNotificationPriority.maximumPriority), - 2); - }); + AndroidNotificationPriority.maximumPriority, + ), + 2, + ); + }, + ); - test( - 'returns the priority value that represents ' + test('returns the priority value that represents ' 'AndroidNotificationPriority.defaultPriority ' 'if AndroidNotificationPriority is null', () { expect(convertAndroidNotificationPriorityToInt(null), 0); @@ -75,52 +102,71 @@ void main() { }); group('convertToAndroidNotificationVisibility', () { - test('returns correct AndroidNotificationVisibility for visibility value', - () { - expect(convertToAndroidNotificationVisibility(-1), - AndroidNotificationVisibility.secret); - expect(convertToAndroidNotificationVisibility(0), - AndroidNotificationVisibility.private); - expect(convertToAndroidNotificationVisibility(1), - AndroidNotificationVisibility.public); - }); - test( - 'returns AndroidNotificationVisibility.private ' + 'returns correct AndroidNotificationVisibility for visibility value', + () { + expect( + convertToAndroidNotificationVisibility(-1), + AndroidNotificationVisibility.secret, + ); + expect( + convertToAndroidNotificationVisibility(0), + AndroidNotificationVisibility.private, + ); + expect( + convertToAndroidNotificationVisibility(1), + AndroidNotificationVisibility.public, + ); + }, + ); + + test('returns AndroidNotificationVisibility.private ' 'if visibility is no a possible value', () { - expect(convertToAndroidNotificationVisibility(-2), - AndroidNotificationVisibility.private); - expect(convertToAndroidNotificationVisibility(2), - AndroidNotificationVisibility.private); + expect( + convertToAndroidNotificationVisibility(-2), + AndroidNotificationVisibility.private, + ); + expect( + convertToAndroidNotificationVisibility(2), + AndroidNotificationVisibility.private, + ); }); - test( - 'returns AndroidNotificationVisibility.private ' + test('returns AndroidNotificationVisibility.private ' 'if visibility is null', () { - expect(convertToAndroidNotificationVisibility(null), - AndroidNotificationVisibility.private); + expect( + convertToAndroidNotificationVisibility(null), + AndroidNotificationVisibility.private, + ); }); }); group('convertAndroidNotificationVisibilityToInt', () { - test('returns correct visibility value for AndroidNotificationVisibility', - () { - expect( + test( + 'returns correct visibility value for AndroidNotificationVisibility', + () { + expect( convertAndroidNotificationVisibilityToInt( - AndroidNotificationVisibility.secret), - -1); - expect( + AndroidNotificationVisibility.secret, + ), + -1, + ); + expect( convertAndroidNotificationVisibilityToInt( - AndroidNotificationVisibility.private), - 0); - expect( + AndroidNotificationVisibility.private, + ), + 0, + ); + expect( convertAndroidNotificationVisibilityToInt( - AndroidNotificationVisibility.public), - 1); - }); + AndroidNotificationVisibility.public, + ), + 1, + ); + }, + ); - test( - 'returns the visibility value that represents ' + test('returns the visibility value that represents ' 'AndroidNotificationVisibility.private ' 'if AndroidNotificationVisibility is null', () { expect(convertAndroidNotificationVisibilityToInt(null), 0); @@ -129,86 +175,118 @@ void main() { group('convertToAuthorizationStatus()', () { test('returns correct AuthorizationStatus for status value', () { - expect(convertToAuthorizationStatus(-1), - AuthorizationStatus.notDetermined); + expect( + convertToAuthorizationStatus(-1), + AuthorizationStatus.notDetermined, + ); expect(convertToAuthorizationStatus(0), AuthorizationStatus.denied); expect(convertToAuthorizationStatus(1), AuthorizationStatus.authorized); expect( - convertToAuthorizationStatus(2), AuthorizationStatus.provisional); - expect(convertToAuthorizationStatus(3), - AuthorizationStatus.deniedPermanently); + convertToAuthorizationStatus(2), + AuthorizationStatus.provisional, + ); + expect( + convertToAuthorizationStatus(3), + AuthorizationStatus.deniedPermanently, + ); }); - test( - 'returns AuthorizationStatus.notDetermined ' + test('returns AuthorizationStatus.notDetermined ' 'if status is no a possible value', () { - expect(convertToAuthorizationStatus(-2), - AuthorizationStatus.notDetermined); expect( - convertToAuthorizationStatus(4), AuthorizationStatus.notDetermined); + convertToAuthorizationStatus(-2), + AuthorizationStatus.notDetermined, + ); + expect( + convertToAuthorizationStatus(4), + AuthorizationStatus.notDetermined, + ); }); - test( - 'returns AuthorizationStatus.notDetermined ' + test('returns AuthorizationStatus.notDetermined ' 'if status is null', () { - expect(convertToAuthorizationStatus(null), - AuthorizationStatus.notDetermined); + expect( + convertToAuthorizationStatus(null), + AuthorizationStatus.notDetermined, + ); }); }); group('convertToAppleNotificationSetting', () { test('returns correct AppleNotificationSetting for status value', () { - expect(convertToAppleNotificationSetting(-1), - AppleNotificationSetting.notSupported); - expect(convertToAppleNotificationSetting(0), - AppleNotificationSetting.disabled); - expect(convertToAppleNotificationSetting(1), - AppleNotificationSetting.enabled); + expect( + convertToAppleNotificationSetting(-1), + AppleNotificationSetting.notSupported, + ); + expect( + convertToAppleNotificationSetting(0), + AppleNotificationSetting.disabled, + ); + expect( + convertToAppleNotificationSetting(1), + AppleNotificationSetting.enabled, + ); }); - test( - 'returns AppleNotificationSetting.notSupported ' + test('returns AppleNotificationSetting.notSupported ' 'if status is no a possible value', () { - expect(convertToAppleNotificationSetting(-2), - AppleNotificationSetting.notSupported); - expect(convertToAppleNotificationSetting(2), - AppleNotificationSetting.notSupported); + expect( + convertToAppleNotificationSetting(-2), + AppleNotificationSetting.notSupported, + ); + expect( + convertToAppleNotificationSetting(2), + AppleNotificationSetting.notSupported, + ); }); - test( - 'returns AppleNotificationSetting.notSupported ' + test('returns AppleNotificationSetting.notSupported ' 'if status is null', () { - expect(convertToAppleNotificationSetting(null), - AppleNotificationSetting.notSupported); + expect( + convertToAppleNotificationSetting(null), + AppleNotificationSetting.notSupported, + ); }); }); group('convertToAppleShowPreviewSetting', () { test('returns correct AppleShowPreviewSetting for status value', () { - expect(convertToAppleShowPreviewSetting(-1), - AppleShowPreviewSetting.notSupported); - expect( - convertToAppleShowPreviewSetting(0), AppleShowPreviewSetting.never); - expect(convertToAppleShowPreviewSetting(1), - AppleShowPreviewSetting.always); - expect(convertToAppleShowPreviewSetting(2), - AppleShowPreviewSetting.whenAuthenticated); + expect( + convertToAppleShowPreviewSetting(-1), + AppleShowPreviewSetting.notSupported, + ); + expect( + convertToAppleShowPreviewSetting(0), + AppleShowPreviewSetting.never, + ); + expect( + convertToAppleShowPreviewSetting(1), + AppleShowPreviewSetting.always, + ); + expect( + convertToAppleShowPreviewSetting(2), + AppleShowPreviewSetting.whenAuthenticated, + ); }); - test( - 'returns AppleShowPreviewSetting.notSupported ' + test('returns AppleShowPreviewSetting.notSupported ' 'if status is no a possible value', () { - expect(convertToAppleShowPreviewSetting(-2), - AppleShowPreviewSetting.notSupported); - expect(convertToAppleShowPreviewSetting(3), - AppleShowPreviewSetting.notSupported); + expect( + convertToAppleShowPreviewSetting(-2), + AppleShowPreviewSetting.notSupported, + ); + expect( + convertToAppleShowPreviewSetting(3), + AppleShowPreviewSetting.notSupported, + ); }); - test( - 'returns AppleShowPreviewSetting.notSupported ' + test('returns AppleShowPreviewSetting.notSupported ' 'if status is null', () { - expect(convertToAppleShowPreviewSetting(null), - AppleShowPreviewSetting.notSupported); + expect( + convertToAppleShowPreviewSetting(null), + AppleShowPreviewSetting.notSupported, + ); }); }); }); diff --git a/packages/firebase_messaging/firebase_messaging_web/lib/firebase_messaging_web.dart b/packages/firebase_messaging/firebase_messaging_web/lib/firebase_messaging_web.dart index 7825b227fa1c..d3640e90ba15 100644 --- a/packages/firebase_messaging/firebase_messaging_web/lib/firebase_messaging_web.dart +++ b/packages/firebase_messaging/firebase_messaging_web/lib/firebase_messaging_web.dart @@ -29,14 +29,17 @@ class FirebaseMessagingWeb extends FirebaseMessagingPlatform { messaging_interop.Messaging? _webMessaging; messaging_interop.Messaging get _delegate { - _webMessaging ??= - messaging_interop.getMessagingInstance(core_interop.app(app.name)); + _webMessaging ??= messaging_interop.getMessagingInstance( + core_interop.app(app.name), + ); if (!_initialized) { - _webMessaging!.onMessage - .listen((messaging_interop.MessagePayload webMessagePayload) { - RemoteMessage remoteMessage = - RemoteMessage.fromMap(utils.messagePayloadToMap(webMessagePayload)); + _webMessaging!.onMessage.listen(( + messaging_interop.MessagePayload webMessagePayload, + ) { + RemoteMessage remoteMessage = RemoteMessage.fromMap( + utils.messagePayloadToMap(webMessagePayload), + ); FirebaseMessagingPlatform.onMessage.add(remoteMessage); }); @@ -112,8 +115,10 @@ class FirebaseMessagingWeb extends FirebaseMessagingPlatform { } @override - Future getToken( - {String? vapidKey, String? serviceWorkerScriptPath}) async { + Future getToken({ + String? vapidKey, + String? serviceWorkerScriptPath, + }) async { _delegate; if (!_initialized) { @@ -123,7 +128,9 @@ class FirebaseMessagingWeb extends FirebaseMessagingPlatform { return convertWebExceptions( () => _delegate.getToken( - vapidKey: vapidKey, serviceWorkerScriptPath: serviceWorkerScriptPath), + vapidKey: vapidKey, + serviceWorkerScriptPath: serviceWorkerScriptPath, + ), ); } diff --git a/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging.dart b/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging.dart index 265724c2c288..ded1099a2260 100644 --- a/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging.dart +++ b/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging.dart @@ -16,9 +16,11 @@ export 'messaging_interop.dart'; /// Given an AppJSImp, return the Messaging instance. Messaging getMessagingInstance([App? app]) { - return Messaging.getInstance(app != null - ? messaging_interop.getMessaging(app.jsObject) - : messaging_interop.getMessaging()); + return Messaging.getInstance( + app != null + ? messaging_interop.getMessaging(app.jsObject) + : messaging_interop.getMessaging(), + ); } class Messaging extends JsObjectWrapper { @@ -35,7 +37,7 @@ class Messaging extends JsObjectWrapper { messaging_interop.isSupported().toDart.then((value) => value.toDart); Messaging._fromJsObject(messaging_interop.MessagingJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); /// To forcibly stop a registration token from being used, delete it by calling this method. /// Calling this method will stop the periodic data transmission to the FCM backend. @@ -43,8 +45,10 @@ class Messaging extends JsObjectWrapper { /// After calling [requestPermission] you can call this method to get an FCM registration token /// that can be used to send push messages to this user. - Future getToken( - {String? vapidKey, String? serviceWorkerScriptPath}) async { + Future getToken({ + String? vapidKey, + String? serviceWorkerScriptPath, + }) async { try { web.ServiceWorkerRegistration? serviceWorkerRegistration; if (serviceWorkerScriptPath != null) { @@ -52,17 +56,20 @@ class Messaging extends JsObjectWrapper { .register(serviceWorkerScriptPath.toJS) .toDart; } - final token = (await messaging_interop - .getToken( - jsObject, - vapidKey == null && serviceWorkerRegistration == null - ? null - : messaging_interop.GetTokenOptions( - vapidKey: vapidKey?.toJS, - serviceWorkerRegistration: serviceWorkerRegistration, - )) - .toDart) - .toDart; + final token = + (await messaging_interop + .getToken( + jsObject, + vapidKey == null && serviceWorkerRegistration == null + ? null + : messaging_interop.GetTokenOptions( + vapidKey: vapidKey?.toJS, + serviceWorkerRegistration: + serviceWorkerRegistration, + ), + ) + .toDart) + .toDart; return token; } catch (err) { // A race condition can happen in which the service worker get registered @@ -89,22 +96,29 @@ class Messaging extends JsObjectWrapper { _createOnMessageStream(_onMessageController); Stream _createOnMessageStream( - StreamController? controller) { + StreamController? controller, + ) { StreamController? _controller = controller; if (_controller == null) { _controller = StreamController.broadcast(sync: true); final nextWrapper = (JSAny payload) { - _controller!.add(MessagePayload._fromJsObject( - payload as messaging_interop.MessagePayloadJsImpl)); + _controller!.add( + MessagePayload._fromJsObject( + payload as messaging_interop.MessagePayloadJsImpl, + ), + ); }; final errorWrapper = (JSError e) { _controller!.addError(e); }; messaging_interop.onMessage( - jsObject, - messaging_interop.Observer( - next: nextWrapper.toJS, error: errorWrapper.toJS)); + jsObject, + messaging_interop.Observer( + next: nextWrapper.toJS, + error: errorWrapper.toJS, + ), + ); } return _controller.stream; } @@ -113,8 +127,8 @@ class Messaging extends JsObjectWrapper { class NotificationPayload extends JsObjectWrapper { NotificationPayload._fromJsObject( - messaging_interop.NotificationPayloadJsImpl jsObject) - : super.fromJsObject(jsObject); + messaging_interop.NotificationPayloadJsImpl jsObject, + ) : super.fromJsObject(jsObject); String? get title => jsObject.title?.toDart; String? get body => jsObject.body?.toDart; @@ -124,7 +138,7 @@ class NotificationPayload class MessagePayload extends JsObjectWrapper { MessagePayload._fromJsObject(messaging_interop.MessagePayloadJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); String get messageId => jsObject.messageId.toDart; String? get collapseKey => jsObject.collapseKey?.toDart; @@ -142,7 +156,7 @@ class MessagePayload class FcmOptions extends JsObjectWrapper { FcmOptions._fromJsObject(messaging_interop.FcmOptionsJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); String? get analyticsLabel => jsObject.analyticsLabel?.toDart; String? get link => jsObject.link?.toDart; diff --git a/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging_interop.dart b/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging_interop.dart index 9603e421c961..96d83af0afa7 100644 --- a/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging_interop.dart +++ b/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging_interop.dart @@ -24,7 +24,9 @@ external JSPromise deleteToken(MessagingJsImpl messaging); @JS() @staticInterop external JSPromise getToken( - MessagingJsImpl messaging, GetTokenOptions? getTokenOptions); + MessagingJsImpl messaging, + GetTokenOptions? getTokenOptions, +); @JS('isSupported') @staticInterop @@ -32,10 +34,7 @@ external JSPromise isSupported(); @JS() @staticInterop -external JSFunction onMessage( - MessagingJsImpl messaging, - Observer observer, -); +external JSFunction onMessage(MessagingJsImpl messaging, Observer observer); extension type MessagingJsImpl._(JSObject _) implements JSObject {} diff --git a/packages/firebase_messaging/firebase_messaging_web/lib/src/utils.dart b/packages/firebase_messaging/firebase_messaging_web/lib/src/utils.dart index 80cc6aee8102..1d61a2205fe3 100644 --- a/packages/firebase_messaging/firebase_messaging_web/lib/src/utils.dart +++ b/packages/firebase_messaging/firebase_messaging_web/lib/src/utils.dart @@ -80,7 +80,9 @@ Map messagePayloadToMap(MessagePayload messagePayload) { 'notification': messagePayload.notification == null ? null : notificationPayloadToMap( - messagePayload.notification!, messagePayload.fcmOptions), + messagePayload.notification!, + messagePayload.fcmOptions, + ), 'sentTime': sentTime, 'threadId': null, 'ttl': null, @@ -92,7 +94,9 @@ Map messagePayloadToMap(MessagePayload messagePayload) { /// Since [FcmOptions] are web specific, we pass these down to the upper layer /// as web properties. Map notificationPayloadToMap( - NotificationPayload notificationPayload, FcmOptions? fcmOptions) { + NotificationPayload notificationPayload, + FcmOptions? fcmOptions, +) { return { 'title': notificationPayload.title, 'body': notificationPayload.body, diff --git a/packages/firebase_messaging/firebase_messaging_web/pubspec.yaml b/packages/firebase_messaging/firebase_messaging_web/pubspec.yaml index 43c34d884b40..c566551f7b82 100644 --- a/packages/firebase_messaging/firebase_messaging_web/pubspec.yaml +++ b/packages/firebase_messaging/firebase_messaging_web/pubspec.yaml @@ -6,8 +6,8 @@ version: 4.2.5 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.22.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_messaging/firebase_messaging_web/test/firebase_messaging_web_test.dart b/packages/firebase_messaging/firebase_messaging_web/test/firebase_messaging_web_test.dart index 86929a6c74c6..cda4ee180904 100644 --- a/packages/firebase_messaging/firebase_messaging_web/test/firebase_messaging_web_test.dart +++ b/packages/firebase_messaging/firebase_messaging_web/test/firebase_messaging_web_test.dart @@ -4,7 +4,6 @@ // BSD-style license that can be found in the LICENSE file. @TestOn('chrome') - import 'package:firebase_messaging_platform_interface/firebase_messaging_platform_interface.dart'; import 'package:firebase_messaging_web/src/utils.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -12,13 +11,16 @@ import 'package:flutter_test/flutter_test.dart'; void main() { group('firebase_messaging_web utils', () { test('convertToAuthorizationStatus()', () { - AuthorizationStatus grantedStatus = - convertToAuthorizationStatus('granted'); + AuthorizationStatus grantedStatus = convertToAuthorizationStatus( + 'granted', + ); AuthorizationStatus deniedStatus = convertToAuthorizationStatus('denied'); - AuthorizationStatus defaultStatus = - convertToAuthorizationStatus('default'); - AuthorizationStatus anyOtherStatus = - convertToAuthorizationStatus('random string'); + AuthorizationStatus defaultStatus = convertToAuthorizationStatus( + 'default', + ); + AuthorizationStatus anyOtherStatus = convertToAuthorizationStatus( + 'random string', + ); expect(grantedStatus, AuthorizationStatus.authorized); expect(deniedStatus, AuthorizationStatus.denied); @@ -44,12 +46,15 @@ void main() { expect(notification.showPreviews, AppleShowPreviewSetting.notSupported); expect(notification.sound, AppleNotificationSetting.notSupported); - NotificationSettings deniedNotification = - getNotificationSettings('denied'); - NotificationSettings defaultNotification = - getNotificationSettings('default'); - NotificationSettings randomNotification = - getNotificationSettings('random string'); + NotificationSettings deniedNotification = getNotificationSettings( + 'denied', + ); + NotificationSettings defaultNotification = getNotificationSettings( + 'default', + ); + NotificationSettings randomNotification = getNotificationSettings( + 'random string', + ); expect( deniedNotification.authorizationStatus, diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/integration_test/report_test_results.dart b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/integration_test/report_test_results.dart index fb80e3ba19f7..db17f5dab066 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/integration_test/report_test_results.dart +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/integration_test/report_test_results.dart @@ -26,8 +26,9 @@ void reportTestResultsToDriver(IntegrationTestWidgetsFlutterBinding binding) { for (final entry in binding.results.entries) if (entry.value is Failure) entry.key, ]; - bool didFail(String name) => failures - .any((failure) => name == failure || name.endsWith(' $failure')); + bool didFail(String name) => failures.any( + (failure) => name == failure || name.endsWith(' $failure'), + ); binding.reportData ??= {}; binding.reportData!['testResults'] = { diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/lib/firebase_options.dart b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/lib/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/lib/firebase_options.dart +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/lib/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/lib/main.dart b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/lib/main.dart index 125686f931fb..892213ab822d 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/lib/main.dart +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/lib/main.dart @@ -15,9 +15,7 @@ const kModelName = "mobilenet_v1_1_0_224"; void main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); + await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); runApp(const MyApp()); } @@ -40,7 +38,9 @@ class _MyAppState extends State { /// Initially get the lcoal model if found, and asynchronously get the latest one in background. Future initWithLocalModel() async { final newModel = await FirebaseModelDownloader.instance.getModel( - kModelName, FirebaseModelDownloadType.localModelUpdateInBackground); + kModelName, + FirebaseModelDownloadType.localModelUpdateInBackground, + ); setState(() { model = newModel; @@ -52,9 +52,7 @@ class _MyAppState extends State { return MaterialApp( theme: ThemeData(primarySwatch: Colors.amber), home: Scaffold( - appBar: AppBar( - title: const Text('Plugin example app'), - ), + appBar: AppBar(title: const Text('Plugin example app')), body: Padding( padding: const EdgeInsets.all(20.0), child: Center( @@ -85,10 +83,12 @@ class _MyAppState extends State { Expanded( child: ElevatedButton( onPressed: () async { - final newModel = - await FirebaseModelDownloader.instance.getModel( - kModelName, - FirebaseModelDownloadType.latestModel); + final newModel = await FirebaseModelDownloader + .instance + .getModel( + kModelName, + FirebaseModelDownloadType.latestModel, + ); setState(() { model = newModel; diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/pubspec.yaml b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/pubspec.yaml index 50f1433dc6f6..0c8c70bbb6ad 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/pubspec.yaml +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/pubspec.yaml @@ -5,8 +5,8 @@ resolution: workspace publish_to: 'none' environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: flutter: diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/test_driver/integration_test.dart b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/test_driver/integration_test.dart index 691723cbbfe1..9ccbcc26ab97 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/test_driver/integration_test.dart +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/example/test_driver/integration_test.dart @@ -7,28 +7,32 @@ import 'dart:io'; import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver( - writeResponseOnFailure: true, - responseDataCallback: (Map? data) async { - final results = - (data?['testResults'] as Map?)?.cast() ?? - const {}; - var passed = 0; - var failed = 0; - for (final entry in results.entries) { - final ok = entry.value == 'success'; - ok ? passed++ : failed++; - // ignore: avoid_print - print('${ok ? '✅' : '❌'} ${entry.key}'); - } - // ignore: avoid_print - print('Web e2e summary: $passed passed, $failed failed, ' - '${results.length} total'); - if (results.isEmpty) { - // ignore: avoid_print - print('[E] No tests reported by the app - treating as ' - 'infrastructure failure.'); - exit(1); - } - await writeResponseData(data); - }, + writeResponseOnFailure: true, + responseDataCallback: (Map? data) async { + final results = + (data?['testResults'] as Map?)?.cast() ?? + const {}; + var passed = 0; + var failed = 0; + for (final entry in results.entries) { + final ok = entry.value == 'success'; + ok ? passed++ : failed++; + // ignore: avoid_print + print('${ok ? '✅' : '❌'} ${entry.key}'); + } + // ignore: avoid_print + print( + 'Web e2e summary: $passed passed, $failed failed, ' + '${results.length} total', ); + if (results.isEmpty) { + // ignore: avoid_print + print( + '[E] No tests reported by the app - treating as ' + 'infrastructure failure.', + ); + exit(1); + } + await writeResponseData(data); + }, +); diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/lib/src/firebase_ml_model_downloader.dart b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/lib/src/firebase_ml_model_downloader.dart index ece49d7fbdda..04d92557bb04 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/lib/src/firebase_ml_model_downloader.dart +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/lib/src/firebase_ml_model_downloader.dart @@ -16,7 +16,7 @@ class FirebaseModelDownloader extends FirebasePlugin { 'for Firebase. See https://firebase.google.com/docs/ml/migrate-to-cloud-storage.', ) FirebaseModelDownloader._({required this.app}) - : super(app.name, 'plugins.flutter.io/firebase_ml_model_downloader'); + : super(app.name, 'plugins.flutter.io/firebase_ml_model_downloader'); // Cached and lazily loaded instance of [FirebaseModelDownloaderPlatform] to avoid // creating a [MethodChannelFirebaseFunctions] when not needed or creating an @@ -38,9 +38,7 @@ class FirebaseModelDownloader extends FirebasePlugin { /// Returns an instance using the default [FirebaseApp]. static FirebaseModelDownloader get instance { - return FirebaseModelDownloader.instanceFor( - app: Firebase.app(), - ); + return FirebaseModelDownloader.instanceFor(app: Firebase.app()); } /// Returns an instance using a specified [FirebaseApp]. diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/pubspec.yaml b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/pubspec.yaml index 0a010a345b7f..ecbc2204cee4 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/pubspec.yaml +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/pubspec.yaml @@ -14,8 +14,8 @@ false_secrets: - example/** environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core: ^4.14.0 diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/test/firebase_ml_model_downloader_test.dart b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/test/firebase_ml_model_downloader_test.dart index fcdb5476bea3..15b4791dc2a9 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/test/firebase_ml_model_downloader_test.dart +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/test/firebase_ml_model_downloader_test.dart @@ -55,14 +55,16 @@ void main() { group('instanceFor', () { test('returns an instance', () async { - final mlModelDownloader = - FirebaseModelDownloader.instanceFor(app: secondaryApp); + final mlModelDownloader = FirebaseModelDownloader.instanceFor( + app: secondaryApp, + ); expect(mlModelDownloader, isA()); }); test('returns the correct $FirebaseApp', () { - final mlModelDownloader = - FirebaseModelDownloader.instanceFor(app: secondaryApp); + final mlModelDownloader = FirebaseModelDownloader.instanceFor( + app: secondaryApp, + ); expect(mlModelDownloader.app, isA()); expect(mlModelDownloader.app.name, 'secondaryApp'); }); @@ -113,8 +115,9 @@ void main() { size: 123, ), ]; - when(kMockDownloaderPlatform.listDownloadedModels()) - .thenAnswer((_) => Future.value(customModels)); + when( + kMockDownloaderPlatform.listDownloadedModels(), + ).thenAnswer((_) => Future.value(customModels)); final modelList = await mlModelDownloader.listDownloadedModels(); @@ -126,8 +129,9 @@ void main() { group('deleteDownloadedModel', () { test('verify delegate method is called', () async { const String modelName = 'modelName'; - when(kMockDownloaderPlatform.deleteDownloadedModel(modelName)) - .thenAnswer((_) => Future.value()); + when( + kMockDownloaderPlatform.deleteDownloadedModel(modelName), + ).thenAnswer((_) => Future.value()); await mlModelDownloader.deleteDownloadedModel(modelName); diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/lib/src/method_channel/method_channel_firebase_ml_model_downloader.dart b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/lib/src/method_channel/method_channel_firebase_ml_model_downloader.dart index 3251b38b2e03..213501d6902c 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/lib/src/method_channel/method_channel_firebase_ml_model_downloader.dart +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/lib/src/method_channel/method_channel_firebase_ml_model_downloader.dart @@ -31,7 +31,7 @@ class MethodChannelFirebaseModelDownloader /// Creates a new instance with a given [FirebaseApp]. MethodChannelFirebaseModelDownloader({required FirebaseApp app}) - : super(appInstance: app); + : super(appInstance: app); /// Gets a [FirebaseModelDownloaderPlatform] with specific arguments such as a different /// [FirebaseApp]. @@ -48,12 +48,14 @@ class MethodChannelFirebaseModelDownloader ) async { try { final result = await channel.invokeMapMethod( - 'FirebaseModelDownloader#getModel', { - 'appName': app.name, - 'modelName': modelName, - 'downloadType': _downloadTypeToString(downloadType), - 'conditions': conditions.toMap(), - }); + 'FirebaseModelDownloader#getModel', + { + 'appName': app.name, + 'modelName': modelName, + 'downloadType': _downloadTypeToString(downloadType), + 'conditions': conditions.toMap(), + }, + ); return _resultToFirebaseCustomModel(result!); } catch (e, s) { @@ -65,9 +67,9 @@ class MethodChannelFirebaseModelDownloader Future> listDownloadedModels() async { try { final result = await channel.invokeListMethod( - 'FirebaseModelDownloader#listDownloadedModels', { - 'appName': app.name, - }); + 'FirebaseModelDownloader#listDownloadedModels', + {'appName': app.name}, + ); return result!.map(_resultToFirebaseCustomModel).toList(growable: false); } catch (e, s) { @@ -78,19 +80,16 @@ class MethodChannelFirebaseModelDownloader @override Future deleteDownloadedModel(String modelName) async { try { - await channel - .invokeMethod('FirebaseModelDownloader#deleteDownloadedModel', { - 'appName': app.name, - 'modelName': modelName, - }); + await channel.invokeMethod( + 'FirebaseModelDownloader#deleteDownloadedModel', + {'appName': app.name, 'modelName': modelName}, + ); } catch (e, s) { convertPlatformException(e, s); } } - FirebaseCustomModel _resultToFirebaseCustomModel( - Map result, - ) { + FirebaseCustomModel _resultToFirebaseCustomModel(Map result) { return FirebaseCustomModel( file: File(result['filePath']), size: result['size'], diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/lib/src/method_channel/utils/exception.dart index 78cfb28a18e1..0f3333e943c0 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/lib/src/method_channel/utils/exception.dart @@ -10,10 +10,7 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and returns an [Exception]. /// /// If the [Exception] is a [PlatformException], a [FirebaseException] is returned. -Never convertPlatformException( - dynamic exception, - StackTrace stackTrace, -) { +Never convertPlatformException(dynamic exception, StackTrace stackTrace) { if (exception is! Exception || exception is! PlatformException) { Error.throwWithStackTrace(exception, stackTrace); } diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/pubspec.yaml b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/pubspec.yaml index f5c367044112..9cdcff9e55f9 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/pubspec.yaml +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/pubspec.yaml @@ -6,8 +6,8 @@ homepage: https://github.com/firebase/flutterfire/tree/main/packages/firebase_ml repository: https://github.com/firebase/flutterfire/tree/main/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core: ^4.14.0 diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/test/method_channel_tests/method_channel_firebase_ml_model_downloader_test.dart b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/test/method_channel_tests/method_channel_firebase_ml_model_downloader_test.dart index 76b2548dd6ca..7f831a760295 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/test/method_channel_tests/method_channel_firebase_ml_model_downloader_test.dart +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/test/method_channel_tests/method_channel_firebase_ml_model_downloader_test.dart @@ -85,8 +85,9 @@ void main() { group('delegateFor', () { test('returns correct class instance', () { - final testMlDownloader = - TestMethodChannelFirebaseModelDownloader(Firebase.app()); + final testMlDownloader = TestMethodChannelFirebaseModelDownloader( + Firebase.app(), + ); final result = testMlDownloader.delegateFor(app: Firebase.app()); expect(result, isA()); @@ -118,19 +119,20 @@ void main() { }); test( - 'catch a [PlatformException] error and throws a [FirebaseException] error', - () async { - mockPlatformExceptionThrown = true; - - await testExceptionHandling( - 'PLATFORM', - () => mlDownloader.getModel( - kModelName, - FirebaseModelDownloadType.latestModel, - FirebaseModelDownloadConditions(), - ), - ); - }); + 'catch a [PlatformException] error and throws a [FirebaseException] error', + () async { + mockPlatformExceptionThrown = true; + + await testExceptionHandling( + 'PLATFORM', + () => mlDownloader.getModel( + kModelName, + FirebaseModelDownloadType.latestModel, + FirebaseModelDownloadConditions(), + ), + ); + }, + ); }); group('listDownloadedModels', () { @@ -142,23 +144,22 @@ void main() { expect(log, [ isMethodCall( 'FirebaseModelDownloader#listDownloadedModels', - arguments: { - 'appName': app.name, - }, + arguments: {'appName': app.name}, ), ]); }); test( - 'catch a [PlatformException] error and throws a [FirebaseException] error', - () async { - mockPlatformExceptionThrown = true; - - await testExceptionHandling( - 'PLATFORM', - () => mlDownloader.listDownloadedModels(), - ); - }); + 'catch a [PlatformException] error and throws a [FirebaseException] error', + () async { + mockPlatformExceptionThrown = true; + + await testExceptionHandling( + 'PLATFORM', + () => mlDownloader.listDownloadedModels(), + ); + }, + ); }); group('deleteDownloadedModel', () { @@ -178,15 +179,16 @@ void main() { }); test( - 'catch a [PlatformException] error and throws a [FirebaseException] error', - () async { - mockPlatformExceptionThrown = true; - - await testExceptionHandling( - 'PLATFORM', - () => mlDownloader.deleteDownloadedModel(kModelName), - ); - }); + 'catch a [PlatformException] error and throws a [FirebaseException] error', + () async { + mockPlatformExceptionThrown = true; + + await testExceptionHandling( + 'PLATFORM', + () => mlDownloader.deleteDownloadedModel(kModelName), + ); + }, + ); }); }); } diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/test/mock.dart b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/test/mock.dart index 655358e4cdf4..0b8880fcdc70 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/test/mock.dart +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/test/mock.dart @@ -18,10 +18,12 @@ void setupFirebaseModelDownloaderMocks([Callback? customHandlers]) { void handleMethodCall(MethodCallCallback methodCallCallback) => TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(MethodChannelFirebaseModelDownloader.channel, - (call) async { - return await methodCallCallback(call); - }); + .setMockMethodCallHandler( + MethodChannelFirebaseModelDownloader.channel, + (call) async { + return await methodCallCallback(call); + }, + ); Future testExceptionHandling(String type, Function testMethod) async { try { diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/test/platform_interface_tests/platform_interface_firebase_ml_model_downloader_test.dart b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/test/platform_interface_tests/platform_interface_firebase_ml_model_downloader_test.dart index 6266ce2c34b3..06ab65c64aa4 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/test/platform_interface_tests/platform_interface_firebase_ml_model_downloader_test.dart +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/test/platform_interface_tests/platform_interface_firebase_ml_model_downloader_test.dart @@ -51,9 +51,7 @@ void main() { }); test('instanceFor', () { - final result = FirebaseModelDownloaderPlatform.instanceFor( - app: app, - ); + final result = FirebaseModelDownloaderPlatform.instanceFor(app: app); expect(result, isA()); }); @@ -146,7 +144,7 @@ void main() { class TestFirebaseModelDownloaderPlatform extends FirebaseModelDownloaderPlatform { TestFirebaseModelDownloaderPlatform(FirebaseApp? app) - : super(appInstance: app); + : super(appInstance: app); FirebaseModelDownloaderPlatform testDelegateFor({FirebaseApp? app}) { return delegateFor(app: app ?? Firebase.app()); diff --git a/packages/firebase_performance/firebase_performance/example/integration_test/e2e_test.dart b/packages/firebase_performance/firebase_performance/example/integration_test/e2e_test.dart index 101cfc47ae31..67b4c3499e36 100644 --- a/packages/firebase_performance/firebase_performance/example/integration_test/e2e_test.dart +++ b/packages/firebase_performance/firebase_performance/example/integration_test/e2e_test.dart @@ -33,246 +33,224 @@ void main() { } }); - group( - '$FirebasePerformance.instance', - () { - test( - 'isPerformanceCollectionEnabled', - () async { - FirebasePerformance performance = FirebasePerformance.instance; - - expect( - performance.isPerformanceCollectionEnabled(), - completion(isTrue), - ); - }, - // Works locally but fails on CI - skip: defaultTargetPlatform == TargetPlatform.android || - defaultTargetPlatform == TargetPlatform.macOS, - ); - test('setPerformanceCollectionEnabled', () async { + group('$FirebasePerformance.instance', () { + test( + 'isPerformanceCollectionEnabled', + () async { FirebasePerformance performance = FirebasePerformance.instance; - await performance.setPerformanceCollectionEnabled(false); expect( performance.isPerformanceCollectionEnabled(), - completion(isFalse), + completion(isTrue), ); - }); - }, - skip: kIsWeb || defaultTargetPlatform == TargetPlatform.macOS, - ); - - group( - '$Trace', - () { - late FirebasePerformance performance; - late Trace testTrace; - const String metricName = 'test-metric'; - - setUpAll(() async { - performance = FirebasePerformance.instance; - }); - - setUp(() async { - await performance.setPerformanceCollectionEnabled(true); - testTrace = performance.newTrace('test-trace'); + }, + // Works locally but fails on CI + skip: + defaultTargetPlatform == TargetPlatform.android || + defaultTargetPlatform == TargetPlatform.macOS, + ); + test('setPerformanceCollectionEnabled', () async { + FirebasePerformance performance = FirebasePerformance.instance; + + await performance.setPerformanceCollectionEnabled(false); + expect(performance.isPerformanceCollectionEnabled(), completion(isFalse)); + }); + }, skip: kIsWeb || defaultTargetPlatform == TargetPlatform.macOS); + + group('$Trace', () { + late FirebasePerformance performance; + late Trace testTrace; + const String metricName = 'test-metric'; + + setUpAll(() async { + performance = FirebasePerformance.instance; + }); + + setUp(() async { + await performance.setPerformanceCollectionEnabled(true); + testTrace = performance.newTrace('test-trace'); + }); + + test('start & stop trace', () async { + await testTrace.start(); + await testTrace.stop(); + }); + + test('starting trace with performance collection disabled', () async { + await performance.setPerformanceCollectionEnabled(false); + await testTrace.start(); + await testTrace.stop(); + }); + + test("starting Trace twice shouldn't throw an error", () async { + await testTrace.start(); + await testTrace.start(); + }); + + test("stopping Trace twice shouldn't throw an error", () async { + await testTrace.start(); + await testTrace.stop(); + await testTrace.stop(); + }); + + test('incrementMetric works correctly', () { + testTrace.incrementMetric(metricName, 14); + expect(testTrace.getMetric(metricName), 14); + + testTrace.incrementMetric(metricName, 45); + expect(testTrace.getMetric(metricName), 59); + }); + + test('setMetric works correctly', () async { + testTrace.setMetric(metricName, 37); + expect(testTrace.getMetric(metricName), 37); + testTrace.setMetric(metricName, 3); + expect(testTrace.getMetric(metricName), 3); + }); + + test('putAttribute works correctly', () { + testTrace.putAttribute('apple', 'sauce'); + testTrace.putAttribute('banana', 'pie'); + + expect(testTrace.getAttributes(), { + 'apple': 'sauce', + 'banana': 'pie', }); - test('start & stop trace', () async { - await testTrace.start(); - await testTrace.stop(); + testTrace.putAttribute('apple', 'sauce2'); + expect(testTrace.getAttributes(), { + 'apple': 'sauce2', + 'banana': 'pie', }); + }); - test('starting trace with performance collection disabled', () async { - await performance.setPerformanceCollectionEnabled(false); - await testTrace.start(); - await testTrace.stop(); - }); - - test("starting Trace twice shouldn't throw an error", () async { - await testTrace.start(); - await testTrace.start(); - }); + test('removeAttribute works correctly', () { + testTrace.putAttribute('sponge', 'bob'); + testTrace.putAttribute('patrick', 'star'); + testTrace.removeAttribute('sponge'); - test("stopping Trace twice shouldn't throw an error", () async { - await testTrace.start(); - await testTrace.stop(); - await testTrace.stop(); - }); - - test('incrementMetric works correctly', () { - testTrace.incrementMetric(metricName, 14); - expect(testTrace.getMetric(metricName), 14); - - testTrace.incrementMetric(metricName, 45); - expect(testTrace.getMetric(metricName), 59); - }); - - test('setMetric works correctly', () async { - testTrace.setMetric(metricName, 37); - expect(testTrace.getMetric(metricName), 37); - testTrace.setMetric(metricName, 3); - expect(testTrace.getMetric(metricName), 3); - }); + expect(testTrace.getAttributes(), {'patrick': 'star'}); - test('putAttribute works correctly', () { - testTrace.putAttribute('apple', 'sauce'); - testTrace.putAttribute('banana', 'pie'); + testTrace.removeAttribute('sponge'); - expect( - testTrace.getAttributes(), - {'apple': 'sauce', 'banana': 'pie'}, - ); + expect(testTrace.getAttributes(), {'patrick': 'star'}); + }); - testTrace.putAttribute('apple', 'sauce2'); - expect( - testTrace.getAttributes(), - {'apple': 'sauce2', 'banana': 'pie'}, - ); - }); + test('getAttribute', () async { + testTrace.putAttribute('yugi', 'oh'); - test('removeAttribute works correctly', () { - testTrace.putAttribute('sponge', 'bob'); - testTrace.putAttribute('patrick', 'star'); - testTrace.removeAttribute('sponge'); + expect(testTrace.getAttribute('yugi'), equals('oh')); + expect(testTrace.getAttribute('yugi'), equals('oh')); + }); + }, skip: kIsWeb || defaultTargetPlatform == TargetPlatform.macOS); - expect( - testTrace.getAttributes(), - {'patrick': 'star'}, - ); + group('$HttpMetric', () { + late FirebasePerformance performance; + late HttpMetric testHttpMetric; - testTrace.removeAttribute('sponge'); + setUpAll(() async { + performance = FirebasePerformance.instance; + await performance.setPerformanceCollectionEnabled(true); + }); - expect( - testTrace.getAttributes(), - {'patrick': 'star'}, - ); - }); + setUp(() async { + testHttpMetric = performance.newHttpMetric( + 'https://www.google.com/', + HttpMethod.Delete, + ); + }); - test('getAttribute', () async { - testTrace.putAttribute('yugi', 'oh'); + tearDown(() { + testHttpMetric.stop(); + }); - expect(testTrace.getAttribute('yugi'), equals('oh')); - expect(testTrace.getAttribute('yugi'), equals('oh')); - }); - }, - skip: kIsWeb || defaultTargetPlatform == TargetPlatform.macOS, - ); - - group( - '$HttpMetric', - () { - late FirebasePerformance performance; - late HttpMetric testHttpMetric; - - setUpAll(() async { - performance = FirebasePerformance.instance; - await performance.setPerformanceCollectionEnabled(true); - }); + test('test all Http method values', () async { + FirebasePerformance performance = FirebasePerformance.instance; - setUp(() async { - testHttpMetric = performance.newHttpMetric( + await Future.forEach(HttpMethod.values, (HttpMethod method) async { + final HttpMetric testMetric = performance.newHttpMetric( 'https://www.google.com/', - HttpMethod.Delete, + method, ); + await testMetric.start(); + await testMetric.stop(); }); + }); - tearDown(() { - testHttpMetric.stop(); - }); - - test('test all Http method values', () async { - FirebasePerformance performance = FirebasePerformance.instance; - - await Future.forEach(HttpMethod.values, (HttpMethod method) async { - final HttpMetric testMetric = performance.newHttpMetric( - 'https://www.google.com/', - method, - ); - await testMetric.start(); - await testMetric.stop(); - }); - }); - - test('test all Http method values with collection disabled', () async { - FirebasePerformance performance = FirebasePerformance.instance; - await performance.setPerformanceCollectionEnabled(false); - - await Future.forEach(HttpMethod.values, (HttpMethod method) async { - final HttpMetric testMetric = performance.newHttpMetric( - 'https://www.google.com/', - method, - ); - await testMetric.start(); - await testMetric.stop(); - }); - }); - - test('putAttribute works correctly', () { - testHttpMetric.putAttribute('apple', 'sauce'); - testHttpMetric.putAttribute('banana', 'pie'); - - expect( - testHttpMetric.getAttributes(), - {'apple': 'sauce', 'banana': 'pie'}, - ); - }); + test('test all Http method values with collection disabled', () async { + FirebasePerformance performance = FirebasePerformance.instance; + await performance.setPerformanceCollectionEnabled(false); - test('removeAttribute works correctly', () { - testHttpMetric.putAttribute('sponge', 'bob'); - testHttpMetric.putAttribute('patrick', 'star'); - testHttpMetric.removeAttribute('sponge'); - - expect( - testHttpMetric.getAttributes(), - {'patrick': 'star'}, - ); - - testHttpMetric.removeAttribute('sponge'); - expect( - testHttpMetric.getAttributes(), - {'patrick': 'star'}, + await Future.forEach(HttpMethod.values, (HttpMethod method) async { + final HttpMetric testMetric = performance.newHttpMetric( + 'https://www.google.com/', + method, ); + await testMetric.start(); + await testMetric.stop(); }); + }); - test('getAttribute works correctly', () { - testHttpMetric.putAttribute('yugi', 'oh'); + test('putAttribute works correctly', () { + testHttpMetric.putAttribute('apple', 'sauce'); + testHttpMetric.putAttribute('banana', 'pie'); - expect(testHttpMetric.getAttribute('yugi'), equals('oh')); + expect(testHttpMetric.getAttributes(), { + 'apple': 'sauce', + 'banana': 'pie', }); + }); - test('set HTTP response code correctly', () { - testHttpMetric.httpResponseCode = 443; - expect(testHttpMetric.httpResponseCode, equals(443)); - }); - - test('set request payload size correctly', () { - testHttpMetric.requestPayloadSize = 56734; - expect(testHttpMetric.requestPayloadSize, equals(56734)); - }); - - test('set response payload size correctly', () { - testHttpMetric.responsePayloadSize = 4949; - expect(testHttpMetric.responsePayloadSize, equals(4949)); - }); - - test('set response content type correctly', () { - testHttpMetric.responseContentType = 'content'; - expect(testHttpMetric.responseContentType, equals('content')); - }); + test('removeAttribute works correctly', () { + testHttpMetric.putAttribute('sponge', 'bob'); + testHttpMetric.putAttribute('patrick', 'star'); + testHttpMetric.removeAttribute('sponge'); - test("starting HttpMetric twice shouldn't throw an error", () async { - await testHttpMetric.start(); - await testHttpMetric.start(); + expect(testHttpMetric.getAttributes(), { + 'patrick': 'star', }); - test("stopping HttpMetric twice shouldn't throw an error", () async { - await testHttpMetric.start(); - await testHttpMetric.stop(); - await testHttpMetric.stop(); + testHttpMetric.removeAttribute('sponge'); + expect(testHttpMetric.getAttributes(), { + 'patrick': 'star', }); - }, - skip: kIsWeb || defaultTargetPlatform == TargetPlatform.macOS, - ); + }); + + test('getAttribute works correctly', () { + testHttpMetric.putAttribute('yugi', 'oh'); + + expect(testHttpMetric.getAttribute('yugi'), equals('oh')); + }); + + test('set HTTP response code correctly', () { + testHttpMetric.httpResponseCode = 443; + expect(testHttpMetric.httpResponseCode, equals(443)); + }); + + test('set request payload size correctly', () { + testHttpMetric.requestPayloadSize = 56734; + expect(testHttpMetric.requestPayloadSize, equals(56734)); + }); + + test('set response payload size correctly', () { + testHttpMetric.responsePayloadSize = 4949; + expect(testHttpMetric.responsePayloadSize, equals(4949)); + }); + + test('set response content type correctly', () { + testHttpMetric.responseContentType = 'content'; + expect(testHttpMetric.responseContentType, equals('content')); + }); + + test("starting HttpMetric twice shouldn't throw an error", () async { + await testHttpMetric.start(); + await testHttpMetric.start(); + }); + + test("stopping HttpMetric twice shouldn't throw an error", () async { + await testHttpMetric.start(); + await testHttpMetric.stop(); + await testHttpMetric.stop(); + }); + }, skip: kIsWeb || defaultTargetPlatform == TargetPlatform.macOS); } diff --git a/packages/firebase_performance/firebase_performance/example/integration_test/report_test_results.dart b/packages/firebase_performance/firebase_performance/example/integration_test/report_test_results.dart index ddeaeab1eaf0..c170cb63c415 100644 --- a/packages/firebase_performance/firebase_performance/example/integration_test/report_test_results.dart +++ b/packages/firebase_performance/firebase_performance/example/integration_test/report_test_results.dart @@ -26,8 +26,9 @@ void reportTestResultsToDriver(IntegrationTestWidgetsFlutterBinding binding) { for (final entry in binding.results.entries) if (entry.value is Failure) entry.key, ]; - bool didFail(String name) => failures - .any((failure) => name == failure || name.endsWith(' $failure')); + bool didFail(String name) => failures.any( + (failure) => name == failure || name.endsWith(' $failure'), + ); binding.reportData ??= {}; binding.reportData!['testResults'] = { diff --git a/packages/firebase_performance/firebase_performance/example/lib/firebase_options.dart b/packages/firebase_performance/firebase_performance/example/lib/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/firebase_performance/firebase_performance/example/lib/firebase_options.dart +++ b/packages/firebase_performance/firebase_performance/example/lib/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/firebase_performance/firebase_performance/example/lib/main.dart b/packages/firebase_performance/firebase_performance/example/lib/main.dart index 19c2d8a38eb8..a48004960cd4 100644 --- a/packages/firebase_performance/firebase_performance/example/lib/main.dart +++ b/packages/firebase_performance/firebase_performance/example/lib/main.dart @@ -13,9 +13,7 @@ import 'firebase_options.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); + await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); runApp(MyApp()); } @@ -33,8 +31,10 @@ class _MetricHttpClient extends BaseClient { Future send(BaseRequest request) async { // Custom network monitoring is not supported for web. // https://firebase.google.com/docs/perf-mon/custom-network-traces?platform=android - final HttpMetric metric = FirebasePerformance.instance - .newHttpMetric(request.url.toString(), HttpMethod.Get); + final HttpMetric metric = FirebasePerformance.instance.newHttpMetric( + request.url.toString(), + HttpMethod.Get, + ); metric.requestPayloadSize = request.contentLength; await metric.start(); @@ -85,8 +85,9 @@ class _MyAppState extends State { Future _togglePerformanceCollection() async { // No-op for web. - await _performance - .setPerformanceCollectionEnabled(!_isPerformanceCollectionEnabled); + await _performance.setPerformanceCollectionEnabled( + !_isPerformanceCollectionEnabled, + ); // Always true for web. final bool isEnabled = await _performance.isPerformanceCollectionEnabled(); @@ -155,10 +156,7 @@ class _MyAppState extends State { final _MetricHttpClient metricHttpClient = _MetricHttpClient(Client()); - final Request request = Request( - 'SEND', - Uri.parse('https://www.bbc.co.uk'), - ); + final Request request = Request('SEND', Uri.parse('https://www.bbc.co.uk')); unawaited(metricHttpClient.send(request)); @@ -177,9 +175,7 @@ class _MyAppState extends State { const textStyle = TextStyle(color: Colors.lightGreenAccent, fontSize: 25); return MaterialApp( home: Scaffold( - appBar: AppBar( - title: const Text('Firebase Performance Example'), - ), + appBar: AppBar(title: const Text('Firebase Performance Example')), body: Center( child: Column( children: [ @@ -192,18 +188,12 @@ class _MyAppState extends State { onPressed: _testTrace1, child: const Text('Run Trace One'), ), - Text( - _trace1HasRan ? 'Trace Ran!' : '', - style: textStyle, - ), + Text(_trace1HasRan ? 'Trace Ran!' : '', style: textStyle), ElevatedButton( onPressed: _testTrace2, child: const Text('Run Trace Two'), ), - Text( - _trace2HasRan ? 'Trace Ran!' : '', - style: textStyle, - ), + Text(_trace2HasRan ? 'Trace Ran!' : '', style: textStyle), ElevatedButton( onPressed: _testCustomHttpMetric, child: const Text('Run Custom HttpMetric'), diff --git a/packages/firebase_performance/firebase_performance/example/pubspec.yaml b/packages/firebase_performance/firebase_performance/example/pubspec.yaml index b14996493d15..9762aee5ff9e 100644 --- a/packages/firebase_performance/firebase_performance/example/pubspec.yaml +++ b/packages/firebase_performance/firebase_performance/example/pubspec.yaml @@ -5,8 +5,8 @@ resolution: workspace publish_to: none environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core: ^4.14.0 diff --git a/packages/firebase_performance/firebase_performance/example/test_driver/integration_test.dart b/packages/firebase_performance/firebase_performance/example/test_driver/integration_test.dart index 691723cbbfe1..9ccbcc26ab97 100644 --- a/packages/firebase_performance/firebase_performance/example/test_driver/integration_test.dart +++ b/packages/firebase_performance/firebase_performance/example/test_driver/integration_test.dart @@ -7,28 +7,32 @@ import 'dart:io'; import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver( - writeResponseOnFailure: true, - responseDataCallback: (Map? data) async { - final results = - (data?['testResults'] as Map?)?.cast() ?? - const {}; - var passed = 0; - var failed = 0; - for (final entry in results.entries) { - final ok = entry.value == 'success'; - ok ? passed++ : failed++; - // ignore: avoid_print - print('${ok ? '✅' : '❌'} ${entry.key}'); - } - // ignore: avoid_print - print('Web e2e summary: $passed passed, $failed failed, ' - '${results.length} total'); - if (results.isEmpty) { - // ignore: avoid_print - print('[E] No tests reported by the app - treating as ' - 'infrastructure failure.'); - exit(1); - } - await writeResponseData(data); - }, + writeResponseOnFailure: true, + responseDataCallback: (Map? data) async { + final results = + (data?['testResults'] as Map?)?.cast() ?? + const {}; + var passed = 0; + var failed = 0; + for (final entry in results.entries) { + final ok = entry.value == 'success'; + ok ? passed++ : failed++; + // ignore: avoid_print + print('${ok ? '✅' : '❌'} ${entry.key}'); + } + // ignore: avoid_print + print( + 'Web e2e summary: $passed passed, $failed failed, ' + '${results.length} total', ); + if (results.isEmpty) { + // ignore: avoid_print + print( + '[E] No tests reported by the app - treating as ' + 'infrastructure failure.', + ); + exit(1); + } + await writeResponseData(data); + }, +); diff --git a/packages/firebase_performance/firebase_performance/lib/src/firebase_performance.dart b/packages/firebase_performance/firebase_performance/lib/src/firebase_performance.dart index 5061983318c5..a86bfe5ab04d 100644 --- a/packages/firebase_performance/firebase_performance/lib/src/firebase_performance.dart +++ b/packages/firebase_performance/firebase_performance/lib/src/firebase_performance.dart @@ -9,7 +9,7 @@ part of '../firebase_performance.dart'; /// You can get an instance by calling [FirebasePerformance.instance]. class FirebasePerformance extends FirebasePlugin { FirebasePerformance._({required this.app}) - : super(app.name, 'plugins.flutter.io/firebase_performance'); + : super(app.name, 'plugins.flutter.io/firebase_performance'); // Cached and lazily loaded instance of [FirebasePerformancePlatform] to avoid // creating a [MethodChannelFirebasePerformance] when not needed or creating an diff --git a/packages/firebase_performance/firebase_performance/pubspec.yaml b/packages/firebase_performance/firebase_performance/pubspec.yaml index 37c69998accd..e3c62b927bba 100644 --- a/packages/firebase_performance/firebase_performance/pubspec.yaml +++ b/packages/firebase_performance/firebase_performance/pubspec.yaml @@ -17,8 +17,8 @@ false_secrets: - example/** environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core: ^4.14.0 diff --git a/packages/firebase_performance/firebase_performance/test/firebase_performance_test.dart b/packages/firebase_performance/firebase_performance/test/firebase_performance_test.dart index 7a0016ebb129..462209b0d292 100644 --- a/packages/firebase_performance/firebase_performance/test/firebase_performance_test.dart +++ b/packages/firebase_performance/firebase_performance/test/firebase_performance_test.dart @@ -22,8 +22,9 @@ void main() { late FirebasePerformance performance; group('$FirebasePerformance', () { - when(mockPerformancePlatform.delegateFor(app: anyNamed('app'))) - .thenReturn(mockPerformancePlatform); + when( + mockPerformancePlatform.delegateFor(app: anyNamed('app')), + ).thenReturn(mockPerformancePlatform); setUpAll(() async { await Firebase.initializeApp(); @@ -43,26 +44,31 @@ void main() { group('performanceCollectionEnabled', () { test('getter should call delegate method', () async { - when(mockPerformancePlatform.isPerformanceCollectionEnabled()) - .thenAnswer((_) => Future.value(true)); + when( + mockPerformancePlatform.isPerformanceCollectionEnabled(), + ).thenAnswer((_) => Future.value(true)); await performance.isPerformanceCollectionEnabled(); verify(mockPerformancePlatform.isPerformanceCollectionEnabled()); }); test('setter should call delegate method', () async { - when(mockPerformancePlatform.setPerformanceCollectionEnabled(true)) - .thenAnswer((_) => Future.value()); + when( + mockPerformancePlatform.setPerformanceCollectionEnabled(true), + ).thenAnswer((_) => Future.value()); await performance.setPerformanceCollectionEnabled(true); verify(mockPerformancePlatform.setPerformanceCollectionEnabled(true)); }); }); group('trace', () { - when(mockPerformancePlatform.newTrace('foo')) - .thenReturn(mockTracePlatform); - when(mockTracePlatform.start()) - .thenAnswer((realInvocation) => Future.value()); - when(mockTracePlatform.incrementMetric('bar', 8)) - .thenAnswer((realInvocation) => Future.value()); + when( + mockPerformancePlatform.newTrace('foo'), + ).thenReturn(mockTracePlatform); + when( + mockTracePlatform.start(), + ).thenAnswer((realInvocation) => Future.value()); + when( + mockTracePlatform.incrementMetric('bar', 8), + ).thenAnswer((realInvocation) => Future.value()); test('newTrace should call delegate method', () async { performance.newTrace('foo'); @@ -97,8 +103,9 @@ void main() { }); group('http metric', () { - when(mockPerformancePlatform.newHttpMetric(mockUrl, HttpMethod.Get)) - .thenReturn(mockHttpMetricPlatform); + when( + mockPerformancePlatform.newHttpMetric(mockUrl, HttpMethod.Get), + ).thenReturn(mockHttpMetricPlatform); test('newHttpMetric should call delegate method', () async { performance.newHttpMetric(mockUrl, HttpMethod.Get); @@ -136,29 +143,37 @@ void main() { verify(mockHttpMetricPlatform.httpResponseCode = 8080); }); - test('set requestPayloadSize setter should call delegate setter', - () async { - final httpMetric = performance.newHttpMetric(mockUrl, HttpMethod.Get); - when(mockHttpMetricPlatform.requestPayloadSize = 8).thenReturn(0); - httpMetric.requestPayloadSize = 8; - verify(mockHttpMetricPlatform.requestPayloadSize = 8); - }); - - test('setResponsePayloadSize setter should call delegate setter', - () async { - final httpMetric = performance.newHttpMetric(mockUrl, HttpMethod.Get); - when(mockHttpMetricPlatform.responsePayloadSize = 99).thenReturn(0); - httpMetric.responsePayloadSize = 99; - verify(mockHttpMetricPlatform.responsePayloadSize = 99); - }); - - test('set responseContentType setter should call delegate setter', - () async { - final httpMetric = performance.newHttpMetric(mockUrl, HttpMethod.Get); - when(mockHttpMetricPlatform.responseContentType = 'foo').thenReturn(''); - httpMetric.responseContentType = 'foo'; - verify(mockHttpMetricPlatform.responseContentType = 'foo'); - }); + test( + 'set requestPayloadSize setter should call delegate setter', + () async { + final httpMetric = performance.newHttpMetric(mockUrl, HttpMethod.Get); + when(mockHttpMetricPlatform.requestPayloadSize = 8).thenReturn(0); + httpMetric.requestPayloadSize = 8; + verify(mockHttpMetricPlatform.requestPayloadSize = 8); + }, + ); + + test( + 'setResponsePayloadSize setter should call delegate setter', + () async { + final httpMetric = performance.newHttpMetric(mockUrl, HttpMethod.Get); + when(mockHttpMetricPlatform.responsePayloadSize = 99).thenReturn(0); + httpMetric.responsePayloadSize = 99; + verify(mockHttpMetricPlatform.responsePayloadSize = 99); + }, + ); + + test( + 'set responseContentType setter should call delegate setter', + () async { + final httpMetric = performance.newHttpMetric(mockUrl, HttpMethod.Get); + when( + mockHttpMetricPlatform.responseContentType = 'foo', + ).thenReturn(''); + httpMetric.responseContentType = 'foo'; + verify(mockHttpMetricPlatform.responseContentType = 'foo'); + }, + ); test('start should call delegate', () async { final httpMetric = performance.newHttpMetric(mockUrl, HttpMethod.Get); diff --git a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_firebase_performance.dart b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_firebase_performance.dart index 70b070c25e55..ae8d3c43c00c 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_firebase_performance.dart +++ b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_firebase_performance.dart @@ -15,9 +15,10 @@ import 'utils/exception.dart'; /// The method channel implementation of [FirebasePerformancePlatform]. class MethodChannelFirebasePerformance extends FirebasePerformancePlatform { MethodChannelFirebasePerformance({required FirebaseApp app}) - : super(appInstance: app); - static const MethodChannel channel = - MethodChannel('plugins.flutter.io/firebase_performance'); + : super(appInstance: app); + static const MethodChannel channel = MethodChannel( + 'plugins.flutter.io/firebase_performance', + ); /// Internal stub class initializer. /// diff --git a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_http_metric.dart b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_http_metric.dart index d002a8849b0c..8991cea2be22 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_http_metric.dart +++ b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_http_metric.dart @@ -9,10 +9,7 @@ import 'method_channel_firebase_performance.dart'; import 'utils/exception.dart'; class MethodChannelHttpMetric extends HttpMetricPlatform { - MethodChannelHttpMetric( - this._url, - this._httpMethod, - ) : super(); + MethodChannelHttpMetric(this._url, this._httpMethod) : super(); int? _httpMetricHandle; final String _url; @@ -84,8 +81,10 @@ class MethodChannelHttpMetric extends HttpMetricPlatform { responseContentType: _responseContentType, attributes: _attributes, ); - await MethodChannelFirebasePerformance.pigeonChannel - .stopHttpMetric(_httpMetricHandle!, attributes); + await MethodChannelFirebasePerformance.pigeonChannel.stopHttpMetric( + _httpMetricHandle!, + attributes, + ); _hasStopped = true; } catch (e, s) { convertPlatformException(e, s); diff --git a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_trace.dart b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_trace.dart index d6d46f1d1b35..303d9714b02c 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_trace.dart +++ b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_trace.dart @@ -41,8 +41,10 @@ class MethodChannelTrace extends TracePlatform { metrics: _metrics, attributes: _attributes, ); - await MethodChannelFirebasePerformance.pigeonChannel - .stopTrace(_traceHandle!, attributes); + await MethodChannelFirebasePerformance.pigeonChannel.stopTrace( + _traceHandle!, + attributes, + ); _hasStopped = true; } catch (e, s) { convertPlatformException(e, s); diff --git a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/pigeon/messages.pigeon.dart b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/pigeon/messages.pigeon.dart index df055af51a47..cbe375f61b9b 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/pigeon/messages.pigeon.dart +++ b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/pigeon/messages.pigeon.dart @@ -37,8 +37,11 @@ Object? _extractReplyValueOrThrow( return replyList.firstOrNull; } -List wrapResponse( - {Object? result, PlatformException? error, bool empty = false}) { +List wrapResponse({ + Object? result, + PlatformException? error, + bool empty = false, +}) { if (empty) { return []; } @@ -60,8 +63,9 @@ bool _deepEquals(Object? a, Object? b) { } if (a is List && b is List) { return a.length == b.length && - a.indexed - .every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1])); + a.indexed.every( + ((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]), + ); } if (a is Map && b is Map) { if (a.length != b.length) { @@ -110,33 +114,17 @@ int _deepHash(Object? value) { return value.hashCode; } -enum HttpMethod { - connect, - delete, - get, - head, - options, - patch, - post, - put, - trace, -} +enum HttpMethod { connect, delete, get, head, options, patch, post, put, trace } class HttpMetricOptions { - HttpMetricOptions({ - required this.url, - required this.httpMethod, - }); + HttpMetricOptions({required this.url, required this.httpMethod}); String url; HttpMethod httpMethod; List _toList() { - return [ - url, - httpMethod, - ]; + return [url, httpMethod]; } Object encode() { @@ -235,20 +223,14 @@ class HttpMetricAttributes { } class TraceAttributes { - TraceAttributes({ - this.metrics, - this.attributes, - }); + TraceAttributes({this.metrics, this.attributes}); Map? metrics; Map? attributes; List _toList() { - return [ - metrics, - attributes, - ]; + return [metrics, attributes]; } Object encode() { @@ -327,11 +309,13 @@ class FirebasePerformanceHostApi { /// Constructor for [FirebasePerformanceHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - FirebasePerformanceHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + FirebasePerformanceHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -346,8 +330,9 @@ class FirebasePerformanceHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([enabled]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [enabled], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -384,8 +369,9 @@ class FirebasePerformanceHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([name]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [name], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -404,8 +390,9 @@ class FirebasePerformanceHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([handle, attributes]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [handle, attributes], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -423,8 +410,9 @@ class FirebasePerformanceHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([options]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [options], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -436,7 +424,9 @@ class FirebasePerformanceHostApi { } Future stopHttpMetric( - int handle, HttpMetricAttributes attributes) async { + int handle, + HttpMetricAttributes attributes, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_performance_platform_interface.FirebasePerformanceHostApi.stopHttpMetric$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -444,8 +434,9 @@ class FirebasePerformanceHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([handle, attributes]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [handle, attributes], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( diff --git a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/platform_interface/platform_interface_firebase_performance.dart b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/platform_interface/platform_interface_firebase_performance.dart index f487f8e1ad8e..cd1c025010b1 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/platform_interface/platform_interface_firebase_performance.dart +++ b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/platform_interface/platform_interface_firebase_performance.dart @@ -45,9 +45,7 @@ abstract class FirebasePerformancePlatform extends PlatformInterface { } /// Create an instance with a [FirebaseApp] using an existing instance. - factory FirebasePerformancePlatform.instanceFor({ - required FirebaseApp app, - }) { + factory FirebasePerformancePlatform.instanceFor({required FirebaseApp app}) { return FirebasePerformancePlatform.instance.delegateFor(app: app); } diff --git a/packages/firebase_performance/firebase_performance_platform_interface/pigeons/messages.dart b/packages/firebase_performance/firebase_performance_platform_interface/pigeons/messages.dart index 10603e2a480a..274f4b1ded4d 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/pigeons/messages.dart +++ b/packages/firebase_performance/firebase_performance_platform_interface/pigeons/messages.dart @@ -22,23 +22,10 @@ import 'package:pigeon/pigeon.dart'; copyrightHeader: 'pigeons/copyright.txt', ), ) -enum HttpMethod { - connect, - delete, - get, - head, - options, - patch, - post, - put, - trace, -} +enum HttpMethod { connect, delete, get, head, options, patch, post, put, trace } class HttpMetricOptions { - const HttpMetricOptions({ - required this.url, - required this.httpMethod, - }); + const HttpMetricOptions({required this.url, required this.httpMethod}); final String url; final HttpMethod httpMethod; @@ -61,10 +48,7 @@ class HttpMetricAttributes { } class TraceAttributes { - const TraceAttributes({ - this.metrics, - this.attributes, - }); + const TraceAttributes({this.metrics, this.attributes}); final Map? metrics; final Map? attributes; diff --git a/packages/firebase_performance/firebase_performance_platform_interface/pubspec.yaml b/packages/firebase_performance/firebase_performance_platform_interface/pubspec.yaml index 2eda61142d15..95c6c361fccb 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/pubspec.yaml +++ b/packages/firebase_performance/firebase_performance_platform_interface/pubspec.yaml @@ -5,8 +5,8 @@ resolution: workspace homepage: https://firebase.google.com/docs/perf-mon/flutter/get-started environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_performance/firebase_performance_platform_interface/test/method_channel_tests/method_channel_firebase_performance_test.dart b/packages/firebase_performance/firebase_performance_platform_interface/test/method_channel_tests/method_channel_firebase_performance_test.dart index 49b990c607a9..0b4e143fc6fa 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/test/method_channel_tests/method_channel_firebase_performance_test.dart +++ b/packages/firebase_performance/firebase_performance_platform_interface/test/method_channel_tests/method_channel_firebase_performance_test.dart @@ -85,8 +85,10 @@ void main() { group('newHttpMetric', () { test('should call delegate method successfully', () { - final httpMetric = - performance.newHttpMetric('http-metric-url', HttpMethod.Get); + final httpMetric = performance.newHttpMetric( + 'http-metric-url', + HttpMethod.Get, + ); expect(httpMetric, isA()); }); diff --git a/packages/firebase_performance/firebase_performance_platform_interface/test/method_channel_tests/method_channel_http_metric_test.dart b/packages/firebase_performance/firebase_performance_platform_interface/test/method_channel_tests/method_channel_http_metric_test.dart index 79b95d7c8af2..96e423a416ce 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/test/method_channel_tests/method_channel_http_metric_test.dart +++ b/packages/firebase_performance/firebase_performance_platform_interface/test/method_channel_tests/method_channel_http_metric_test.dart @@ -46,10 +46,7 @@ void main() { }); setUp(() async { - httpMetric = TestMethodChannelHttpMetric( - kUrl, - kMethod, - ); + httpMetric = TestMethodChannelHttpMetric(kUrl, kMethod); mockPlatformExceptionThrown = false; mockExceptionThrown = false; log.clear(); @@ -103,49 +100,52 @@ void main() { }); test( - "will immediately return if name length is longer than 'HttpMetricPlatform.maxAttributeKeyLength' ", - () async { - String longName = - 'thisisaverylongnamethatislongerthanthe40charactersallowedbyHttpMetricPlatformmaxAttributeKeyLengthwaywaylongertogetover100charlimit'; - const String attributeValue = 'foo'; - httpMetric.putAttribute(longName, attributeValue); - expect(log, []); - expect(httpMetric.getAttribute(longName), isNull); - }); + "will immediately return if name length is longer than 'HttpMetricPlatform.maxAttributeKeyLength' ", + () async { + String longName = + 'thisisaverylongnamethatislongerthanthe40charactersallowedbyHttpMetricPlatformmaxAttributeKeyLengthwaywaylongertogetover100charlimit'; + const String attributeValue = 'foo'; + httpMetric.putAttribute(longName, attributeValue); + expect(log, []); + expect(httpMetric.getAttribute(longName), isNull); + }, + ); test( - "will immediately return if value length is longer than 'HttpMetricPlatform.maxAttributeValueLength' ", - () async { - String attributeName = 'foo'; - String longValue = - 'thisisaverylongnamethatislongerthanthe40charactersallowedbyHttpMetricPlatformmaxAttributeKeyLengthwaywaylongertogetover100charlimit'; - httpMetric.putAttribute(attributeName, longValue); - expect(log, []); - expect(httpMetric.getAttribute(attributeName), isNull); - }); + "will immediately return if value length is longer than 'HttpMetricPlatform.maxAttributeValueLength' ", + () async { + String attributeName = 'foo'; + String longValue = + 'thisisaverylongnamethatislongerthanthe40charactersallowedbyHttpMetricPlatformmaxAttributeKeyLengthwaywaylongertogetover100charlimit'; + httpMetric.putAttribute(attributeName, longValue); + expect(log, []); + expect(httpMetric.getAttribute(attributeName), isNull); + }, + ); test( - "will immediately return if attribute map has more properties than 'HttpMetricPlatform.maxCustomAttributes' allows", - () async { - String attributeName1 = 'foo'; - String attributeName2 = 'bar'; - String attributeName3 = 'baz'; - String attributeName4 = 'too'; - String attributeName5 = 'yoo'; - String attributeName6 = 'who'; - String attributeValue = 'bar'; - httpMetric.putAttribute(attributeName1, attributeValue); - httpMetric.putAttribute(attributeName2, attributeValue); - httpMetric.putAttribute(attributeName3, attributeValue); - httpMetric.putAttribute(attributeName4, attributeValue); - httpMetric.putAttribute(attributeName5, attributeValue); - httpMetric.putAttribute(attributeName6, attributeValue); - - expect(log, []); - - expect(httpMetric.getAttribute(attributeName5), attributeValue); - expect(httpMetric.getAttribute(attributeName6), isNull); - }); + "will immediately return if attribute map has more properties than 'HttpMetricPlatform.maxCustomAttributes' allows", + () async { + String attributeName1 = 'foo'; + String attributeName2 = 'bar'; + String attributeName3 = 'baz'; + String attributeName4 = 'too'; + String attributeName5 = 'yoo'; + String attributeName6 = 'who'; + String attributeValue = 'bar'; + httpMetric.putAttribute(attributeName1, attributeValue); + httpMetric.putAttribute(attributeName2, attributeValue); + httpMetric.putAttribute(attributeName3, attributeValue); + httpMetric.putAttribute(attributeName4, attributeValue); + httpMetric.putAttribute(attributeName5, attributeValue); + httpMetric.putAttribute(attributeName6, attributeValue); + + expect(log, []); + + expect(httpMetric.getAttribute(attributeName5), attributeValue); + expect(httpMetric.getAttribute(attributeName6), isNull); + }, + ); }); group('removeAttribute', () { @@ -203,8 +203,6 @@ class TestFirebasePerformancePlatform extends FirebasePerformancePlatform { } class TestMethodChannelHttpMetric extends MethodChannelHttpMetric { - TestMethodChannelHttpMetric( - String url, - HttpMethod method, - ) : super(url, method); + TestMethodChannelHttpMetric(String url, HttpMethod method) + : super(url, method); } diff --git a/packages/firebase_performance/firebase_performance_platform_interface/test/method_channel_tests/method_channel_trace_test.dart b/packages/firebase_performance/firebase_performance_platform_interface/test/method_channel_tests/method_channel_trace_test.dart index 72b5033a095c..834ce2a7f3ac 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/test/method_channel_tests/method_channel_trace_test.dart +++ b/packages/firebase_performance/firebase_performance_platform_interface/test/method_channel_tests/method_channel_trace_test.dart @@ -70,49 +70,52 @@ void main() { }); test( - "will immediately return if name length is longer than 'TracePlatform.maxAttributeKeyLength' ", - () async { - String longName = - 'thisisaverylongnamethatislongerthanthe40charactersallowedbyTracePlatformmaxAttributeKeyLengthwaywaylongertogetover100charlimit'; - const String attributeValue = 'foo'; - trace.putAttribute(longName, attributeValue); - expect(log, []); - expect(trace.getAttribute(longName), isNull); - }); + "will immediately return if name length is longer than 'TracePlatform.maxAttributeKeyLength' ", + () async { + String longName = + 'thisisaverylongnamethatislongerthanthe40charactersallowedbyTracePlatformmaxAttributeKeyLengthwaywaylongertogetover100charlimit'; + const String attributeValue = 'foo'; + trace.putAttribute(longName, attributeValue); + expect(log, []); + expect(trace.getAttribute(longName), isNull); + }, + ); test( - "will immediately return if value length is longer than 'TracePlatform.maxAttributeValueLength' ", - () async { - String attributeName = 'foo'; - String longValue = - 'thisisaverylongnamethatislongerthanthe40charactersallowedbyTracePlatformmaxAttributeKeyLengthwaywaylongertogetover100charlimit'; - trace.putAttribute(attributeName, longValue); - expect(log, []); - expect(trace.getAttribute(attributeName), isNull); - }); + "will immediately return if value length is longer than 'TracePlatform.maxAttributeValueLength' ", + () async { + String attributeName = 'foo'; + String longValue = + 'thisisaverylongnamethatislongerthanthe40charactersallowedbyTracePlatformmaxAttributeKeyLengthwaywaylongertogetover100charlimit'; + trace.putAttribute(attributeName, longValue); + expect(log, []); + expect(trace.getAttribute(attributeName), isNull); + }, + ); test( - "will immediately return if attribute map has more properties than 'TracePlatform.maxCustomAttributes' allows", - () async { - String attributeName1 = 'foo'; - String attributeName2 = 'bar'; - String attributeName3 = 'baz'; - String attributeName4 = 'too'; - String attributeName5 = 'yoo'; - String attributeName6 = 'who'; - String attributeValue = 'bar'; - trace.putAttribute(attributeName1, attributeValue); - trace.putAttribute(attributeName2, attributeValue); - trace.putAttribute(attributeName3, attributeValue); - trace.putAttribute(attributeName4, attributeValue); - trace.putAttribute(attributeName5, attributeValue); - trace.putAttribute(attributeName6, attributeValue); - - expect(log, []); - - expect(trace.getAttribute(attributeName5), attributeValue); - expect(trace.getAttribute(attributeName6), isNull); - }); + "will immediately return if attribute map has more properties than 'TracePlatform.maxCustomAttributes' allows", + () async { + String attributeName1 = 'foo'; + String attributeName2 = 'bar'; + String attributeName3 = 'baz'; + String attributeName4 = 'too'; + String attributeName5 = 'yoo'; + String attributeName6 = 'who'; + String attributeValue = 'bar'; + trace.putAttribute(attributeName1, attributeValue); + trace.putAttribute(attributeName2, attributeValue); + trace.putAttribute(attributeName3, attributeValue); + trace.putAttribute(attributeName4, attributeValue); + trace.putAttribute(attributeName5, attributeValue); + trace.putAttribute(attributeName6, attributeValue); + + expect(log, []); + + expect(trace.getAttribute(attributeName5), attributeValue); + expect(trace.getAttribute(attributeName6), isNull); + }, + ); }); group('removeAttribute', () { diff --git a/packages/firebase_performance/firebase_performance_platform_interface/test/mock.dart b/packages/firebase_performance/firebase_performance_platform_interface/test/mock.dart index 9bcbb3f6ce07..2f314e037588 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/test/mock.dart +++ b/packages/firebase_performance/firebase_performance_platform_interface/test/mock.dart @@ -22,10 +22,11 @@ void setupFirebasePerformanceMocks([Callback? customHandlers]) { void handleMethodCall(MethodCallCallback methodCallCallback) => TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(MethodChannelFirebasePerformance.channel, - (call) async { - return await methodCallCallback(call); - }); + .setMockMethodCallHandler(MethodChannelFirebasePerformance.channel, ( + call, + ) async { + return await methodCallCallback(call); + }); Future testExceptionHandling( String type, diff --git a/packages/firebase_performance/firebase_performance_platform_interface/test/pigeon/test_api.dart b/packages/firebase_performance/firebase_performance_platform_interface/test/pigeon/test_api.dart index e1bf4fe97659..efd3750f5178 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/test/pigeon/test_api.dart +++ b/packages/firebase_performance/firebase_performance_platform_interface/test/pigeon/test_api.dart @@ -77,163 +77,202 @@ abstract class TestFirebasePerformanceHostApi { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_performance_platform_interface.FirebasePerformanceHostApi.setPerformanceCollectionEnabled$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_performance_platform_interface.FirebasePerformanceHostApi.setPerformanceCollectionEnabled$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final bool arg_enabled = args[0]! as bool; - try { - await api.setPerformanceCollectionEnabled(arg_enabled); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final bool arg_enabled = args[0]! as bool; + try { + await api.setPerformanceCollectionEnabled(arg_enabled); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_performance_platform_interface.FirebasePerformanceHostApi.isPerformanceCollectionEnabled$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_performance_platform_interface.FirebasePerformanceHostApi.isPerformanceCollectionEnabled$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - try { - final bool output = await api.isPerformanceCollectionEnabled(); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + try { + final bool output = await api.isPerformanceCollectionEnabled(); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_performance_platform_interface.FirebasePerformanceHostApi.startTrace$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_performance_platform_interface.FirebasePerformanceHostApi.startTrace$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final String arg_name = args[0]! as String; - try { - final int output = await api.startTrace(arg_name); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final String arg_name = args[0]! as String; + try { + final int output = await api.startTrace(arg_name); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_performance_platform_interface.FirebasePerformanceHostApi.stopTrace$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_performance_platform_interface.FirebasePerformanceHostApi.stopTrace$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final int arg_handle = args[0]! as int; - final TraceAttributes arg_attributes = args[1]! as TraceAttributes; - try { - await api.stopTrace(arg_handle, arg_attributes); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final int arg_handle = args[0]! as int; + final TraceAttributes arg_attributes = + args[1]! as TraceAttributes; + try { + await api.stopTrace(arg_handle, arg_attributes); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_performance_platform_interface.FirebasePerformanceHostApi.startHttpMetric$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_performance_platform_interface.FirebasePerformanceHostApi.startHttpMetric$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final HttpMetricOptions arg_options = args[0]! as HttpMetricOptions; - try { - final int output = await api.startHttpMetric(arg_options); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final HttpMetricOptions arg_options = + args[0]! as HttpMetricOptions; + try { + final int output = await api.startHttpMetric(arg_options); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_performance_platform_interface.FirebasePerformanceHostApi.stopHttpMetric$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_performance_platform_interface.FirebasePerformanceHostApi.stopHttpMetric$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final int arg_handle = args[0]! as int; - final HttpMetricAttributes arg_attributes = - args[1]! as HttpMetricAttributes; - try { - await api.stopHttpMetric(arg_handle, arg_attributes); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final int arg_handle = args[0]! as int; + final HttpMetricAttributes arg_attributes = + args[1]! as HttpMetricAttributes; + try { + await api.stopHttpMetric(arg_handle, arg_attributes); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } diff --git a/packages/firebase_performance/firebase_performance_platform_interface/test/platform_interface_tests/platform_interface_firebase_performance_test.dart b/packages/firebase_performance/firebase_performance_platform_interface/test/platform_interface_tests/platform_interface_firebase_performance_test.dart index 1b94cb377bf9..4cde31a82ab3 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/test/platform_interface_tests/platform_interface_firebase_performance_test.dart +++ b/packages/firebase_performance/firebase_performance_platform_interface/test/platform_interface_tests/platform_interface_firebase_performance_test.dart @@ -19,9 +19,7 @@ void main() { setUpAll(() async { app = await Firebase.initializeApp(); - firebasePerformancePlatform = TestFirebasePerformancePlatform( - app, - ); + firebasePerformancePlatform = TestFirebasePerformancePlatform(app); }); test('Constructor', () { @@ -30,9 +28,7 @@ void main() { }); test('FirebasePerformancePlatform.instanceFor', () { - final result = FirebasePerformancePlatform.instanceFor( - app: app, - ); + final result = FirebasePerformancePlatform.instanceFor(app: app); expect(result, isA()); }); @@ -49,8 +45,9 @@ void main() { group('set.instance', () { test('sets the current instance', () { - FirebasePerformancePlatform.instance = - TestFirebasePerformancePlatform(app); + FirebasePerformancePlatform.instance = TestFirebasePerformancePlatform( + app, + ); expect( FirebasePerformancePlatform.instance, diff --git a/packages/firebase_performance/firebase_performance_web/lib/firebase_performance_web.dart b/packages/firebase_performance/firebase_performance_web/lib/firebase_performance_web.dart index 76846c992ce5..1119a2e0e08e 100644 --- a/packages/firebase_performance/firebase_performance_web/lib/firebase_performance_web.dart +++ b/packages/firebase_performance/firebase_performance_web/lib/firebase_performance_web.dart @@ -22,9 +22,7 @@ class FirebasePerformanceWeb extends FirebasePerformancePlatform { /// Stub initializer to allow the [registerWith] to create an instance without /// registering the web delegates or listeners. - FirebasePerformanceWeb._() - : _webPerformance = null, - super(appInstance: null); + FirebasePerformanceWeb._() : _webPerformance = null, super(appInstance: null); /// Instance of Performance from the web plugin. performance_interop.Performance? _webPerformance; diff --git a/packages/firebase_performance/firebase_performance_web/lib/src/interop/performance.dart b/packages/firebase_performance/firebase_performance_web/lib/src/interop/performance.dart index 538a9568a0c4..a84da9c4f49d 100644 --- a/packages/firebase_performance/firebase_performance_web/lib/src/interop/performance.dart +++ b/packages/firebase_performance/firebase_performance_web/lib/src/interop/performance.dart @@ -33,11 +33,10 @@ class Performance static Performance getInstance( performance_interop.PerformanceJsImpl jsObject, - ) => - _expando[jsObject] ??= Performance._fromJsObject(jsObject); + ) => _expando[jsObject] ??= Performance._fromJsObject(jsObject); Performance._fromJsObject(performance_interop.PerformanceJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); Trace trace(String traceName) => Trace.fromJsObject(performance_interop.trace(jsObject, traceName.toJS)); @@ -51,7 +50,7 @@ class Performance class Trace extends JsObjectWrapper { Trace.fromJsObject(performance_interop.TraceJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); String getAttribute(String attr) => jsObject.getAttribute(attr.toJS).toDart; diff --git a/packages/firebase_performance/firebase_performance_web/pubspec.yaml b/packages/firebase_performance/firebase_performance_web/pubspec.yaml index fa828a5bc07d..7194497a6903 100644 --- a/packages/firebase_performance/firebase_performance_web/pubspec.yaml +++ b/packages/firebase_performance/firebase_performance_web/pubspec.yaml @@ -5,8 +5,8 @@ version: 0.1.8+13 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.22.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_remote_config/firebase_remote_config/example/integration_test/e2e_test.dart b/packages/firebase_remote_config/firebase_remote_config/example/integration_test/e2e_test.dart index 0e851ed09a5b..dbc08756ea94 100644 --- a/packages/firebase_remote_config/firebase_remote_config/example/integration_test/e2e_test.dart +++ b/packages/firebase_remote_config/firebase_remote_config/example/integration_test/e2e_test.dart @@ -15,226 +15,203 @@ void main() { final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized(); reportTestResultsToDriver(binding); - group( - 'firebase_remote_config', - () { - setUpAll(() async { - // The native SDK may already have configured [DEFAULT] from a bundled - // GoogleService-Info.plist (the plugin registrant does this before any - // Dart runs). Dart's Firebase.apps cannot see that app until the first - // platform-channel call, so the only reliable guard is catching the - // duplicate-app error and keeping the natively configured instance. - try { - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); - } on FirebaseException catch (e) { - if (e.code != 'duplicate-app') { - rethrow; - } - } - await FirebaseRemoteConfig.instance.setConfigSettings( - RemoteConfigSettings( - fetchTimeout: const Duration(seconds: 8), - minimumFetchInterval: Duration.zero, - ), + group('firebase_remote_config', () { + setUpAll(() async { + // The native SDK may already have configured [DEFAULT] from a bundled + // GoogleService-Info.plist (the plugin registrant does this before any + // Dart runs). Dart's Firebase.apps cannot see that app until the first + // platform-channel call, so the only reliable guard is catching the + // duplicate-app error and keeping the natively configured instance. + try { + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, ); - await FirebaseRemoteConfig.instance.setDefaults({ - 'hello': 'default hello', - }); - await FirebaseRemoteConfig.instance.ensureInitialized(); - }); - - test( - 'fetch', - () async { - final mark = DateTime.now(); - expect( - FirebaseRemoteConfig.instance.lastFetchTime.isBefore(mark), - true, - ); - - await FirebaseRemoteConfig.instance.fetchAndActivate(); - - expect( - FirebaseRemoteConfig.instance.lastFetchStatus, - RemoteConfigFetchStatus.success, - ); - expect( - FirebaseRemoteConfig.instance.lastFetchTime.isAfter(mark), - true, - ); - expect( - FirebaseRemoteConfig.instance.getString('string'), - 'flutterfire', - ); - expect(FirebaseRemoteConfig.instance.getBool('bool'), isTrue); - expect(FirebaseRemoteConfig.instance.getInt('int'), 123); - expect(FirebaseRemoteConfig.instance.getDouble('double'), 123.456); - expect( - FirebaseRemoteConfig.instance.getValue('string').source, - ValueSource.valueRemote, - ); - - expect( - FirebaseRemoteConfig.instance.getString('hello'), - 'default hello', - ); - expect( - FirebaseRemoteConfig.instance.getValue('hello').source, - ValueSource.valueDefault, - ); - - expect(FirebaseRemoteConfig.instance.getInt('nonexisting'), 0); - - expect( - FirebaseRemoteConfig.instance.getValue('nonexisting').source, - ValueSource.valueStatic, - ); - - expect( - FirebaseRemoteConfig.instance.getAll(), - isA>(), - ); - }, - // iOS v9.2.0 hangs on ci if `fetchAndActivate()` is used, but works locally. - // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 - skip: defaultTargetPlatform == TargetPlatform.iOS || - defaultTargetPlatform == TargetPlatform.macOS, + } on FirebaseException catch (e) { + if (e.code != 'duplicate-app') { + rethrow; + } + } + await FirebaseRemoteConfig.instance.setConfigSettings( + RemoteConfigSettings( + fetchTimeout: const Duration(seconds: 8), + minimumFetchInterval: Duration.zero, + ), ); + await FirebaseRemoteConfig.instance.setDefaults({ + 'hello': 'default hello', + }); + await FirebaseRemoteConfig.instance.ensureInitialized(); + }); - test('settings', () async { + test( + 'fetch', + () async { + final mark = DateTime.now(); expect( - FirebaseRemoteConfig.instance.settings.fetchTimeout, - const Duration(seconds: 8), + FirebaseRemoteConfig.instance.lastFetchTime.isBefore(mark), + true, ); + + await FirebaseRemoteConfig.instance.fetchAndActivate(); + expect( - FirebaseRemoteConfig.instance.settings.minimumFetchInterval, - Duration.zero, - ); - await FirebaseRemoteConfig.instance.setConfigSettings( - RemoteConfigSettings( - fetchTimeout: Duration.zero, - minimumFetchInterval: const Duration(seconds: 88), - ), + FirebaseRemoteConfig.instance.lastFetchStatus, + RemoteConfigFetchStatus.success, ); + expect(FirebaseRemoteConfig.instance.lastFetchTime.isAfter(mark), true); expect( - FirebaseRemoteConfig.instance.settings.fetchTimeout, - const Duration(seconds: 60), + FirebaseRemoteConfig.instance.getString('string'), + 'flutterfire', ); + expect(FirebaseRemoteConfig.instance.getBool('bool'), isTrue); + expect(FirebaseRemoteConfig.instance.getInt('int'), 123); + expect(FirebaseRemoteConfig.instance.getDouble('double'), 123.456); expect( - FirebaseRemoteConfig.instance.settings.minimumFetchInterval, - const Duration(seconds: 88), - ); - await FirebaseRemoteConfig.instance.setConfigSettings( - RemoteConfigSettings( - fetchTimeout: const Duration(seconds: 10), - minimumFetchInterval: Duration.zero, - ), + FirebaseRemoteConfig.instance.getValue('string').source, + ValueSource.valueRemote, ); + expect( - FirebaseRemoteConfig.instance.settings.fetchTimeout, - const Duration(seconds: 10), + FirebaseRemoteConfig.instance.getString('hello'), + 'default hello', ); expect( - FirebaseRemoteConfig.instance.settings.minimumFetchInterval, - Duration.zero, + FirebaseRemoteConfig.instance.getValue('hello').source, + ValueSource.valueDefault, ); - }); - // We cannot change the default values on the fly, so we only test the - // EventChannel here. - test( - 'onConfigUpdated can run without issue', - () async { - final configSubscription = - FirebaseRemoteConfig.instance.onConfigUpdated.listen((event) {}); + expect(FirebaseRemoteConfig.instance.getInt('nonexisting'), 0); - await configSubscription.cancel(); - }, - ); - - test('default values', () async { - // Ensure that the default values are returned when no values are set. - // - // We test this to be sure that the behaviour is consistent across - // platforms. - expect(FirebaseRemoteConfig.instance.getString('does-not-exist'), ''); expect( - FirebaseRemoteConfig.instance.getBool('does-not-exist'), - isFalse, + FirebaseRemoteConfig.instance.getValue('nonexisting').source, + ValueSource.valueStatic, ); - expect(FirebaseRemoteConfig.instance.getInt('does-not-exist'), 0); - expect(FirebaseRemoteConfig.instance.getDouble('does-not-exist'), 0.0); - }); - test( - 'getAll() returns without throwing', - () async { - try { - await FirebaseRemoteConfig.instance.fetchAndActivate(); - FirebaseRemoteConfig.instance.getAll(); - } on UnimplementedError catch (e) { - fail('getAll() threw an exception: $e'); - } - }, - skip: !kIsWeb, + expect( + FirebaseRemoteConfig.instance.getAll(), + isA>(), + ); + }, + // iOS v9.2.0 hangs on ci if `fetchAndActivate()` is used, but works locally. + // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 + skip: + defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS, + ); + + test('settings', () async { + expect( + FirebaseRemoteConfig.instance.settings.fetchTimeout, + const Duration(seconds: 8), + ); + expect( + FirebaseRemoteConfig.instance.settings.minimumFetchInterval, + Duration.zero, + ); + await FirebaseRemoteConfig.instance.setConfigSettings( + RemoteConfigSettings( + fetchTimeout: Duration.zero, + minimumFetchInterval: const Duration(seconds: 88), + ), + ); + expect( + FirebaseRemoteConfig.instance.settings.fetchTimeout, + const Duration(seconds: 60), + ); + expect( + FirebaseRemoteConfig.instance.settings.minimumFetchInterval, + const Duration(seconds: 88), + ); + await FirebaseRemoteConfig.instance.setConfigSettings( + RemoteConfigSettings( + fetchTimeout: const Duration(seconds: 10), + minimumFetchInterval: Duration.zero, + ), + ); + expect( + FirebaseRemoteConfig.instance.settings.fetchTimeout, + const Duration(seconds: 10), + ); + expect( + FirebaseRemoteConfig.instance.settings.minimumFetchInterval, + Duration.zero, ); + }); + + // We cannot change the default values on the fly, so we only test the + // EventChannel here. + test('onConfigUpdated can run without issue', () async { + final configSubscription = FirebaseRemoteConfig.instance.onConfigUpdated + .listen((event) {}); + + await configSubscription.cancel(); + }); + + test('default values', () async { + // Ensure that the default values are returned when no values are set. + // + // We test this to be sure that the behaviour is consistent across + // platforms. + expect(FirebaseRemoteConfig.instance.getString('does-not-exist'), ''); + expect(FirebaseRemoteConfig.instance.getBool('does-not-exist'), isFalse); + expect(FirebaseRemoteConfig.instance.getInt('does-not-exist'), 0); + expect(FirebaseRemoteConfig.instance.getDouble('does-not-exist'), 0.0); + }); + + test('getAll() returns without throwing', () async { + try { + await FirebaseRemoteConfig.instance.fetchAndActivate(); + FirebaseRemoteConfig.instance.getAll(); + } on UnimplementedError catch (e) { + fail('getAll() threw an exception: $e'); + } + }, skip: !kIsWeb); + + group('setCustomSignals()', () { + test('valid signal values; `string`, `number` & `null`', () async { + const signals = { + 'signal1': 'string', + 'signal2': 204953, + 'signal3': 3.24, + 'signal4': null, + }; + + await FirebaseRemoteConfig.instance.setCustomSignals(signals); + }, skip: defaultTargetPlatform == TargetPlatform.windows); + + test('invalid signal values throws assertion', () async { + const signals = {'signal1': true}; + + await expectLater( + () => FirebaseRemoteConfig.instance.setCustomSignals(signals), + throwsA(isA()), + ); + + const signals2 = { + 'signal1': [1, 2, 3], + }; - group('setCustomSignals()', () { - test( - 'valid signal values; `string`, `number` & `null`', - () async { - const signals = { - 'signal1': 'string', - 'signal2': 204953, - 'signal3': 3.24, - 'signal4': null, - }; - - await FirebaseRemoteConfig.instance.setCustomSignals(signals); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, + await expectLater( + () => FirebaseRemoteConfig.instance.setCustomSignals(signals2), + throwsA(isA()), ); - test('invalid signal values throws assertion', () async { - const signals = { - 'signal1': true, - }; - - await expectLater( - () => FirebaseRemoteConfig.instance.setCustomSignals(signals), - throwsA(isA()), - ); - - const signals2 = { - 'signal1': [1, 2, 3], - }; - - await expectLater( - () => FirebaseRemoteConfig.instance.setCustomSignals(signals2), - throwsA(isA()), - ); - - const signals3 = { - 'signal1': {'key': 'value'}, - }; - - await expectLater( - () => FirebaseRemoteConfig.instance.setCustomSignals(signals3), - throwsA(isA()), - ); - - const signals4 = { - 'signal1': false, - }; - - await expectLater( - () => FirebaseRemoteConfig.instance.setCustomSignals(signals4), - throwsA(isA()), - ); - }); + const signals3 = { + 'signal1': {'key': 'value'}, + }; + + await expectLater( + () => FirebaseRemoteConfig.instance.setCustomSignals(signals3), + throwsA(isA()), + ); + + const signals4 = {'signal1': false}; + + await expectLater( + () => FirebaseRemoteConfig.instance.setCustomSignals(signals4), + throwsA(isA()), + ); }); - }, - ); + }); + }); } diff --git a/packages/firebase_remote_config/firebase_remote_config/example/integration_test/report_test_results.dart b/packages/firebase_remote_config/firebase_remote_config/example/integration_test/report_test_results.dart index 038d20c39931..416b8cd76dd0 100644 --- a/packages/firebase_remote_config/firebase_remote_config/example/integration_test/report_test_results.dart +++ b/packages/firebase_remote_config/firebase_remote_config/example/integration_test/report_test_results.dart @@ -26,8 +26,9 @@ void reportTestResultsToDriver(IntegrationTestWidgetsFlutterBinding binding) { for (final entry in binding.results.entries) if (entry.value is Failure) entry.key, ]; - bool didFail(String name) => failures - .any((failure) => name == failure || name.endsWith(' $failure')); + bool didFail(String name) => failures.any( + (failure) => name == failure || name.endsWith(' $failure'), + ); binding.reportData ??= {}; binding.reportData!['testResults'] = { diff --git a/packages/firebase_remote_config/firebase_remote_config/example/lib/firebase_options.dart b/packages/firebase_remote_config/firebase_remote_config/example/lib/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/firebase_remote_config/firebase_remote_config/example/lib/firebase_options.dart +++ b/packages/firebase_remote_config/firebase_remote_config/example/lib/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/firebase_remote_config/firebase_remote_config/example/lib/home_page.dart b/packages/firebase_remote_config/firebase_remote_config/example/lib/home_page.dart index dacdfdc8c61a..b56b2fc1bcff 100644 --- a/packages/firebase_remote_config/firebase_remote_config/example/lib/home_page.dart +++ b/packages/firebase_remote_config/firebase_remote_config/example/lib/home_page.dart @@ -21,9 +21,7 @@ class _HomePageState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: const Text('Remote Config Example'), - ), + appBar: AppBar(title: const Text('Remote Config Example')), body: Column( children: [ _ButtonAndText( @@ -110,8 +108,9 @@ class _HomePageState extends State { return 'Listening cancelled'; } setState(() { - subscription = - remoteConfig.onConfigUpdated.listen((event) async { + subscription = remoteConfig.onConfigUpdated.listen(( + event, + ) async { // Make new values available to the app. await remoteConfig.activate(); diff --git a/packages/firebase_remote_config/firebase_remote_config/example/lib/main.dart b/packages/firebase_remote_config/firebase_remote_config/example/lib/main.dart index 0978d942d2d2..4f7932ff79b0 100644 --- a/packages/firebase_remote_config/firebase_remote_config/example/lib/main.dart +++ b/packages/firebase_remote_config/firebase_remote_config/example/lib/main.dart @@ -10,9 +10,7 @@ import 'firebase_options.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); + await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); runApp(const RemoteConfigApp()); } @@ -24,10 +22,7 @@ class RemoteConfigApp extends StatelessWidget { return MaterialApp( title: 'Remote Config Example', home: const HomePage(), - theme: ThemeData( - useMaterial3: true, - primarySwatch: Colors.blue, - ), + theme: ThemeData(useMaterial3: true, primarySwatch: Colors.blue), ); } } diff --git a/packages/firebase_remote_config/firebase_remote_config/example/pubspec.yaml b/packages/firebase_remote_config/firebase_remote_config/example/pubspec.yaml index 12d04f7d69e7..6029dd993291 100644 --- a/packages/firebase_remote_config/firebase_remote_config/example/pubspec.yaml +++ b/packages/firebase_remote_config/firebase_remote_config/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the firebase_remote_config plugin. resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: # The following adds the Cupertino Icons font to your application. diff --git a/packages/firebase_remote_config/firebase_remote_config/example/test_driver/integration_test.dart b/packages/firebase_remote_config/firebase_remote_config/example/test_driver/integration_test.dart index 691723cbbfe1..9ccbcc26ab97 100644 --- a/packages/firebase_remote_config/firebase_remote_config/example/test_driver/integration_test.dart +++ b/packages/firebase_remote_config/firebase_remote_config/example/test_driver/integration_test.dart @@ -7,28 +7,32 @@ import 'dart:io'; import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver( - writeResponseOnFailure: true, - responseDataCallback: (Map? data) async { - final results = - (data?['testResults'] as Map?)?.cast() ?? - const {}; - var passed = 0; - var failed = 0; - for (final entry in results.entries) { - final ok = entry.value == 'success'; - ok ? passed++ : failed++; - // ignore: avoid_print - print('${ok ? '✅' : '❌'} ${entry.key}'); - } - // ignore: avoid_print - print('Web e2e summary: $passed passed, $failed failed, ' - '${results.length} total'); - if (results.isEmpty) { - // ignore: avoid_print - print('[E] No tests reported by the app - treating as ' - 'infrastructure failure.'); - exit(1); - } - await writeResponseData(data); - }, + writeResponseOnFailure: true, + responseDataCallback: (Map? data) async { + final results = + (data?['testResults'] as Map?)?.cast() ?? + const {}; + var passed = 0; + var failed = 0; + for (final entry in results.entries) { + final ok = entry.value == 'success'; + ok ? passed++ : failed++; + // ignore: avoid_print + print('${ok ? '✅' : '❌'} ${entry.key}'); + } + // ignore: avoid_print + print( + 'Web e2e summary: $passed passed, $failed failed, ' + '${results.length} total', ); + if (results.isEmpty) { + // ignore: avoid_print + print( + '[E] No tests reported by the app - treating as ' + 'infrastructure failure.', + ); + exit(1); + } + await writeResponseData(data); + }, +); diff --git a/packages/firebase_remote_config/firebase_remote_config/lib/src/firebase_remote_config.dart b/packages/firebase_remote_config/firebase_remote_config/lib/src/firebase_remote_config.dart index cd63529b539f..bfa1e1b3892b 100644 --- a/packages/firebase_remote_config/firebase_remote_config/lib/src/firebase_remote_config.dart +++ b/packages/firebase_remote_config/firebase_remote_config/lib/src/firebase_remote_config.dart @@ -11,11 +11,11 @@ part of '../firebase_remote_config.dart'; // ignore: prefer_mixin class FirebaseRemoteConfig extends FirebasePlugin { FirebaseRemoteConfig._({required this.app}) - : super(app.name, 'plugins.flutter.io/firebase_remote_config'); + : super(app.name, 'plugins.flutter.io/firebase_remote_config'); // Cached instances of [FirebaseRemoteConfig]. static final Map - _firebaseRemoteConfigInstances = {}; + _firebaseRemoteConfigInstances = {}; /// Returns the underlying delegate implementation. /// diff --git a/packages/firebase_remote_config/firebase_remote_config/pubspec.yaml b/packages/firebase_remote_config/firebase_remote_config/pubspec.yaml index 0840a7cf47bc..01177582452a 100644 --- a/packages/firebase_remote_config/firebase_remote_config/pubspec.yaml +++ b/packages/firebase_remote_config/firebase_remote_config/pubspec.yaml @@ -16,8 +16,8 @@ false_secrets: - example/** environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core: ^4.14.0 diff --git a/packages/firebase_remote_config/firebase_remote_config/test/firebase_remote_config_test.dart b/packages/firebase_remote_config/firebase_remote_config/test/firebase_remote_config_test.dart index e9021c16db0d..7a9e946cbb8e 100644 --- a/packages/firebase_remote_config/firebase_remote_config/test/firebase_remote_config_test.dart +++ b/packages/firebase_remote_config/firebase_remote_config/test/firebase_remote_config_test.dart @@ -53,9 +53,7 @@ void main() { ).thenAnswer((_) => mockRemoteConfigPlatform); when( - mockRemoteConfigPlatform.delegateFor( - app: anyNamed('app'), - ), + mockRemoteConfigPlatform.delegateFor(app: anyNamed('app')), ).thenAnswer((_) => mockRemoteConfigPlatform); when( @@ -64,28 +62,35 @@ void main() { ), ).thenAnswer((_) => mockRemoteConfigPlatform); - when(mockRemoteConfigPlatform.lastFetchTime) - .thenReturn(mockLastFetchTime); + when( + mockRemoteConfigPlatform.lastFetchTime, + ).thenReturn(mockLastFetchTime); - when(mockRemoteConfigPlatform.lastFetchStatus) - .thenReturn(mockLastFetchStatus); + when( + mockRemoteConfigPlatform.lastFetchStatus, + ).thenReturn(mockLastFetchStatus); - when(mockRemoteConfigPlatform.settings) - .thenReturn(mockRemoteConfigSettings); + when( + mockRemoteConfigPlatform.settings, + ).thenReturn(mockRemoteConfigSettings); - when(mockRemoteConfigPlatform.setConfigSettings(any)) - .thenAnswer((_) => Future.value()); + when( + mockRemoteConfigPlatform.setConfigSettings(any), + ).thenAnswer((_) => Future.value()); - when(mockRemoteConfigPlatform.activate()) - .thenAnswer((_) => Future.value(true)); + when( + mockRemoteConfigPlatform.activate(), + ).thenAnswer((_) => Future.value(true)); - when(mockRemoteConfigPlatform.ensureInitialized()) - .thenAnswer((_) => Future.value()); + when( + mockRemoteConfigPlatform.ensureInitialized(), + ).thenAnswer((_) => Future.value()); when(mockRemoteConfigPlatform.fetch()).thenAnswer((_) => Future.value()); - when(mockRemoteConfigPlatform.fetchAndActivate()) - .thenAnswer((_) => Future.value(true)); + when( + mockRemoteConfigPlatform.fetchAndActivate(), + ).thenAnswer((_) => Future.value(true)); when(mockRemoteConfigPlatform.getAll()).thenReturn(mockParameters); @@ -97,11 +102,13 @@ void main() { when(mockRemoteConfigPlatform.getString('foo')).thenReturn('bar'); - when(mockRemoteConfigPlatform.getValue('foo')) - .thenReturn(mockRemoteConfigValue); + when( + mockRemoteConfigPlatform.getValue('foo'), + ).thenReturn(mockRemoteConfigValue); - when(mockRemoteConfigPlatform.setDefaults(any)) - .thenAnswer((_) => Future.value()); + when( + mockRemoteConfigPlatform.setDefaults(any), + ).thenAnswer((_) => Future.value()); }); test('doubleInstance', () async { @@ -236,8 +243,7 @@ class MockFirebaseRemoteConfig extends Mock with // ignore: prefer_mixin MockPlatformInterfaceMixin - implements - TestFirebaseRemoteConfigPlatform { + implements TestFirebaseRemoteConfigPlatform { MockFirebaseRemoteConfig() { TestFirebaseRemoteConfigPlatform(); } @@ -254,11 +260,9 @@ class MockFirebaseRemoteConfig extends Mock @override FirebaseRemoteConfigPlatform setInitialValues({Map? remoteConfigValues}) { return super.noSuchMethod( - Invocation.method( - #setInitialValues, - [], - {#remoteConfigValues: remoteConfigValues}, - ), + Invocation.method(#setInitialValues, [], { + #remoteConfigValues: remoteConfigValues, + }), returnValue: TestFirebaseRemoteConfigPlatform(), returnValueForMissingStub: TestFirebaseRemoteConfigPlatform(), ); @@ -367,10 +371,7 @@ class MockFirebaseRemoteConfig extends Mock RemoteConfigValue getValue(String key) { return super.noSuchMethod( Invocation.method(#getValue, [key]), - returnValue: RemoteConfigValue( - [], - ValueSource.valueStatic, - ), + returnValue: RemoteConfigValue([], ValueSource.valueStatic), returnValueForMissingStub: RemoteConfigValue( [], ValueSource.valueStatic, diff --git a/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/method_channel_firebase_remote_config.dart b/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/method_channel_firebase_remote_config.dart index c7a072189d78..dacd5fa6cc62 100644 --- a/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/method_channel_firebase_remote_config.dart +++ b/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/method_channel_firebase_remote_config.dart @@ -16,7 +16,7 @@ import 'utils/exception.dart'; class MethodChannelFirebaseRemoteConfig extends FirebaseRemoteConfigPlatform { /// Creates a new instance for a given [FirebaseApp]. MethodChannelFirebaseRemoteConfig({required FirebaseApp app}) - : super(appInstance: app); + : super(appInstance: app); /// Internal stub class initializer. /// @@ -31,11 +31,12 @@ class MethodChannelFirebaseRemoteConfig extends FirebaseRemoteConfigPlatform { static int get nextMethodChannelHandleId => _methodChannelHandleId++; /// The [MethodChannelRemoteConfig] method channel. - static const MethodChannel channel = - MethodChannel('plugins.flutter.io/firebase_remote_config'); + static const MethodChannel channel = MethodChannel( + 'plugins.flutter.io/firebase_remote_config', + ); static Map - _methodChannelFirebaseRemoteConfigInstances = + _methodChannelFirebaseRemoteConfigInstances = {}; /// Returns a stub instance to allow the platform interface to access @@ -67,10 +68,12 @@ class MethodChannelFirebaseRemoteConfig extends FirebaseRemoteConfigPlatform { FirebaseRemoteConfigPlatform setInitialValues({ required Map remoteConfigValues, }) { - final fetchTimeout = - Duration(seconds: remoteConfigValues['fetchTimeout'] ?? 60); - final minimumFetchInterval = - Duration(seconds: remoteConfigValues['minimumFetchInterval'] ?? 43200); + final fetchTimeout = Duration( + seconds: remoteConfigValues['fetchTimeout'] ?? 60, + ); + final minimumFetchInterval = Duration( + seconds: remoteConfigValues['minimumFetchInterval'] ?? 43200, + ); final lastFetchMillis = remoteConfigValues['lastFetchTime'] ?? 0; final lastFetchStatus = remoteConfigValues['lastFetchStatus']; @@ -80,8 +83,9 @@ class MethodChannelFirebaseRemoteConfig extends FirebaseRemoteConfigPlatform { ); _lastFetchTime = DateTime.fromMillisecondsSinceEpoch(lastFetchMillis); _lastFetchStatus = _parseFetchStatus(lastFetchStatus); - _activeParameters = - _parseParameters(remoteConfigValues['parameters'] ?? {}); + _activeParameters = _parseParameters( + remoteConfigValues['parameters'] ?? {}, + ); return this; } @@ -238,8 +242,9 @@ class MethodChannelFirebaseRemoteConfig extends FirebaseRemoteConfigPlatform { Future _updateConfigProperties() async { Map properties = await _api.getProperties(app.name); final fetchTimeout = Duration(seconds: properties['fetchTimeout']); - final minimumFetchInterval = - Duration(seconds: properties['minimumFetchInterval']); + final minimumFetchInterval = Duration( + seconds: properties['minimumFetchInterval'], + ); final lastFetchMillis = properties['lastFetchTime']; final lastFetchStatus = properties['lastFetchStatus']; @@ -252,12 +257,15 @@ class MethodChannelFirebaseRemoteConfig extends FirebaseRemoteConfigPlatform { } Map _parseParameters( - Map rawParameters) { + Map rawParameters, + ) { var parameters = {}; for (final key in rawParameters.keys) { final rawValue = rawParameters[key]; parameters[key] = RemoteConfigValue( - rawValue['value'], _parseValueSource(rawValue['source'])); + rawValue['value'], + _parseValueSource(rawValue['source']), + ); } return parameters; } @@ -275,20 +283,20 @@ class MethodChannelFirebaseRemoteConfig extends FirebaseRemoteConfigPlatform { } } - static const EventChannel _eventChannelConfigUpdated = - EventChannel('plugins.flutter.io/firebase_remote_config_updated'); + static const EventChannel _eventChannelConfigUpdated = EventChannel( + 'plugins.flutter.io/firebase_remote_config_updated', + ); Stream? _onConfigUpdatedStream; @override Stream get onConfigUpdated { - _onConfigUpdatedStream ??= - _eventChannelConfigUpdated.receiveBroadcastStream({ - 'appName': app.name, - }).map((event) { - final updatedKeys = Set.from(event); - return RemoteConfigUpdate(updatedKeys); - }); + _onConfigUpdatedStream ??= _eventChannelConfigUpdated + .receiveBroadcastStream({'appName': app.name}) + .map((event) { + final updatedKeys = Set.from(event); + return RemoteConfigUpdate(updatedKeys); + }); return _onConfigUpdatedStream!; } diff --git a/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/utils/exception.dart index 08b5c69f0c6c..9e8eddea3ae9 100644 --- a/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/utils/exception.dart @@ -21,9 +21,9 @@ Never convertPlatformException(Object exception, StackTrace stackTrace) { if (exception is PlatformException) { final FirebaseException firebaseException = platformExceptionToFirebaseException( - exception, - plugin: 'firebase_remote_config', - ); + exception, + plugin: 'firebase_remote_config', + ); final String code = refineRemoteConfigErrorCode( firebaseException.code, diff --git a/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/pigeon/messages.pigeon.dart b/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/pigeon/messages.pigeon.dart index f1d5c1686e7d..f87191b0922d 100644 --- a/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/pigeon/messages.pigeon.dart +++ b/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/pigeon/messages.pigeon.dart @@ -49,8 +49,9 @@ bool _deepEquals(Object? a, Object? b) { } if (a is List && b is List) { return a.length == b.length && - a.indexed - .every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1])); + a.indexed.every( + ((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]), + ); } if (a is Map && b is Map) { if (a.length != b.length) { @@ -110,10 +111,7 @@ class RemoteConfigPigeonSettings { int minimumFetchIntervalSeconds; List _toList() { - return [ - fetchTimeoutSeconds, - minimumFetchIntervalSeconds, - ]; + return [fetchTimeoutSeconds, minimumFetchIntervalSeconds]; } Object encode() { @@ -140,7 +138,9 @@ class RemoteConfigPigeonSettings { } return _deepEquals(fetchTimeoutSeconds, other.fetchTimeoutSeconds) && _deepEquals( - minimumFetchIntervalSeconds, other.minimumFetchIntervalSeconds); + minimumFetchIntervalSeconds, + other.minimumFetchIntervalSeconds, + ); } @override @@ -178,11 +178,13 @@ class FirebaseRemoteConfigHostApi { /// Constructor for [FirebaseRemoteConfigHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - FirebaseRemoteConfigHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + FirebaseRemoteConfigHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -197,8 +199,9 @@ class FirebaseRemoteConfigHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -216,8 +219,9 @@ class FirebaseRemoteConfigHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -236,8 +240,9 @@ class FirebaseRemoteConfigHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -249,7 +254,9 @@ class FirebaseRemoteConfigHostApi { } Future setConfigSettings( - String appName, RemoteConfigPigeonSettings settings) async { + String appName, + RemoteConfigPigeonSettings settings, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_remote_config_platform_interface.FirebaseRemoteConfigHostApi.setConfigSettings$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -257,8 +264,9 @@ class FirebaseRemoteConfigHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName, settings]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName, settings], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -269,7 +277,9 @@ class FirebaseRemoteConfigHostApi { } Future setDefaults( - String appName, Map defaultParameters) async { + String appName, + Map defaultParameters, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_remote_config_platform_interface.FirebaseRemoteConfigHostApi.setDefaults$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -277,8 +287,9 @@ class FirebaseRemoteConfigHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName, defaultParameters]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName, defaultParameters], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -296,8 +307,9 @@ class FirebaseRemoteConfigHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -308,7 +320,9 @@ class FirebaseRemoteConfigHostApi { } Future setCustomSignals( - String appName, Map customSignals) async { + String appName, + Map customSignals, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_remote_config_platform_interface.FirebaseRemoteConfigHostApi.setCustomSignals$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -316,8 +330,9 @@ class FirebaseRemoteConfigHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName, customSignals]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName, customSignals], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -335,8 +350,9 @@ class FirebaseRemoteConfigHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -356,8 +372,9 @@ class FirebaseRemoteConfigHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([appName]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [appName], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( diff --git a/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/remote_config_status.dart b/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/remote_config_status.dart index bccb35a2bf93..0c613670f60e 100644 --- a/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/remote_config_status.dart +++ b/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/remote_config_status.dart @@ -16,5 +16,5 @@ enum RemoteConfigFetchStatus { failure, /// Indicates the last fetch attempt was rate-limited. - throttle + throttle, } diff --git a/packages/firebase_remote_config/firebase_remote_config_platform_interface/pubspec.yaml b/packages/firebase_remote_config/firebase_remote_config_platform_interface/pubspec.yaml index 05b4643668ef..e8971671ab20 100644 --- a/packages/firebase_remote_config/firebase_remote_config_platform_interface/pubspec.yaml +++ b/packages/firebase_remote_config/firebase_remote_config_platform_interface/pubspec.yaml @@ -8,8 +8,8 @@ version: 3.0.7 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_remote_config/firebase_remote_config_platform_interface/test/method_channel/method_channel_firebase_remote_config_test.dart b/packages/firebase_remote_config/firebase_remote_config_platform_interface/test/method_channel/method_channel_firebase_remote_config_test.dart index 74e0e4f2eeb9..f7cbcf3a8298 100644 --- a/packages/firebase_remote_config/firebase_remote_config_platform_interface/test/method_channel/method_channel_firebase_remote_config_test.dart +++ b/packages/firebase_remote_config/firebase_remote_config_platform_interface/test/method_channel/method_channel_firebase_remote_config_test.dart @@ -8,12 +8,10 @@ import 'package:flutter_test/flutter_test.dart'; void main() { test('parses native throttled fetch status', () { - final remoteConfig = - MethodChannelFirebaseRemoteConfig.instance.setInitialValues( - remoteConfigValues: { - 'lastFetchStatus': 'throttled', - }, - ); + final remoteConfig = MethodChannelFirebaseRemoteConfig.instance + .setInitialValues( + remoteConfigValues: {'lastFetchStatus': 'throttled'}, + ); expect(remoteConfig.lastFetchStatus, RemoteConfigFetchStatus.throttle); }); diff --git a/packages/firebase_remote_config/firebase_remote_config_web/lib/firebase_remote_config_web.dart b/packages/firebase_remote_config/firebase_remote_config_web/lib/firebase_remote_config_web.dart index acd1da819b82..b8580af570b2 100644 --- a/packages/firebase_remote_config/firebase_remote_config_web/lib/firebase_remote_config_web.dart +++ b/packages/firebase_remote_config/firebase_remote_config_web/lib/firebase_remote_config_web.dart @@ -24,8 +24,8 @@ class FirebaseRemoteConfigWeb extends FirebaseRemoteConfigPlatform { /// Stub initializer to allow the [registerWith] to create an instance without /// registering the web delegates or listeners. FirebaseRemoteConfigWeb._() - : _webRemoteConfig = null, - super(appInstance: null); + : _webRemoteConfig = null, + super(appInstance: null); /// Instance of functions from the web plugin remote_config_interop.RemoteConfig? _webRemoteConfig; @@ -190,8 +190,9 @@ class FirebaseRemoteConfigWeb extends FirebaseRemoteConfigPlatform { @override Stream get onConfigUpdated { - return _delegate.onConfigUpdated - .map((event) => RemoteConfigUpdate(event.updatedKeys)); + return _delegate.onConfigUpdated.map( + (event) => RemoteConfigUpdate(event.updatedKeys), + ); } @override diff --git a/packages/firebase_remote_config/firebase_remote_config_web/lib/src/interop/firebase_remote_config.dart b/packages/firebase_remote_config/firebase_remote_config_web/lib/src/interop/firebase_remote_config.dart index 045409fd398a..b7ee1c046338 100644 --- a/packages/firebase_remote_config/firebase_remote_config_web/lib/src/interop/firebase_remote_config.dart +++ b/packages/firebase_remote_config/firebase_remote_config_web/lib/src/interop/firebase_remote_config.dart @@ -28,11 +28,10 @@ class RemoteConfig static RemoteConfig getInstance( remote_config_interop.RemoteConfigJsImpl jsObject, - ) => - _expando[jsObject] ??= RemoteConfig._fromJsObject(jsObject); + ) => _expando[jsObject] ??= RemoteConfig._fromJsObject(jsObject); RemoteConfig._fromJsObject(remote_config_interop.RemoteConfigJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); /// Defines configuration for the Remote Config SDK. RemoteConfigSettings get settings => @@ -51,8 +50,8 @@ class RemoteConfig /// remoteConfig.defaultConfig['x'] = 1; // Runtime error: attempt to modify an unmodifiable map. /// ``` Map get defaultConfig => Map.unmodifiable( - jsObject.defaultConfig.dartify()! as Map, - ); + jsObject.defaultConfig.dartify()! as Map, + ); set defaultConfig(Map value) { jsObject.defaultConfig = value.jsify()! as JSObject; @@ -100,16 +99,17 @@ class RemoteConfig /// Performs fetch and activate operations, as a convenience. /// Returns a promise which resolves to true if the current call activated the fetched configs. /// If the fetched configs were already activated, the promise will resolve to false. - Future fetchAndActivate() async => - remote_config_interop.fetchAndActivate(jsObject).toDart.then( - (value) => value.toDart, - ); + Future fetchAndActivate() async => remote_config_interop + .fetchAndActivate(jsObject) + .toDart + .then((value) => value.toDart); /// Returns all config values. Map getAll() { // Return type is Map - final map = remote_config_interop.getAll(jsObject).dartify()! - as Map; + final map = + remote_config_interop.getAll(jsObject).dartify()! + as Map; // Cast the map to to mirror expected return type: Record; final castMap = map.cast(); final entries = castMap.keys.map>( @@ -119,13 +119,13 @@ class RemoteConfig } RemoteConfigValue getValue(String key) => RemoteConfigValue( - utf8.encode( - remote_config_interop.getValue(jsObject, key.toJS).asString().toDart, - ), - getSource( - remote_config_interop.getValue(jsObject, key.toJS).getSource().toDart, - ), - ); + utf8.encode( + remote_config_interop.getValue(jsObject, key.toJS).asString().toDart, + ), + getSource( + remote_config_interop.getValue(jsObject, key.toJS).getSource().toDart, + ), + ); /// Gets the value for the given key as a boolean. /// Convenience method for calling `remoteConfig.getValue(key).asString()`. @@ -149,8 +149,7 @@ class RemoteConfig RemoteConfigLogLevel.debug: 'debug', RemoteConfigLogLevel.error: 'error', RemoteConfigLogLevel.silent: 'silent', - }[value]! - .toJS, + }[value]!.toJS, ); } @@ -171,14 +170,15 @@ class RemoteConfig }; final nextWrapper = (remote_config_interop.ConfigUpdateJsImpl configUpdate) { - _onConfigUpdatedController - ?.add(RemoteConfigUpdatePayload._fromJsObject(configUpdate)); - }; + _onConfigUpdatedController?.add( + RemoteConfigUpdatePayload._fromJsObject(configUpdate), + ); + }; remote_config_interop.ConfigUpdateObserver observer = remote_config_interop.ConfigUpdateObserver( - error: errorWrapper.toJS, - next: nextWrapper.toJS, - ); + error: errorWrapper.toJS, + next: nextWrapper.toJS, + ); remote_config_interop.onConfigUpdate(jsObject, observer); } @@ -242,11 +242,7 @@ enum RemoteConfigFetchStatus { } /// Defines levels of Remote Config logging. -enum RemoteConfigLogLevel { - debug, - error, - silent, -} +enum RemoteConfigLogLevel { debug, error, silent } class RemoteConfigUpdatePayload extends JsObjectWrapper { diff --git a/packages/firebase_remote_config/firebase_remote_config_web/pubspec.yaml b/packages/firebase_remote_config/firebase_remote_config_web/pubspec.yaml index 5dac09c20c0c..51ea4ec88476 100644 --- a/packages/firebase_remote_config/firebase_remote_config_web/pubspec.yaml +++ b/packages/firebase_remote_config/firebase_remote_config_web/pubspec.yaml @@ -7,8 +7,8 @@ version: 1.10.14 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.22.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_remote_config/firebase_remote_config_web/test/firebase_remote_config_web_test.dart b/packages/firebase_remote_config/firebase_remote_config_web/test/firebase_remote_config_web_test.dart index ba0822a26718..2691ddc84837 100644 --- a/packages/firebase_remote_config/firebase_remote_config_web/test/firebase_remote_config_web_test.dart +++ b/packages/firebase_remote_config/firebase_remote_config_web/test/firebase_remote_config_web_test.dart @@ -24,8 +24,9 @@ void main() { test('setInitialValues', () { final remoteConfigValues = {'a': 'b'}; remoteConfig.setInitialValues(remoteConfigValues: remoteConfigValues); - verify(remoteConfig.setInitialValues( - remoteConfigValues: remoteConfigValues)); + verify( + remoteConfig.setInitialValues(remoteConfigValues: remoteConfigValues), + ); verifyNoMoreInteractions(remoteConfig); }); @@ -96,8 +97,10 @@ void main() { test('setConfigSettings', () { const time = Duration(milliseconds: 1000); - RemoteConfigSettings settings = - RemoteConfigSettings(fetchTimeout: time, minimumFetchInterval: time); + RemoteConfigSettings settings = RemoteConfigSettings( + fetchTimeout: time, + minimumFetchInterval: time, + ); remoteConfig.setConfigSettings(settings); verify(remoteConfig.setConfigSettings(settings)); verifyNoMoreInteractions(remoteConfig); diff --git a/packages/firebase_remote_config/firebase_remote_config_web/test/firebase_remote_config_web_test.mocks.dart b/packages/firebase_remote_config/firebase_remote_config_web/test/firebase_remote_config_web_test.mocks.dart index f4654bc554d4..ccb245f20d5c 100644 --- a/packages/firebase_remote_config/firebase_remote_config_web/test/firebase_remote_config_web_test.mocks.dart +++ b/packages/firebase_remote_config/firebase_remote_config_web/test/firebase_remote_config_web_test.mocks.dart @@ -27,34 +27,19 @@ import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: subtype_of_sealed_class class _FakeDateTime_0 extends _i1.SmartFake implements DateTime { - _FakeDateTime_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeDateTime_0(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeRemoteConfigSettings_1 extends _i1.SmartFake implements _i2.RemoteConfigSettings { - _FakeRemoteConfigSettings_1( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeRemoteConfigSettings_1(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeFirebaseApp_2 extends _i1.SmartFake implements _i3.FirebaseApp { - _FakeFirebaseApp_2( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeFirebaseApp_2(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } class _FakeFirebaseRemoteConfigPlatform_3 extends _i1.SmartFake @@ -62,21 +47,13 @@ class _FakeFirebaseRemoteConfigPlatform_3 extends _i1.SmartFake _FakeFirebaseRemoteConfigPlatform_3( Object parent, Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + ) : super(parent, parentInvocation); } class _FakeRemoteConfigValue_4 extends _i1.SmartFake implements _i2.RemoteConfigValue { - _FakeRemoteConfigValue_4( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); + _FakeRemoteConfigValue_4(Object parent, Invocation parentInvocation) + : super(parent, parentInvocation); } /// A class which mocks [FirebaseRemoteConfigWeb]. @@ -85,225 +62,199 @@ class _FakeRemoteConfigValue_4 extends _i1.SmartFake class MockFirebaseRemoteConfigWeb extends _i1.Mock implements _i4.FirebaseRemoteConfigWeb { @override - DateTime get lastFetchTime => (super.noSuchMethod( - Invocation.getter(#lastFetchTime), - returnValue: _FakeDateTime_0( - this, - Invocation.getter(#lastFetchTime), - ), - returnValueForMissingStub: _FakeDateTime_0( - this, - Invocation.getter(#lastFetchTime), - ), - ) as DateTime); + DateTime get lastFetchTime => + (super.noSuchMethod( + Invocation.getter(#lastFetchTime), + returnValue: _FakeDateTime_0( + this, + Invocation.getter(#lastFetchTime), + ), + returnValueForMissingStub: _FakeDateTime_0( + this, + Invocation.getter(#lastFetchTime), + ), + ) + as DateTime); @override - _i2.RemoteConfigFetchStatus get lastFetchStatus => (super.noSuchMethod( - Invocation.getter(#lastFetchStatus), - returnValue: _i2.RemoteConfigFetchStatus.noFetchYet, - returnValueForMissingStub: _i2.RemoteConfigFetchStatus.noFetchYet, - ) as _i2.RemoteConfigFetchStatus); + _i2.RemoteConfigFetchStatus get lastFetchStatus => + (super.noSuchMethod( + Invocation.getter(#lastFetchStatus), + returnValue: _i2.RemoteConfigFetchStatus.noFetchYet, + returnValueForMissingStub: _i2.RemoteConfigFetchStatus.noFetchYet, + ) + as _i2.RemoteConfigFetchStatus); @override - _i2.RemoteConfigSettings get settings => (super.noSuchMethod( - Invocation.getter(#settings), - returnValue: _FakeRemoteConfigSettings_1( - this, - Invocation.getter(#settings), - ), - returnValueForMissingStub: _FakeRemoteConfigSettings_1( - this, - Invocation.getter(#settings), - ), - ) as _i2.RemoteConfigSettings); + _i2.RemoteConfigSettings get settings => + (super.noSuchMethod( + Invocation.getter(#settings), + returnValue: _FakeRemoteConfigSettings_1( + this, + Invocation.getter(#settings), + ), + returnValueForMissingStub: _FakeRemoteConfigSettings_1( + this, + Invocation.getter(#settings), + ), + ) + as _i2.RemoteConfigSettings); @override - _i5.Stream<_i2.RemoteConfigUpdate> get onConfigUpdated => (super.noSuchMethod( - Invocation.getter(#onConfigUpdated), - returnValue: _i5.Stream<_i2.RemoteConfigUpdate>.empty(), - returnValueForMissingStub: _i5.Stream<_i2.RemoteConfigUpdate>.empty(), - ) as _i5.Stream<_i2.RemoteConfigUpdate>); + _i5.Stream<_i2.RemoteConfigUpdate> get onConfigUpdated => + (super.noSuchMethod( + Invocation.getter(#onConfigUpdated), + returnValue: _i5.Stream<_i2.RemoteConfigUpdate>.empty(), + returnValueForMissingStub: + _i5.Stream<_i2.RemoteConfigUpdate>.empty(), + ) + as _i5.Stream<_i2.RemoteConfigUpdate>); @override - _i3.FirebaseApp get app => (super.noSuchMethod( - Invocation.getter(#app), - returnValue: _FakeFirebaseApp_2( - this, - Invocation.getter(#app), - ), - returnValueForMissingStub: _FakeFirebaseApp_2( - this, - Invocation.getter(#app), - ), - ) as _i3.FirebaseApp); + _i3.FirebaseApp get app => + (super.noSuchMethod( + Invocation.getter(#app), + returnValue: _FakeFirebaseApp_2(this, Invocation.getter(#app)), + returnValueForMissingStub: _FakeFirebaseApp_2( + this, + Invocation.getter(#app), + ), + ) + as _i3.FirebaseApp); @override _i2.FirebaseRemoteConfigPlatform delegateFor({_i3.FirebaseApp? app}) => (super.noSuchMethod( - Invocation.method( - #delegateFor, - [], - {#app: app}, - ), - returnValue: _FakeFirebaseRemoteConfigPlatform_3( - this, - Invocation.method( - #delegateFor, - [], - {#app: app}, - ), - ), - returnValueForMissingStub: _FakeFirebaseRemoteConfigPlatform_3( - this, - Invocation.method( - #delegateFor, - [], - {#app: app}, - ), - ), - ) as _i2.FirebaseRemoteConfigPlatform); + Invocation.method(#delegateFor, [], {#app: app}), + returnValue: _FakeFirebaseRemoteConfigPlatform_3( + this, + Invocation.method(#delegateFor, [], {#app: app}), + ), + returnValueForMissingStub: _FakeFirebaseRemoteConfigPlatform_3( + this, + Invocation.method(#delegateFor, [], {#app: app}), + ), + ) + as _i2.FirebaseRemoteConfigPlatform); @override - _i2.FirebaseRemoteConfigPlatform setInitialValues( - {required Map? remoteConfigValues}) => + _i2.FirebaseRemoteConfigPlatform setInitialValues({ + required Map? remoteConfigValues, + }) => (super.noSuchMethod( - Invocation.method( - #setInitialValues, - [], - {#remoteConfigValues: remoteConfigValues}, - ), - returnValue: _FakeFirebaseRemoteConfigPlatform_3( - this, - Invocation.method( - #setInitialValues, - [], - {#remoteConfigValues: remoteConfigValues}, - ), - ), - returnValueForMissingStub: _FakeFirebaseRemoteConfigPlatform_3( - this, - Invocation.method( - #setInitialValues, - [], - {#remoteConfigValues: remoteConfigValues}, - ), - ), - ) as _i2.FirebaseRemoteConfigPlatform); + Invocation.method(#setInitialValues, [], { + #remoteConfigValues: remoteConfigValues, + }), + returnValue: _FakeFirebaseRemoteConfigPlatform_3( + this, + Invocation.method(#setInitialValues, [], { + #remoteConfigValues: remoteConfigValues, + }), + ), + returnValueForMissingStub: _FakeFirebaseRemoteConfigPlatform_3( + this, + Invocation.method(#setInitialValues, [], { + #remoteConfigValues: remoteConfigValues, + }), + ), + ) + as _i2.FirebaseRemoteConfigPlatform); @override - _i5.Future activate() => (super.noSuchMethod( - Invocation.method( - #activate, - [], - ), - returnValue: _i5.Future.value(false), - returnValueForMissingStub: _i5.Future.value(false), - ) as _i5.Future); + _i5.Future activate() => + (super.noSuchMethod( + Invocation.method(#activate, []), + returnValue: _i5.Future.value(false), + returnValueForMissingStub: _i5.Future.value(false), + ) + as _i5.Future); @override - _i5.Future ensureInitialized() => (super.noSuchMethod( - Invocation.method( - #ensureInitialized, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + _i5.Future ensureInitialized() => + (super.noSuchMethod( + Invocation.method(#ensureInitialized, []), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override - _i5.Future fetch() => (super.noSuchMethod( - Invocation.method( - #fetch, - [], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + _i5.Future fetch() => + (super.noSuchMethod( + Invocation.method(#fetch, []), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override - _i5.Future fetchAndActivate() => (super.noSuchMethod( - Invocation.method( - #fetchAndActivate, - [], - ), - returnValue: _i5.Future.value(false), - returnValueForMissingStub: _i5.Future.value(false), - ) as _i5.Future); + _i5.Future fetchAndActivate() => + (super.noSuchMethod( + Invocation.method(#fetchAndActivate, []), + returnValue: _i5.Future.value(false), + returnValueForMissingStub: _i5.Future.value(false), + ) + as _i5.Future); @override - Map getAll() => (super.noSuchMethod( - Invocation.method( - #getAll, - [], - ), - returnValue: {}, - returnValueForMissingStub: {}, - ) as Map); + Map getAll() => + (super.noSuchMethod( + Invocation.method(#getAll, []), + returnValue: {}, + returnValueForMissingStub: {}, + ) + as Map); @override - bool getBool(String? key) => (super.noSuchMethod( - Invocation.method( - #getBool, - [key], - ), - returnValue: false, - returnValueForMissingStub: false, - ) as bool); + bool getBool(String? key) => + (super.noSuchMethod( + Invocation.method(#getBool, [key]), + returnValue: false, + returnValueForMissingStub: false, + ) + as bool); @override - int getInt(String? key) => (super.noSuchMethod( - Invocation.method( - #getInt, - [key], - ), - returnValue: 0, - returnValueForMissingStub: 0, - ) as int); + int getInt(String? key) => + (super.noSuchMethod( + Invocation.method(#getInt, [key]), + returnValue: 0, + returnValueForMissingStub: 0, + ) + as int); @override - double getDouble(String? key) => (super.noSuchMethod( - Invocation.method( - #getDouble, - [key], - ), - returnValue: 0.0, - returnValueForMissingStub: 0.0, - ) as double); + double getDouble(String? key) => + (super.noSuchMethod( + Invocation.method(#getDouble, [key]), + returnValue: 0.0, + returnValueForMissingStub: 0.0, + ) + as double); @override - String getString(String? key) => (super.noSuchMethod( - Invocation.method( - #getString, - [key], - ), - returnValue: '', - returnValueForMissingStub: '', - ) as String); + String getString(String? key) => + (super.noSuchMethod( + Invocation.method(#getString, [key]), + returnValue: '', + returnValueForMissingStub: '', + ) + as String); @override - _i2.RemoteConfigValue getValue(String? key) => (super.noSuchMethod( - Invocation.method( - #getValue, - [key], - ), - returnValue: _FakeRemoteConfigValue_4( - this, - Invocation.method( - #getValue, - [key], - ), - ), - returnValueForMissingStub: _FakeRemoteConfigValue_4( - this, - Invocation.method( - #getValue, - [key], - ), - ), - ) as _i2.RemoteConfigValue); + _i2.RemoteConfigValue getValue(String? key) => + (super.noSuchMethod( + Invocation.method(#getValue, [key]), + returnValue: _FakeRemoteConfigValue_4( + this, + Invocation.method(#getValue, [key]), + ), + returnValueForMissingStub: _FakeRemoteConfigValue_4( + this, + Invocation.method(#getValue, [key]), + ), + ) + as _i2.RemoteConfigValue); @override _i5.Future setConfigSettings( - _i2.RemoteConfigSettings? remoteConfigSettings) => + _i2.RemoteConfigSettings? remoteConfigSettings, + ) => (super.noSuchMethod( - Invocation.method( - #setConfigSettings, - [remoteConfigSettings], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#setConfigSettings, [remoteConfigSettings]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); @override _i5.Future setDefaults(Map? defaultParameters) => (super.noSuchMethod( - Invocation.method( - #setDefaults, - [defaultParameters], - ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + Invocation.method(#setDefaults, [defaultParameters]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); } diff --git a/packages/firebase_storage/firebase_storage/example/integration_test/e2e_test.dart b/packages/firebase_storage/firebase_storage/example/integration_test/e2e_test.dart index 31581c7afceb..bf158e4727b1 100644 --- a/packages/firebase_storage/firebase_storage/example/integration_test/e2e_test.dart +++ b/packages/firebase_storage/firebase_storage/example/integration_test/e2e_test.dart @@ -35,8 +35,10 @@ void main() { rethrow; } } - await FirebaseStorage.instance - .useStorageEmulator(testEmulatorHost, testEmulatorPort); + await FirebaseStorage.instance.useStorageEmulator( + testEmulatorHost, + testEmulatorPort, + ); // Add a write only file await FirebaseStorage.instance diff --git a/packages/firebase_storage/firebase_storage/example/integration_test/instance_e2e.dart b/packages/firebase_storage/firebase_storage/example/integration_test/instance_e2e.dart index c95803302aae..3c9106074b13 100644 --- a/packages/firebase_storage/firebase_storage/example/integration_test/instance_e2e.dart +++ b/packages/firebase_storage/firebase_storage/example/integration_test/instance_e2e.dart @@ -30,32 +30,30 @@ void setupInstanceTests() { }); test('instanceFor', () { - FirebaseStorage secondaryStorage = - FirebaseStorage.instanceFor(app: secondaryApp, bucket: 'test'); + FirebaseStorage secondaryStorage = FirebaseStorage.instanceFor( + app: secondaryApp, + bucket: 'test', + ); expect(storage.app, isA()); expect(secondaryStorage, isA()); expect(secondaryStorage.app.name, 'testapp'); }); - test( - 'default bucket cannot be null', - () async { - try { - secondaryAppWithoutBucket = - await testInitializeSecondaryApp(withDefaultBucket: false); + test('default bucket cannot be null', () async { + try { + secondaryAppWithoutBucket = await testInitializeSecondaryApp( + withDefaultBucket: false, + ); - FirebaseStorage.instanceFor( - app: secondaryAppWithoutBucket, - ); - fail('should have thrown an error'); - } on FirebaseException catch (e) { - expect( - e.message, - "No storage bucket could be found for the app 'testapp-no-bucket'. Ensure you have set the [storageBucket] on [FirebaseOptions] whilst initializing the secondary Firebase app.", - ); - } - }, - ); + FirebaseStorage.instanceFor(app: secondaryAppWithoutBucket); + fail('should have thrown an error'); + } on FirebaseException catch (e) { + expect( + e.message, + "No storage bucket could be found for the app 'testapp-no-bucket'. Ensure you have set the [storageBucket] on [FirebaseOptions] whilst initializing the secondary Firebase app.", + ); + } + }); group('ref', () { test('uses default path if none provided', () { @@ -183,22 +181,24 @@ void setupInstanceTests() { expect(ref.fullPath, '/'); }); - test('throws an error if url does not start with gs:// or https://', - () async { - expect( - () { - storage.refFromURL('bs://foo/bar/cat.gif'); - fail('Should have thrown an [AssertionError]'); - }, - throwsA( - isA().having( - (p0) => p0.message, - 'assertion message', - contains("a url must start with 'gs://' or 'https://'"), + test( + 'throws an error if url does not start with gs:// or https://', + () async { + expect( + () { + storage.refFromURL('bs://foo/bar/cat.gif'); + fail('Should have thrown an [AssertionError]'); + }, + throwsA( + isA().having( + (p0) => p0.message, + 'assertion message', + contains("a url must start with 'gs://' or 'https://'"), + ), ), - ), - ); - }); + ); + }, + ); }); group('setMaxOperationRetryTime', () { diff --git a/packages/firebase_storage/firebase_storage/example/integration_test/list_result_e2e.dart b/packages/firebase_storage/firebase_storage/example/integration_test/list_result_e2e.dart index 66b1d38c8a70..3d90bd821c4d 100644 --- a/packages/firebase_storage/firebase_storage/example/integration_test/list_result_e2e.dart +++ b/packages/firebase_storage/firebase_storage/example/integration_test/list_result_e2e.dart @@ -7,35 +7,31 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/foundation.dart'; void setupListResultTests() { - group( - '$ListResult', - () { - late FirebaseStorage storage; - late ListResult result; + group('$ListResult', () { + late FirebaseStorage storage; + late ListResult result; - setUpAll(() async { - storage = FirebaseStorage.instance; - Reference ref = storage.ref('flutter-tests/list'); - // Needs to be > half of the # of items in the storage, - // so there's a chance of picking up some items and some - // prefixes. - result = await ref.list(const ListOptions(maxResults: 3)); - }); + setUpAll(() async { + storage = FirebaseStorage.instance; + Reference ref = storage.ref('flutter-tests/list'); + // Needs to be > half of the # of items in the storage, + // so there's a chance of picking up some items and some + // prefixes. + result = await ref.list(const ListOptions(maxResults: 3)); + }); - test('items', () async { - expect(result.items, isA>()); - expect(result.items.length, greaterThan(0)); - }); + test('items', () async { + expect(result.items, isA>()); + expect(result.items.length, greaterThan(0)); + }); - test('nextPageToken', () async { - expect(result.nextPageToken, isNotNull); - }); + test('nextPageToken', () async { + expect(result.nextPageToken, isNotNull); + }); - test('prefixes', () async { - expect(result.prefixes, isA>()); - expect(result.prefixes.length, greaterThan(0)); - }); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + test('prefixes', () async { + expect(result.prefixes, isA>()); + expect(result.prefixes.length, greaterThan(0)); + }); + }, skip: defaultTargetPlatform == TargetPlatform.windows); } diff --git a/packages/firebase_storage/firebase_storage/example/integration_test/reference_e2e.dart b/packages/firebase_storage/firebase_storage/example/integration_test/reference_e2e.dart index 5b382fb03767..7bd2891825c6 100644 --- a/packages/firebase_storage/firebase_storage/example/integration_test/reference_e2e.dart +++ b/packages/firebase_storage/firebase_storage/example/integration_test/reference_e2e.dart @@ -146,7 +146,8 @@ void setupReferenceTests() { }, // Fails on emulator since iOS SDK 10. See PR notes: // https://github.com/firebase/flutterfire/pull/9708 - skip: defaultTargetPlatform == TargetPlatform.iOS || + skip: + defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS, ); @@ -185,44 +186,40 @@ void setupReferenceTests() { }); }); - group( - 'list', - () { - test('returns list results', () async { - Reference ref = storage.ref('flutter-tests/list'); - ListResult result = await ref.list(const ListOptions(maxResults: 25)); - - expect(result.items.length, greaterThan(0)); - expect(result.prefixes, isA>()); - expect(result.prefixes.length, greaterThan(0)); - }); - - test('errors if maxResults is less than 0 ', () async { - Reference ref = storage.ref('/list'); - expect( - () => ref.list(const ListOptions(maxResults: -1)), - throwsAssertionError, - ); - }); + group('list', () { + test('returns list results', () async { + Reference ref = storage.ref('flutter-tests/list'); + ListResult result = await ref.list(const ListOptions(maxResults: 25)); - test('errors if maxResults is 0 ', () async { - Reference ref = storage.ref('/list'); - expect( - () => ref.list(const ListOptions(maxResults: 0)), - throwsAssertionError, - ); - }); + expect(result.items.length, greaterThan(0)); + expect(result.prefixes, isA>()); + expect(result.prefixes.length, greaterThan(0)); + }); - test('errors if maxResults is more than 1000 ', () async { - Reference ref = storage.ref('/list'); - expect( - () => ref.list(const ListOptions(maxResults: 1001)), - throwsAssertionError, - ); - }); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + test('errors if maxResults is less than 0 ', () async { + Reference ref = storage.ref('/list'); + expect( + () => ref.list(const ListOptions(maxResults: -1)), + throwsAssertionError, + ); + }); + + test('errors if maxResults is 0 ', () async { + Reference ref = storage.ref('/list'); + expect( + () => ref.list(const ListOptions(maxResults: 0)), + throwsAssertionError, + ); + }); + + test('errors if maxResults is more than 1000 ', () async { + Reference ref = storage.ref('/list'); + expect( + () => ref.list(const ListOptions(maxResults: 1001)), + throwsAssertionError, + ); + }); + }, skip: defaultTargetPlatform == TargetPlatform.windows); test( 'list operations report that they are unsupported on Windows', @@ -246,139 +243,127 @@ void setupReferenceTests() { skip: defaultTargetPlatform != TargetPlatform.windows, ); - test( - 'listAll', - () async { - Reference ref = storage.ref('flutter-tests/list'); - ListResult result = await ref.listAll(); - expect(result.items, isNotNull); - expect(result.items.length, greaterThan(0)); - expect(result.nextPageToken, isNull); + test('listAll', () async { + Reference ref = storage.ref('flutter-tests/list'); + ListResult result = await ref.listAll(); + expect(result.items, isNotNull); + expect(result.items.length, greaterThan(0)); + expect(result.nextPageToken, isNull); - expect(result.prefixes, isA>()); - expect(result.prefixes.length, greaterThan(0)); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + expect(result.prefixes, isA>()); + expect(result.prefixes.length, greaterThan(0)); + }, skip: defaultTargetPlatform == TargetPlatform.windows); - group( - 'putData', - () { - test( - 'uploads a file with buffer and download to check content matches', - () async { - const text = - 'put data text to compare with uploaded and downloaded'; - List list = utf8.encode(text); + group('putData', () { + test( + 'uploads a file with buffer and download to check content matches', + () async { + const text = 'put data text to compare with uploaded and downloaded'; + List list = utf8.encode(text); - Uint8List data = Uint8List.fromList(list); + Uint8List data = Uint8List.fromList(list); - final Reference ref = - storage.ref('flutter-tests').child('flt-put-data.txt'); + final Reference ref = storage + .ref('flutter-tests') + .child('flt-put-data.txt'); - final TaskSnapshot complete = await ref.putData( - data, - SettableMetadata( - contentLanguage: 'en', - ), - ); + final TaskSnapshot complete = await ref.putData( + data, + SettableMetadata(contentLanguage: 'en'), + ); - expect(complete.metadata?.size, text.length); - expect(complete.metadata?.contentLanguage, 'en'); + expect(complete.metadata?.size, text.length); + expect(complete.metadata?.contentLanguage, 'en'); - // Download the file from Firebase Storage - final downloadedData = await ref.getData(); - final downloadedContent = String.fromCharCodes(downloadedData!); + // Download the file from Firebase Storage + final downloadedData = await ref.getData(); + final downloadedContent = String.fromCharCodes(downloadedData!); - // Verify that the downloaded content matches the original content - expect(downloadedContent, equals(text)); - }, - ); + // Verify that the downloaded content matches the original content + expect(downloadedContent, equals(text)); + }, + ); - //TODO(pr-mais): causes the emulator to crash - // test('errors if permission denied', () async { - // List list = utf8.encode('hello world'); - // Uint8List data = Uint8List.fromList(list); + //TODO(pr-mais): causes the emulator to crash + // test('errors if permission denied', () async { + // List list = utf8.encode('hello world'); + // Uint8List data = Uint8List.fromList(list); - // final Reference ref = storage.ref('/uploadNope.jpeg'); + // final Reference ref = storage.ref('/uploadNope.jpeg'); - // await expectLater( - // () => ref.putData(data), - // throwsA(isA() - // .having((e) => e.code, 'code', 'unauthorized') - // .having((e) => e.message, 'message', - // 'User is not authorized to perform the desired action.'))); - // }); + // await expectLater( + // () => ref.putData(data), + // throwsA(isA() + // .having((e) => e.code, 'code', 'unauthorized') + // .having((e) => e.message, 'message', + // 'User is not authorized to perform the desired action.'))); + // }); - test( - 'upload a json file', - () async { - final Map data = { - 'name': 'John Doe', - 'age': 30, - }; - final Uint8List jsonData = utf8.encode(jsonEncode(data)); - final Reference ref = - storage.ref('flutter-tests').child('flt-web-ok.json'); - final TaskSnapshot complete = await ref.putData( - jsonData, - SettableMetadata( - contentType: 'application/json', - ), - ); - expect(complete.metadata?.contentType, 'application/json'); - }, + test('upload a json file', () async { + final Map data = { + 'name': 'John Doe', + 'age': 30, + }; + final Uint8List jsonData = utf8.encode(jsonEncode(data)); + final Reference ref = storage + .ref('flutter-tests') + .child('flt-web-ok.json'); + final TaskSnapshot complete = await ref.putData( + jsonData, + SettableMetadata(contentType: 'application/json'), ); + expect(complete.metadata?.contentType, 'application/json'); + }); - test( - 'infers contentType from .json ref path when no contentType set', - () async { - final Uint8List jsonData = - utf8.encode(jsonEncode({'key': 'value'})); - final Reference ref = - storage.ref('flutter-tests').child('flt-infer.json'); - final TaskSnapshot complete = await ref.putData(jsonData); - expect(complete.metadata?.contentType, 'application/json'); - }, - ); + test( + 'infers contentType from .json ref path when no contentType set', + () async { + final Uint8List jsonData = utf8.encode(jsonEncode({'key': 'value'})); + final Reference ref = storage + .ref('flutter-tests') + .child('flt-infer.json'); + final TaskSnapshot complete = await ref.putData(jsonData); + expect(complete.metadata?.contentType, 'application/json'); + }, + ); - test( - 'infers contentType from .txt ref path and preserves customMetadata', - () async { - final Uint8List txtData = utf8.encode('hello world'); - final Reference ref = - storage.ref('flutter-tests').child('flt-infer.txt'); - final TaskSnapshot complete = await ref.putData( - txtData, - SettableMetadata( - customMetadata: {'activity': 'test'}, - ), - ); - expect(complete.metadata?.contentType, 'text/plain'); - expect(complete.metadata?.customMetadata?['activity'], 'test'); - }, - ); + test( + 'infers contentType from .txt ref path and preserves customMetadata', + () async { + final Uint8List txtData = utf8.encode('hello world'); + final Reference ref = storage + .ref('flutter-tests') + .child('flt-infer.txt'); + final TaskSnapshot complete = await ref.putData( + txtData, + SettableMetadata(customMetadata: {'activity': 'test'}), + ); + expect(complete.metadata?.contentType, 'text/plain'); + expect(complete.metadata?.customMetadata?['activity'], 'test'); + }, + ); - test( - 'infers contentType from .jpg ref path when no metadata provided', - () async { - final Uint8List imgData = Uint8List.fromList([0xFF, 0xD8, 0xFF]); - final Reference ref = - storage.ref('flutter-tests').child('flt-infer.jpg'); - final TaskSnapshot complete = await ref.putData(imgData); - expect(complete.metadata?.contentType, 'image/jpeg'); - }, - ); - }, - ); + test( + 'infers contentType from .jpg ref path when no metadata provided', + () async { + final Uint8List imgData = Uint8List.fromList([0xFF, 0xD8, 0xFF]); + final Reference ref = storage + .ref('flutter-tests') + .child('flt-infer.jpg'); + final TaskSnapshot complete = await ref.putData(imgData); + expect(complete.metadata?.contentType, 'image/jpeg'); + }, + ); + }); group('putBlob', () { test( 'throws [UnimplementedError] for native platforms', () async { final File file = await createFile('flt-put-blob.txt'); - final Reference ref = - storage.ref('flutter-tests').child('flt-put-blob.txt'); + final Reference ref = storage + .ref('flutter-tests') + .child('flt-put-blob.txt'); await expectLater( () => ref.putBlob( @@ -413,8 +398,9 @@ void setupReferenceTests() { string: kTestString, ); - final Reference ref = - storage.ref('flutter-tests').child('flt-put-file.txt'); + final Reference ref = storage + .ref('flutter-tests') + .child('flt-put-file.txt'); final TaskSnapshot complete = await ref.putFile( file, @@ -430,11 +416,10 @@ void setupReferenceTests() { expect(complete.metadata?.customMetadata!['activity'], 'test'); expect(complete.metadata?.contentType, 'text/plain'); // Check without SettableMetadata - final Reference ref2 = - storage.ref('flutter-tests').child('flt-ok-2.txt'); - final TaskSnapshot complete2 = await ref2.putFile( - file, - ); + final Reference ref2 = storage + .ref('flutter-tests') + .child('flt-ok-2.txt'); + final TaskSnapshot complete2 = await ref2.putFile(file); expect(complete2.metadata?.size, kTestString.length); expect(complete2.metadata?.customMetadata, isA()); }, @@ -442,31 +427,32 @@ void setupReferenceTests() { skip: kIsWeb, ); - test('Upload and download text file and ensure content is the same', - () async { - const text = - 'put file some text to compare with uploaded and downloaded'; - final File file = await createFile( - 'read-and-write.txt', - string: text, - ); + test( + 'Upload and download text file and ensure content is the same', + () async { + const text = + 'put file some text to compare with uploaded and downloaded'; + final File file = await createFile( + 'read-and-write.txt', + string: text, + ); - final Reference ref = - storage.ref('flutter-tests').child('read-and-write.txt'); + final Reference ref = storage + .ref('flutter-tests') + .child('read-and-write.txt'); - final TaskSnapshot complete = await ref.putFile( - file, - ); + final TaskSnapshot complete = await ref.putFile(file); - expect(complete.state, TaskState.success); + expect(complete.state, TaskState.success); - // Download the file from Firebase Storage - final downloadedData = await ref.getData(); - final downloadedContent = String.fromCharCodes(downloadedData!); + // Download the file from Firebase Storage + final downloadedData = await ref.getData(); + final downloadedContent = String.fromCharCodes(downloadedData!); - // Verify that the downloaded content matches the original content - expect(downloadedContent, equals(text)); - }); + // Verify that the downloaded content matches the original content + expect(downloadedContent, equals(text)); + }, + ); // TODO(ehesp): Emulator rules issue - comment back in once fixed // test('errors if permission denied', () async { @@ -484,7 +470,8 @@ void setupReferenceTests() { // putFile is not supported in web. // iOS & macOS work locally but times out on CI. We ought to check this periodically // as it may be OS version specific. - skip: kIsWeb || + skip: + kIsWeb || defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS, ); @@ -493,8 +480,9 @@ void setupReferenceTests() { test('uploads a string and downloads to check its content', () async { const text = 'put string some text to compare with uploaded and downloaded'; - final Reference ref = - storage.ref('flutter-tests').child('flt-put-string.txt'); + final Reference ref = storage + .ref('flutter-tests') + .child('flt-put-string.txt'); final TaskSnapshot complete = await ref.putString(text); expect(complete.totalBytes, greaterThan(0)); expect(complete.state, TaskState.success); @@ -527,21 +515,19 @@ void setupReferenceTests() { }); group('updateMetadata', () { - test( - 'updates metadata', - () async { - Reference ref = - storage.ref('flutter-tests').child('flt-update-metadata.txt'); - // Ensure the file exists before updating metadata - await ref.putString('metadata test content'); - // Verify the file is visible before updating metadata - await ref.getMetadata(); - FullMetadata fullMetadata = await ref - .updateMetadata(SettableMetadata(customMetadata: {'foo': 'bar'})); - expect(fullMetadata.customMetadata!['foo'], 'bar'); - }, - timeout: const Timeout(Duration(minutes: 2)), - ); + test('updates metadata', () async { + Reference ref = storage + .ref('flutter-tests') + .child('flt-update-metadata.txt'); + // Ensure the file exists before updating metadata + await ref.putString('metadata test content'); + // Verify the file is visible before updating metadata + await ref.getMetadata(); + FullMetadata fullMetadata = await ref.updateMetadata( + SettableMetadata(customMetadata: {'foo': 'bar'}), + ); + expect(fullMetadata.customMetadata!['foo'], 'bar'); + }, timeout: const Timeout(Duration(minutes: 2))); test( 'errors if property does not exist', @@ -565,60 +551,54 @@ void setupReferenceTests() { skip: defaultTargetPlatform == TargetPlatform.windows, ); - test( - 'errors if permission denied', - () async { - final ref = storage.ref('uploadNope.jpeg'); - await expectLater( - () => ref.updateMetadata(SettableMetadata(contentType: 'jpeg')), - throwsA( - isA() - .having((e) => e.code, 'code', 'unauthorized') - .having( - (e) => e.message, - 'message', - 'User is not authorized to perform the desired action.', - ), - ), - ); - }, - ); + test('errors if permission denied', () async { + final ref = storage.ref('uploadNope.jpeg'); + await expectLater( + () => ref.updateMetadata(SettableMetadata(contentType: 'jpeg')), + throwsA( + isA() + .having((e) => e.code, 'code', 'unauthorized') + .having( + (e) => e.message, + 'message', + 'User is not authorized to perform the desired action.', + ), + ), + ); + }); }); - group( - 'writeToFile', - () { - test('downloads a file', () async { - File file = await createFile('ok.jpeg'); - TaskSnapshot complete = - await storage.ref('flutter-tests/ok.txt').writeToFile(file); - expect(complete.bytesTransferred, complete.totalBytes); - expect(complete.state, TaskState.success); - }); - - // [TODO] This test always time out for catch the exception - // test('errors if permission denied', () async { - // File file = await createFile('not.jpeg'); - // final Reference ref = storage.ref('/nope.jpeg'); + group('writeToFile', () { + test('downloads a file', () async { + File file = await createFile('ok.jpeg'); + TaskSnapshot complete = await storage + .ref('flutter-tests/ok.txt') + .writeToFile(file); + expect(complete.bytesTransferred, complete.totalBytes); + expect(complete.state, TaskState.success); + }); - // await expectLater( - // () => ref.writeToFile(file), - // throwsA( - // isA() - // .having((e) => e.code, 'code', 'unauthorized') - // .having( - // (e) => e.message, - // 'message', - // 'User is not authorized to perform the desired action.', - // ), - // ), - // ); - // }); + // [TODO] This test always time out for catch the exception + // test('errors if permission denied', () async { + // File file = await createFile('not.jpeg'); + // final Reference ref = storage.ref('/nope.jpeg'); - // writeToFile is not supported in web - }, - skip: kIsWeb, - ); + // await expectLater( + // () => ref.writeToFile(file), + // throwsA( + // isA() + // .having((e) => e.code, 'code', 'unauthorized') + // .having( + // (e) => e.message, + // 'message', + // 'User is not authorized to perform the desired action.', + // ), + // ), + // ); + // }); + + // writeToFile is not supported in web + }, skip: kIsWeb); test('toString', () async { expect( diff --git a/packages/firebase_storage/firebase_storage/example/integration_test/report_test_results.dart b/packages/firebase_storage/firebase_storage/example/integration_test/report_test_results.dart index fb80e3ba19f7..db17f5dab066 100644 --- a/packages/firebase_storage/firebase_storage/example/integration_test/report_test_results.dart +++ b/packages/firebase_storage/firebase_storage/example/integration_test/report_test_results.dart @@ -26,8 +26,9 @@ void reportTestResultsToDriver(IntegrationTestWidgetsFlutterBinding binding) { for (final entry in binding.results.entries) if (entry.value is Failure) entry.key, ]; - bool didFail(String name) => failures - .any((failure) => name == failure || name.endsWith(' $failure')); + bool didFail(String name) => failures.any( + (failure) => name == failure || name.endsWith(' $failure'), + ); binding.reportData ??= {}; binding.reportData!['testResults'] = { diff --git a/packages/firebase_storage/firebase_storage/example/integration_test/second_bucket.dart b/packages/firebase_storage/firebase_storage/example/integration_test/second_bucket.dart index 2b20138d6f04..d375864459e0 100644 --- a/packages/firebase_storage/firebase_storage/example/integration_test/second_bucket.dart +++ b/packages/firebase_storage/firebase_storage/example/integration_test/second_bucket.dart @@ -47,10 +47,7 @@ void setupSecondBucketTests() { group('bucket', () { test('returns the storage bucket as a string', () async { - expect( - storage.ref('/ok.jpeg').bucket, - secondStorageBucket, - ); + expect(storage.ref('/ok.jpeg').bucket, secondStorageBucket); }); }); @@ -125,8 +122,9 @@ void setupSecondBucketTests() { test('throws error if no write permission', () async { // second-bucket-not-allowed.jpeg is not allowed to be deleted via storage.rules for 2nd bucket - Reference ref = - storage.ref('flutter-tests/second-bucket-not-allowed.jpeg'); + Reference ref = storage.ref( + 'flutter-tests/second-bucket-not-allowed.jpeg', + ); await expectLater( () => ref.delete(), @@ -161,7 +159,8 @@ void setupSecondBucketTests() { }, // Fails on emulator since iOS SDK 10. See PR notes: // https://github.com/firebase/flutterfire/pull/9708 - skip: defaultTargetPlatform == TargetPlatform.iOS || + skip: + defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS, ); @@ -200,81 +199,73 @@ void setupSecondBucketTests() { }); }); - group( - 'list', - () { - test('returns list results', () async { - Reference ref = storage.ref(allowableListsSecondBucket); - ListResult result = await ref.list(const ListOptions(maxResults: 25)); - expect(result.items.length, greaterThan(0)); - expect(result.prefixes, isA>()); - }); + group('list', () { + test('returns list results', () async { + Reference ref = storage.ref(allowableListsSecondBucket); + ListResult result = await ref.list(const ListOptions(maxResults: 25)); + expect(result.items.length, greaterThan(0)); + expect(result.prefixes, isA>()); + }); - test( - 'errors if permission denied', - () async { - Reference ref = storage.ref('flutter-tests'); - - await expectLater( - () => ref.list(const ListOptions(maxResults: 25)), - throwsA( - isA() - .having((e) => e.code, 'code', 'unauthorized') - .having( - (e) => e.message, - 'message', - 'User is not authorized to perform the desired action.', - ), - ), - ); - }, - // Web: Firebase JS SDK / emulator never returns the permission error, - // causing a consistent 30s timeout. - // Windows: C++ SDK / emulator does not enforce permissions for list - // operations on the second bucket (returns results instead of error). - skip: kIsWeb || defaultTargetPlatform == TargetPlatform.windows, - ); + test( + 'errors if permission denied', + () async { + Reference ref = storage.ref('flutter-tests'); - test('errors if maxResults is less than 0 ', () async { - Reference ref = storage.ref('/list'); - expect( - () => ref.list(const ListOptions(maxResults: -1)), - throwsAssertionError, + await expectLater( + () => ref.list(const ListOptions(maxResults: 25)), + throwsA( + isA() + .having((e) => e.code, 'code', 'unauthorized') + .having( + (e) => e.message, + 'message', + 'User is not authorized to perform the desired action.', + ), + ), ); - }); + }, + // Web: Firebase JS SDK / emulator never returns the permission error, + // causing a consistent 30s timeout. + // Windows: C++ SDK / emulator does not enforce permissions for list + // operations on the second bucket (returns results instead of error). + skip: kIsWeb || defaultTargetPlatform == TargetPlatform.windows, + ); - test('errors if maxResults is 0 ', () async { - Reference ref = storage.ref('/list'); - expect( - () => ref.list(const ListOptions(maxResults: 0)), - throwsAssertionError, - ); - }); + test('errors if maxResults is less than 0 ', () async { + Reference ref = storage.ref('/list'); + expect( + () => ref.list(const ListOptions(maxResults: -1)), + throwsAssertionError, + ); + }); - test('errors if maxResults is more than 1000 ', () async { - Reference ref = storage.ref('/list'); - expect( - () => ref.list(const ListOptions(maxResults: 1001)), - throwsAssertionError, - ); - }); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + test('errors if maxResults is 0 ', () async { + Reference ref = storage.ref('/list'); + expect( + () => ref.list(const ListOptions(maxResults: 0)), + throwsAssertionError, + ); + }); - test( - 'listAll', - () async { - Reference ref = storage.ref(allowableListsSecondBucket); - ListResult result = await ref.listAll(); - expect(result.items, isNotNull); - expect(result.items.length, greaterThan(0)); - expect(result.nextPageToken, isNull); + test('errors if maxResults is more than 1000 ', () async { + Reference ref = storage.ref('/list'); + expect( + () => ref.list(const ListOptions(maxResults: 1001)), + throwsAssertionError, + ); + }); + }, skip: defaultTargetPlatform == TargetPlatform.windows); - expect(result.prefixes, isA>()); - }, - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + test('listAll', () async { + Reference ref = storage.ref(allowableListsSecondBucket); + ListResult result = await ref.listAll(); + expect(result.items, isNotNull); + expect(result.items.length, greaterThan(0)); + expect(result.nextPageToken, isNull); + + expect(result.prefixes, isA>()); + }, skip: defaultTargetPlatform == TargetPlatform.windows); group( 'putData', @@ -284,14 +275,13 @@ void setupSecondBucketTests() { Uint8List data = Uint8List.fromList(list); - final Reference ref = - storage.ref('flutter-tests').child('flt-ok.txt'); + final Reference ref = storage + .ref('flutter-tests') + .child('flt-ok.txt'); final TaskSnapshot complete = await ref.putData( data, - SettableMetadata( - contentLanguage: 'en', - ), + SettableMetadata(contentLanguage: 'en'), ); expect(complete.metadata?.size, kTestString.length); @@ -324,61 +314,54 @@ void setupSecondBucketTests() { ); group('putBlob', () { - test( - 'throws [UnimplementedError] for native platforms', - () async { - final File file = await createFile('flt-ok.txt'); - final Reference ref = - storage.ref('flutter-tests').child('flt-ok.txt'); + test('throws [UnimplementedError] for native platforms', () async { + final File file = await createFile('flt-ok.txt'); + final Reference ref = storage.ref('flutter-tests').child('flt-ok.txt'); - await expectLater( - () => ref.putBlob( - file, - SettableMetadata( - contentLanguage: 'en', - customMetadata: {'activity': 'test'}, - ), + await expectLater( + () => ref.putBlob( + file, + SettableMetadata( + contentLanguage: 'en', + customMetadata: {'activity': 'test'}, ), - throwsA( - isA().having( - (e) => e.message, - 'message', - 'putBlob() is not supported on native platforms. Use [put], [putFile] or [putString] instead.', - ), + ), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'putBlob() is not supported on native platforms. Use [put], [putFile] or [putString] instead.', ), - ); + ), + ); - // This *must* be skipped in web, the test is intended for native platforms. - }, - skip: kIsWeb, - ); + // This *must* be skipped in web, the test is intended for native platforms. + }, skip: kIsWeb); }); group( 'putFile', () { - test( - 'uploads a file', - () async { - final File file = await createFile('flt-ok.txt'); - - final Reference ref = - storage.ref('flutter-tests').child('flt-ok.txt'); - - final TaskSnapshot complete = await ref.putFile( - file, - SettableMetadata( - contentLanguage: 'en', - customMetadata: {'activity': 'test'}, - ), - ); - - expect(complete.metadata?.size, kTestString.length); - // TODO - remove this note if still appplicable - Metadata isn't saved on objects when using the emulator which fails test - expect(complete.metadata?.contentLanguage, 'en'); - expect(complete.metadata?.customMetadata!['activity'], 'test'); - }, - ); + test('uploads a file', () async { + final File file = await createFile('flt-ok.txt'); + + final Reference ref = storage + .ref('flutter-tests') + .child('flt-ok.txt'); + + final TaskSnapshot complete = await ref.putFile( + file, + SettableMetadata( + contentLanguage: 'en', + customMetadata: {'activity': 'test'}, + ), + ); + + expect(complete.metadata?.size, kTestString.length); + // TODO - remove this note if still appplicable - Metadata isn't saved on objects when using the emulator which fails test + expect(complete.metadata?.contentLanguage, 'en'); + expect(complete.metadata?.customMetadata!['activity'], 'test'); + }); test('errors if permission denied', () async { File file = await createFile('flt-ok.txt'); @@ -441,13 +424,15 @@ void setupSecondBucketTests() { 'writes a file', () async { File file = await createFile('ok.txt'); - TaskSnapshot complete = - await storage.ref('flutter-tests/ok.txt').writeToFile(file); + TaskSnapshot complete = await storage + .ref('flutter-tests/ok.txt') + .writeToFile(file); expect(complete.bytesTransferred, complete.totalBytes); expect(complete.state, TaskState.success); expect(complete.ref.bucket, secondStorageBucket); }, - skip: defaultTargetPlatform == TargetPlatform.iOS || + skip: + defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS, ); }); @@ -455,8 +440,9 @@ void setupSecondBucketTests() { group('updateMetadata', () { test('updates metadata', () async { Reference ref = storage.ref('flutter-tests').child('flt-ok.txt'); - FullMetadata fullMetadata = await ref - .updateMetadata(SettableMetadata(customMetadata: {'foo': 'bar'})); + FullMetadata fullMetadata = await ref.updateMetadata( + SettableMetadata(customMetadata: {'foo': 'bar'}), + ); expect(fullMetadata.customMetadata!['foo'], 'bar'); expect(fullMetadata.bucket, secondStorageBucket); }); @@ -483,25 +469,23 @@ void setupSecondBucketTests() { skip: defaultTargetPlatform == TargetPlatform.windows, ); - test( - 'errors if permission denied', - () async { - Reference ref = - storage.ref('flutter-tests/second-bucket-not-allowed.jpeg'); - await expectLater( - () => ref.updateMetadata(SettableMetadata(contentType: 'jpeg')), - throwsA( - isA() - .having((e) => e.code, 'code', 'unauthorized') - .having( - (e) => e.message, - 'message', - 'User is not authorized to perform the desired action.', - ), - ), - ); - }, - ); + test('errors if permission denied', () async { + Reference ref = storage.ref( + 'flutter-tests/second-bucket-not-allowed.jpeg', + ); + await expectLater( + () => ref.updateMetadata(SettableMetadata(contentType: 'jpeg')), + throwsA( + isA() + .having((e) => e.code, 'code', 'unauthorized') + .having( + (e) => e.message, + 'message', + 'User is not authorized to perform the desired action.', + ), + ), + ); + }); }); }); } diff --git a/packages/firebase_storage/firebase_storage/example/integration_test/task_e2e.dart b/packages/firebase_storage/firebase_storage/example/integration_test/task_e2e.dart index 63ce457576ab..203f9fd355e8 100644 --- a/packages/firebase_storage/firebase_storage/example/integration_test/task_e2e.dart +++ b/packages/firebase_storage/firebase_storage/example/integration_test/task_e2e.dart @@ -107,15 +107,17 @@ void setupTaskTests() { file = await createFile('ok.jpeg'); task = downloadRef.writeToFile(file); } else { - task = downloadRef - .putBlob(createBlob('some content to write to blob')); + task = downloadRef.putBlob( + createBlob('some content to write to blob'), + ); } await _testPauseTask('Download'); }, retry: 2, // TODO(russellwheatley): Windows works on example app, but fails on tests. // Clue is in bytesTransferred + totalBytes which both equal: -3617008641903833651 - skip: !kIsWeb && + skip: + !kIsWeb && (defaultTargetPlatform == TargetPlatform.windows || defaultTargetPlatform == TargetPlatform.android || defaultTargetPlatform == TargetPlatform.macOS), @@ -132,7 +134,8 @@ void setupTaskTests() { // This task is flaky on mac, skip for now. // TODO(russellwheatley): Windows works on example app, but fails on tests. // Clue is in bytesTransferred + totalBytes which both equal: -3617008641903833651 - skip: !kIsWeb && + skip: + !kIsWeb && (defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.windows || defaultTargetPlatform == TargetPlatform.android), @@ -160,8 +163,9 @@ void setupTaskTests() { }, ); // Allow time for listener events to be called - FirebaseException streamError = - await errorReceived.future.timeout(_completerTimeout); + FirebaseException streamError = await errorReceived.future.timeout( + _completerTimeout, + ); expect(streamError.plugin, 'firebase_storage'); expect(streamError.code, 'unauthorized'); @@ -176,221 +180,208 @@ void setupTaskTests() { }, ); - test('handles errors, e.g. if permission denied for `await Task`', - () async { - List list = utf8.encode('hello world'); - Uint8List data = Uint8List.fromList(list); - UploadTask task = storage.ref('/uploadNope.jpeg').putData(data); - try { - await task; - } catch (e) { - expect(e, isA()); - FirebaseException exception = e as FirebaseException; - expect(exception.plugin, 'firebase_storage'); - expect(exception.code, 'unauthorized'); - expect( - exception.message, - 'User is not authorized to perform the desired action.', - ); - } - - expect(task.snapshot.state, TaskState.error); - }); - }); - - group('snapshot', () { test( - 'returns the latest snapshot for download task', + 'handles errors, e.g. if permission denied for `await Task`', () async { - Task downloadTask; - if (!kIsWeb) { - file = await createFile('ok.jpeg'); - downloadTask = downloadRef.writeToFile(file); - } else { - downloadTask = downloadRef - .putBlob(createBlob('some content to write to blob')); + List list = utf8.encode('hello world'); + Uint8List data = Uint8List.fromList(list); + UploadTask task = storage.ref('/uploadNope.jpeg').putData(data); + try { + await task; + } catch (e) { + expect(e, isA()); + FirebaseException exception = e as FirebaseException; + expect(exception.plugin, 'firebase_storage'); + expect(exception.code, 'unauthorized'); + expect( + exception.message, + 'User is not authorized to perform the desired action.', + ); } - expect(downloadTask.snapshot, isNotNull); - - TaskSnapshot completedSnapshot = await downloadTask; - final snapshot = downloadTask.snapshot; - - expect(snapshot, isA()); - expect(snapshot.state, TaskState.success); - expect(snapshot.bytesTransferred, completedSnapshot.bytesTransferred); - expect(snapshot.totalBytes, completedSnapshot.totalBytes); - expect(snapshot.metadata, isA()); + expect(task.snapshot.state, TaskState.error); }, - retry: 2, ); + }); - test( - 'returns the latest snapshot for upload task', - () async { - final uploadTask = uploadRef.putString('This is an upload task!'); - expect(uploadTask.snapshot, isNotNull); - - TaskSnapshot completedSnapshot = await uploadTask; - final snapshot = uploadTask.snapshot; - expect(snapshot, isA()); - expect(snapshot.bytesTransferred, completedSnapshot.bytesTransferred); - expect(snapshot.totalBytes, completedSnapshot.totalBytes); - expect(snapshot.metadata, isA()); - }, - retry: 2, - ); + group('snapshot', () { + test('returns the latest snapshot for download task', () async { + Task downloadTask; + if (!kIsWeb) { + file = await createFile('ok.jpeg'); + downloadTask = downloadRef.writeToFile(file); + } else { + downloadTask = downloadRef.putBlob( + createBlob('some content to write to blob'), + ); + } + + expect(downloadTask.snapshot, isNotNull); + + TaskSnapshot completedSnapshot = await downloadTask; + final snapshot = downloadTask.snapshot; + + expect(snapshot, isA()); + expect(snapshot.state, TaskState.success); + expect(snapshot.bytesTransferred, completedSnapshot.bytesTransferred); + expect(snapshot.totalBytes, completedSnapshot.totalBytes); + expect(snapshot.metadata, isA()); + }, retry: 2); + + test('returns the latest snapshot for upload task', () async { + final uploadTask = uploadRef.putString('This is an upload task!'); + expect(uploadTask.snapshot, isNotNull); + + TaskSnapshot completedSnapshot = await uploadTask; + final snapshot = uploadTask.snapshot; + expect(snapshot, isA()); + expect(snapshot.bytesTransferred, completedSnapshot.bytesTransferred); + expect(snapshot.totalBytes, completedSnapshot.totalBytes); + expect(snapshot.metadata, isA()); + }, retry: 2); }); - group( - 'cancel()', - () { - late Task task; + group('cancel()', () { + late Task task; - Future _testCancelTaskSnapshotEvents(Task task) async { - List snapshots = []; - expect(task.snapshot.state, TaskState.running); - final Completer errorReceived = - Completer(); - final Completer started = Completer(); + Future _testCancelTaskSnapshotEvents(Task task) async { + List snapshots = []; + expect(task.snapshot.state, TaskState.running); + final Completer errorReceived = + Completer(); + final Completer started = Completer(); - task.snapshotEvents.listen( - (TaskSnapshot snapshot) { - if (!started.isCompleted) { - started.complete(true); - } - snapshots.add(snapshot); - }, - onError: (error) { - errorReceived.complete(error); - }, - ); + task.snapshotEvents.listen( + (TaskSnapshot snapshot) { + if (!started.isCompleted) { + started.complete(true); + } + snapshots.add(snapshot); + }, + onError: (error) { + errorReceived.complete(error); + }, + ); - await started.future.timeout(_completerTimeout); + await started.future.timeout(_completerTimeout); - bool canceled = await task.cancel(); - expect(canceled, isTrue); - expect(task.snapshot.state, TaskState.canceled); + bool canceled = await task.cancel(); + expect(canceled, isTrue); + expect(task.snapshot.state, TaskState.canceled); - final streamError = - await errorReceived.future.timeout(_completerTimeout); + final streamError = await errorReceived.future.timeout( + _completerTimeout, + ); - expect(streamError, isNotNull); - expect(streamError.code, 'canceled'); - // Expecting there to only be running states, canceled should not get sent as an event. - expect( - snapshots.every((snapshot) => snapshot.state == TaskState.running), - isTrue, - ); + expect(streamError, isNotNull); + expect(streamError.code, 'canceled'); + // Expecting there to only be running states, canceled should not get sent as an event. + expect( + snapshots.every((snapshot) => snapshot.state == TaskState.running), + isTrue, + ); - await expectLater( - task, - throwsA( - isA() - .having((e) => e.code, 'code', 'canceled'), - ), - ); - } + await expectLater( + task, + throwsA( + isA().having((e) => e.code, 'code', 'canceled'), + ), + ); + } - Future _testCancelTaskLastEvent(Task task) async { - expect(task.snapshot.state, TaskState.running); + Future _testCancelTaskLastEvent(Task task) async { + expect(task.snapshot.state, TaskState.running); - bool canceled = await task.cancel(); - expect(canceled, isTrue); - expect(task.snapshot.state, TaskState.canceled); - } + bool canceled = await task.cancel(); + expect(canceled, isTrue); + expect(task.snapshot.state, TaskState.canceled); + } - test( - 'successfully cancels download task using snapshotEvents', - () async { - file = await createFile('ok.txt'); - // Need to put a large file in emulator first to test cancel. - final initialPut = downloadRef.putFile(file); + test( + 'successfully cancels download task using snapshotEvents', + () async { + file = await createFile('ok.txt'); + // Need to put a large file in emulator first to test cancel. + final initialPut = downloadRef.putFile(file); - await initialPut; - task = downloadRef.writeToFile(file); + await initialPut; + task = downloadRef.writeToFile(file); - await _testCancelTaskSnapshotEvents(task); - }, - // There's no DownloadTask on web. - // Windows `task.cancel()` is returning "false", same code on example app works as intended - skip: kIsWeb || defaultTargetPlatform == TargetPlatform.windows, - retry: 2, - ); + await _testCancelTaskSnapshotEvents(task); + }, + // There's no DownloadTask on web. + // Windows `task.cancel()` is returning "false", same code on example app works as intended + skip: kIsWeb || defaultTargetPlatform == TargetPlatform.windows, + retry: 2, + ); - test( - 'successfully cancels download task and provides the last `canceled` event', - () async { - file = await createFile('ok.txt'); - final initialPut = downloadRef.putFile(file); + test( + 'successfully cancels download task and provides the last `canceled` event', + () async { + file = await createFile('ok.txt'); + final initialPut = downloadRef.putFile(file); - await initialPut; - task = downloadRef.writeToFile(file); - await _testCancelTaskLastEvent(task); - }, - // There's no DownloadTask on web. - // Windows `task.cancel()` is returning "false", same code on example app works as intended - skip: kIsWeb || defaultTargetPlatform == TargetPlatform.windows, - retry: 2, - ); + await initialPut; + task = downloadRef.writeToFile(file); + await _testCancelTaskLastEvent(task); + }, + // There's no DownloadTask on web. + // Windows `task.cancel()` is returning "false", same code on example app works as intended + skip: kIsWeb || defaultTargetPlatform == TargetPlatform.windows, + retry: 2, + ); - test( - 'successfully cancels upload task using snapshotEvents', - () async { - task = uploadRef.putString('A' * 20000000); - await _testCancelTaskSnapshotEvents(task); - }, - retry: 2, - // Windows `task.cancel()` is returning "false", same code on example app works as intended - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + test( + 'successfully cancels upload task using snapshotEvents', + () async { + task = uploadRef.putString('A' * 20000000); + await _testCancelTaskSnapshotEvents(task); + }, + retry: 2, + // Windows `task.cancel()` is returning "false", same code on example app works as intended + skip: defaultTargetPlatform == TargetPlatform.windows, + ); - test( - 'successfully cancels upload task and provides the last `canceled` event', - () async { - task = uploadRef.putString('A' * 20000000); - await _testCancelTaskLastEvent(task); - }, - retry: 2, - // Windows `task.cancel()` is returning "false", same code on example app works as intended - skip: defaultTargetPlatform == TargetPlatform.windows, - ); + test( + 'successfully cancels upload task and provides the last `canceled` event', + () async { + task = uploadRef.putString('A' * 20000000); + await _testCancelTaskLastEvent(task); + }, + retry: 2, + // Windows `task.cancel()` is returning "false", same code on example app works as intended + skip: defaultTargetPlatform == TargetPlatform.windows, + ); - test( - 'cancels multiple in-progress Android tasks during core reinitialization', - () async { - final tasks = [ - for (var i = 0; i < 3; i++) - storage - .ref('flutter-tests/regression-18240-$i.txt') - .putString('A' * 20000000), - ]; - final completions = tasks - .map( - (task) => task.then( - (_) {}, - onError: (_) {}, - ), - ) - .toList(); - - try { - MethodChannelFirebase.isCoreInitialized = false; - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ).timeout(const Duration(seconds: 30)); - } finally { - MethodChannelFirebase.isCoreInitialized = true; - completions.forEach(unawaited); - } - }, - // TODO(SelaseKay): move this white-box core reinitialization - // regression to an isolated test. Forcing global core reinit in the - // shared E2E process can race unrelated plugin app lifecycle tests. - skip: true, - ); - }, - ); + test( + 'cancels multiple in-progress Android tasks during core reinitialization', + () async { + final tasks = [ + for (var i = 0; i < 3; i++) + storage + .ref('flutter-tests/regression-18240-$i.txt') + .putString('A' * 20000000), + ]; + final completions = tasks + .map((task) => task.then((_) {}, onError: (_) {})) + .toList(); + + try { + MethodChannelFirebase.isCoreInitialized = false; + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ).timeout(const Duration(seconds: 30)); + } finally { + MethodChannelFirebase.isCoreInitialized = true; + completions.forEach(unawaited); + } + }, + // TODO(SelaseKay): move this white-box core reinitialization + // regression to an isolated test. Forcing global core reinit in the + // shared E2E process can race unrelated plugin app lifecycle tests. + skip: true, + ); + }); group('snapshotEvents', () { test('loop through successful `snapshotEvents`', () async { @@ -405,8 +396,9 @@ void setupTaskTests() { test('failed `snapshotEvents` loop', () async { final snapshots = []; - UploadTask task = - storage.ref('/uploadNope.jpeg').putString('This will fail'); + UploadTask task = storage + .ref('/uploadNope.jpeg') + .putString('This will fail'); try { // ignore: prefer_foreach await for (final event in task.snapshotEvents) { @@ -424,47 +416,55 @@ void setupTaskTests() { } }); - test('listen to successful snapshotEvents, ensure `onDone` is called', - () async { - final Completer onDoneReceived = Completer(); - final snapshots = []; - final task = uploadRef.putString('This is an upload task!'); + test( + 'listen to successful snapshotEvents, ensure `onDone` is called', + () async { + final Completer onDoneReceived = Completer(); + final snapshots = []; + final task = uploadRef.putString('This is an upload task!'); - task.snapshotEvents.listen( - snapshots.add, - onDone: () { - onDoneReceived.complete(true); - }, - ); + task.snapshotEvents.listen( + snapshots.add, + onDone: () { + onDoneReceived.complete(true); + }, + ); - final response = await onDoneReceived.future.timeout(_completerTimeout); - expect(response, isTrue); - expect(snapshots.last.state, TaskState.success); - }); + final response = await onDoneReceived.future.timeout( + _completerTimeout, + ); + expect(response, isTrue); + expect(snapshots.last.state, TaskState.success); + }, + ); - test('listen to failed snapshotEvents, ensure `onDone` is called', - () async { - final snapshots = []; - final task = storage - .ref('/uploadNope.jpeg') - .putString('This is an upload task!'); - final Completer onDoneReceived = Completer(); - FirebaseException? streamError; - task.snapshotEvents.listen( - snapshots.add, - onError: (e) { - streamError = e; - }, - onDone: () { - onDoneReceived.complete(true); - }, - ); + test( + 'listen to failed snapshotEvents, ensure `onDone` is called', + () async { + final snapshots = []; + final task = storage + .ref('/uploadNope.jpeg') + .putString('This is an upload task!'); + final Completer onDoneReceived = Completer(); + FirebaseException? streamError; + task.snapshotEvents.listen( + snapshots.add, + onError: (e) { + streamError = e; + }, + onDone: () { + onDoneReceived.complete(true); + }, + ); - final response = await onDoneReceived.future.timeout(_completerTimeout); - expect(response, isTrue); - expect(snapshots.last.state, TaskState.running); - expect(streamError, isA()); - }); + final response = await onDoneReceived.future.timeout( + _completerTimeout, + ); + expect(response, isTrue); + expect(snapshots.last.state, TaskState.running); + expect(streamError, isA()); + }, + ); }); }); } diff --git a/packages/firebase_storage/firebase_storage/example/integration_test/test_utils.dart b/packages/firebase_storage/firebase_storage/example/integration_test/test_utils.dart index 819e4af1afed..50e30f39d7f4 100644 --- a/packages/firebase_storage/firebase_storage/example/integration_test/test_utils.dart +++ b/packages/firebase_storage/firebase_storage/example/integration_test/test_utils.dart @@ -16,11 +16,11 @@ const String kTestStorageBucket = 'flutterfire-e2e-tests.appspot.com'; const _chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890'; Random _random = Random(); String _getRandomString(int length) => String.fromCharCodes( - Iterable.generate( - length, - (_) => _chars.codeUnitAt(_random.nextInt(_chars.length)), - ), - ); + Iterable.generate( + length, + (_) => _chars.codeUnitAt(_random.nextInt(_chars.length)), + ), +); String get testEmulatorHost { if (defaultTargetPlatform == TargetPlatform.android && !kIsWeb) { @@ -92,8 +92,9 @@ Uint8List createBlob(String content) { Future testInitializeSecondaryApp({ bool withDefaultBucket = true, }) async { - final String testAppName = - withDefaultBucket ? 'testapp' : 'testapp-no-bucket'; + final String testAppName = withDefaultBucket + ? 'testapp' + : 'testapp-no-bucket'; FirebaseOptions testAppOptions; if (!kIsWeb && diff --git a/packages/firebase_storage/firebase_storage/example/lib/firebase_options.dart b/packages/firebase_storage/firebase_storage/example/lib/firebase_options.dart index a5a1360f6620..a73209882730 100644 --- a/packages/firebase_storage/firebase_storage/example/lib/firebase_options.dart +++ b/packages/firebase_storage/firebase_storage/example/lib/firebase_options.dart @@ -18,8 +18,8 @@ class DefaultFirebaseOptions { TargetPlatform.macOS => macos, TargetPlatform.windows => windows, _ => throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ), + 'DefaultFirebaseOptions are not supported for this platform.', + ), }; } diff --git a/packages/firebase_storage/firebase_storage/example/lib/main.dart b/packages/firebase_storage/firebase_storage/example/lib/main.dart index 927e38ffd49e..0509b4f83dda 100755 --- a/packages/firebase_storage/firebase_storage/example/lib/main.dart +++ b/packages/firebase_storage/firebase_storage/example/lib/main.dart @@ -18,16 +18,14 @@ import 'save_as/save_as.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); + await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); if (defaultTargetPlatform != TargetPlatform.windows) { // window currently don't support storage emulator final emulatorHost = (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) - ? '10.0.2.2' - : 'localhost'; + ? '10.0.2.2' + : 'localhost'; await FirebaseStorage.instance.useStorageEmulator(emulatorHost, 9199); } @@ -63,9 +61,7 @@ class StorageExampleApp extends StatelessWidget { theme: ThemeData.dark(), // Disable the banner to make the "+" button more visible. debugShowCheckedModeBanner: false, - home: Scaffold( - body: TaskManager(), - ), + home: Scaffold(body: TaskManager()), ); } } @@ -87,11 +83,9 @@ class _TaskManager extends State { /// The user selects a file, and the task is added to the list. Future uploadFile(XFile? file) async { if (file == null) { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('No file was selected'), - ), - ); + ScaffoldMessenger.of( + context, + ).showSnackBar(const SnackBar(content: Text('No file was selected'))); return null; } @@ -203,17 +197,11 @@ class _TaskManager extends State { Future _downloadLink(Reference ref) async { final link = await ref.getDownloadURL(); - await Clipboard.setData( - ClipboardData( - text: link, - ), - ); + await Clipboard.setData(ClipboardData(text: link)); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( - content: Text( - 'Success!\n Copied download URL to Clipboard!', - ), + content: Text('Success!\n Copied download URL to Clipboard!'), ), ); } @@ -242,8 +230,9 @@ class _TaskManager extends State { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( - 'Success!\n deleted ${ref.name} \n from bucket: ${ref.bucket}\n ' - 'at path: ${ref.fullPath} \n'), + 'Success!\n deleted ${ref.name} \n from bucket: ${ref.bucket}\n ' + 'at path: ${ref.fullPath} \n', + ), ), ); } @@ -345,72 +334,73 @@ class UploadTaskListTile extends StatelessWidget { Widget build(BuildContext context) { return StreamBuilder( stream: task.snapshotEvents, - builder: ( - BuildContext context, - AsyncSnapshot asyncSnapshot, - ) { - Widget subtitle = const Text('---'); - TaskSnapshot? snapshot = asyncSnapshot.data; - TaskState? state = snapshot?.state; - - if (asyncSnapshot.hasError) { - if (asyncSnapshot.error is FirebaseException && - // ignore: cast_nullable_to_non_nullable - (asyncSnapshot.error as FirebaseException).code == 'canceled') { - subtitle = const Text('Upload canceled.'); - } else { - // ignore: avoid_print - print(asyncSnapshot.error); - subtitle = const Text('Something went wrong.'); - } - } else if (snapshot != null) { - subtitle = Text('$state: ${_bytesTransferred(snapshot)} bytes sent'); - } - - return Dismissible( - key: Key(task.hashCode.toString()), - onDismissed: ($) => onDismissed(), - child: ListTile( - title: Text('Upload Task #${task.hashCode}'), - subtitle: subtitle, - trailing: Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (state == TaskState.running) - IconButton( - icon: const Icon(Icons.pause), - onPressed: task.pause, - ), - if (state == TaskState.running) - IconButton( - icon: const Icon(Icons.cancel), - onPressed: task.cancel, - ), - if (state == TaskState.paused) - IconButton( - icon: const Icon(Icons.file_upload), - onPressed: task.resume, - ), - if (state == TaskState.success) - IconButton( - icon: const Icon(Icons.file_download), - onPressed: onDownload, - ), - if (state == TaskState.success) - IconButton( - icon: const Icon(Icons.link), - onPressed: onDownloadLink, - ), - if (state == TaskState.success) - IconButton( - icon: const Icon(Icons.delete), - onPressed: onDelete, - ), - ], - ), - ), - ); - }, + builder: + (BuildContext context, AsyncSnapshot asyncSnapshot) { + Widget subtitle = const Text('---'); + TaskSnapshot? snapshot = asyncSnapshot.data; + TaskState? state = snapshot?.state; + + if (asyncSnapshot.hasError) { + if (asyncSnapshot.error is FirebaseException && + // ignore: cast_nullable_to_non_nullable + (asyncSnapshot.error as FirebaseException).code == + 'canceled') { + subtitle = const Text('Upload canceled.'); + } else { + // ignore: avoid_print + print(asyncSnapshot.error); + subtitle = const Text('Something went wrong.'); + } + } else if (snapshot != null) { + subtitle = Text( + '$state: ${_bytesTransferred(snapshot)} bytes sent', + ); + } + + return Dismissible( + key: Key(task.hashCode.toString()), + onDismissed: ($) => onDismissed(), + child: ListTile( + title: Text('Upload Task #${task.hashCode}'), + subtitle: subtitle, + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (state == TaskState.running) + IconButton( + icon: const Icon(Icons.pause), + onPressed: task.pause, + ), + if (state == TaskState.running) + IconButton( + icon: const Icon(Icons.cancel), + onPressed: task.cancel, + ), + if (state == TaskState.paused) + IconButton( + icon: const Icon(Icons.file_upload), + onPressed: task.resume, + ), + if (state == TaskState.success) + IconButton( + icon: const Icon(Icons.file_download), + onPressed: onDownload, + ), + if (state == TaskState.success) + IconButton( + icon: const Icon(Icons.link), + onPressed: onDownloadLink, + ), + if (state == TaskState.success) + IconButton( + icon: const Icon(Icons.delete), + onPressed: onDelete, + ), + ], + ), + ), + ); + }, ); } } diff --git a/packages/firebase_storage/firebase_storage/example/lib/save_as/save_as_html.dart b/packages/firebase_storage/firebase_storage/example/lib/save_as/save_as_html.dart index f9de3493af59..cd6d9b045023 100644 --- a/packages/firebase_storage/firebase_storage/example/lib/save_as/save_as_html.dart +++ b/packages/firebase_storage/firebase_storage/example/lib/save_as/save_as_html.dart @@ -51,8 +51,10 @@ Future saveAsBytes(Uint8List bytes, String suggestedName) async { // Create an tag with the appropriate download attributes and click it // May be overridden with XFileTestOverrides - final web.HTMLAnchorElement element = - _createAnchorElement(path, suggestedName); + final web.HTMLAnchorElement element = _createAnchorElement( + path, + suggestedName, + ); // Clear the children in our container so we can add an element to click do { diff --git a/packages/firebase_storage/firebase_storage/example/pubspec.yaml b/packages/firebase_storage/firebase_storage/example/pubspec.yaml index 85302e2e06a5..5f0fb3265182 100755 --- a/packages/firebase_storage/firebase_storage/example/pubspec.yaml +++ b/packages/firebase_storage/firebase_storage/example/pubspec.yaml @@ -3,8 +3,8 @@ description: Demonstrates how to use the firebase_storage plugin. resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core: ^4.14.0 diff --git a/packages/firebase_storage/firebase_storage/example/test_driver/integration_test.dart b/packages/firebase_storage/firebase_storage/example/test_driver/integration_test.dart index 691723cbbfe1..9ccbcc26ab97 100644 --- a/packages/firebase_storage/firebase_storage/example/test_driver/integration_test.dart +++ b/packages/firebase_storage/firebase_storage/example/test_driver/integration_test.dart @@ -7,28 +7,32 @@ import 'dart:io'; import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver( - writeResponseOnFailure: true, - responseDataCallback: (Map? data) async { - final results = - (data?['testResults'] as Map?)?.cast() ?? - const {}; - var passed = 0; - var failed = 0; - for (final entry in results.entries) { - final ok = entry.value == 'success'; - ok ? passed++ : failed++; - // ignore: avoid_print - print('${ok ? '✅' : '❌'} ${entry.key}'); - } - // ignore: avoid_print - print('Web e2e summary: $passed passed, $failed failed, ' - '${results.length} total'); - if (results.isEmpty) { - // ignore: avoid_print - print('[E] No tests reported by the app - treating as ' - 'infrastructure failure.'); - exit(1); - } - await writeResponseData(data); - }, + writeResponseOnFailure: true, + responseDataCallback: (Map? data) async { + final results = + (data?['testResults'] as Map?)?.cast() ?? + const {}; + var passed = 0; + var failed = 0; + for (final entry in results.entries) { + final ok = entry.value == 'success'; + ok ? passed++ : failed++; + // ignore: avoid_print + print('${ok ? '✅' : '❌'} ${entry.key}'); + } + // ignore: avoid_print + print( + 'Web e2e summary: $passed passed, $failed failed, ' + '${results.length} total', ); + if (results.isEmpty) { + // ignore: avoid_print + print( + '[E] No tests reported by the app - treating as ' + 'infrastructure failure.', + ); + exit(1); + } + await writeResponseData(data); + }, +); diff --git a/packages/firebase_storage/firebase_storage/lib/src/firebase_storage.dart b/packages/firebase_storage/firebase_storage/lib/src/firebase_storage.dart index bc53c6bd5ef1..767b5e30d441 100644 --- a/packages/firebase_storage/firebase_storage/lib/src/firebase_storage.dart +++ b/packages/firebase_storage/firebase_storage/lib/src/firebase_storage.dart @@ -8,7 +8,7 @@ part of firebase_storage; /// The entrypoint for [FirebaseStorage]. class FirebaseStorage extends FirebasePlugin { FirebaseStorage._({required this.app, required this.bucket}) - : super(app.name, 'plugins.flutter.io/firebase_storage'); + : super(app.name, 'plugins.flutter.io/firebase_storage'); // Cached and lazily loaded instance of [FirebaseStoragePlatform] to avoid // creating a [MethodChannelStorage] when not needed or creating an @@ -47,28 +47,25 @@ class FirebaseStorage extends FirebasePlugin { /// Returns an instance using the default [FirebaseApp]. static FirebaseStorage get instance { - return FirebaseStorage.instanceFor( - app: Firebase.app(), - ); + return FirebaseStorage.instanceFor(app: Firebase.app()); } /// Returns an instance using a specified [FirebaseApp] and/or custom storage bucket. /// /// If [app] is not provided, the default Firebase app will be used. /// If [bucket] is not provided, the default storage bucket will be used. - static FirebaseStorage instanceFor({ - FirebaseApp? app, - String? bucket, - }) { + static FirebaseStorage instanceFor({FirebaseApp? app, String? bucket}) { app ??= Firebase.app(); if (bucket == null && app.options.storageBucket == null) { if (app.name == defaultFirebaseAppName) { _throwNoBucketError( - 'No default storage bucket could be found. Ensure you have correctly followed the Getting Started guide.'); + 'No default storage bucket could be found. Ensure you have correctly followed the Getting Started guide.', + ); } else { _throwNoBucketError( - "No storage bucket could be found for the app '${app.name}'. Ensure you have set the [storageBucket] on [FirebaseOptions] whilst initializing the secondary Firebase app."); + "No storage bucket could be found for the app '${app.name}'. Ensure you have set the [storageBucket] on [FirebaseOptions] whilst initializing the secondary Firebase app.", + ); } } @@ -109,8 +106,10 @@ class FirebaseStorage extends FirebasePlugin { /// [FirebaseStorage.bucket], a new [FirebaseStorage] instance for the /// [Reference] will be used instead. Reference refFromURL(String url) { - assert(url.startsWith('gs://') || url.startsWith('http'), - "'a url must start with 'gs://' or 'https://'"); + assert( + url.startsWith('gs://') || url.startsWith('http'), + "'a url must start with 'gs://' or 'https://'", + ); String? bucket; String? path; @@ -118,8 +117,10 @@ class FirebaseStorage extends FirebasePlugin { if (url.startsWith('http')) { final parts = partsFromHttpUrl(url); - assert(parts != null, - "url could not be parsed, ensure it's a valid storage url"); + assert( + parts != null, + "url could not be parsed, ensure it's a valid storage url", + ); bucket = parts!['bucket']; path = parts['path']; @@ -128,8 +129,10 @@ class FirebaseStorage extends FirebasePlugin { path = pathFromGoogleStorageUrl(url); } - return FirebaseStorage.instanceFor(app: app, bucket: 'gs://$bucket') - .ref(path); + return FirebaseStorage.instanceFor( + app: app, + bucket: 'gs://$bucket', + ).ref(path); } /// Sets the new maximum operation retry time. @@ -157,8 +160,11 @@ class FirebaseStorage extends FirebasePlugin { /// /// Note: Must be called immediately, prior to accessing storage methods. /// Do not use with production credentials as emulator traffic is not encrypted. - Future useStorageEmulator(String host, int port, - {bool automaticHostMapping = true}) async { + Future useStorageEmulator( + String host, + int port, { + bool automaticHostMapping = true, + }) async { assert(host.isNotEmpty); assert(!port.isNegative); @@ -198,5 +204,8 @@ class FirebaseStorage extends FirebasePlugin { void _throwNoBucketError(String message) { throw FirebaseException( - plugin: 'firebase_storage', code: 'no-bucket', message: message); + plugin: 'firebase_storage', + code: 'no-bucket', + message: message, + ); } diff --git a/packages/firebase_storage/firebase_storage/lib/src/list_result.dart b/packages/firebase_storage/firebase_storage/lib/src/list_result.dart index 1a8bf86843eb..9f458e38bf07 100644 --- a/packages/firebase_storage/firebase_storage/lib/src/list_result.dart +++ b/packages/firebase_storage/firebase_storage/lib/src/list_result.dart @@ -23,7 +23,8 @@ class ListResult { List get items { return _delegate.items .map( - (referencePlatform) => Reference._(storage, referencePlatform)) + (referencePlatform) => Reference._(storage, referencePlatform), + ) .toList(); } @@ -41,7 +42,8 @@ class ListResult { List get prefixes { return _delegate.prefixes .map( - (referencePlatform) => Reference._(storage, referencePlatform)) + (referencePlatform) => Reference._(storage, referencePlatform), + ) .toList(); } } diff --git a/packages/firebase_storage/firebase_storage/lib/src/reference.dart b/packages/firebase_storage/firebase_storage/lib/src/reference.dart index e5c59e20cf83..6d5e2e702c11 100644 --- a/packages/firebase_storage/firebase_storage/lib/src/reference.dart +++ b/packages/firebase_storage/firebase_storage/lib/src/reference.dart @@ -72,9 +72,11 @@ class Reference { /// Storage List API will filter these unsupported objects. [list] may fail /// if there are too many unsupported objects in the bucket. Future list([ListOptions? options]) async { - assert(options == null || - options.maxResults == null || - options.maxResults! > 0 && options.maxResults! <= 1000); + assert( + options == null || + options.maxResults == null || + options.maxResults! > 0 && options.maxResults! <= 1000, + ); return ListResult._(storage, await _delegate.list(options)); } @@ -131,7 +133,9 @@ class Reference { /// Optionally, you can also set metadata onto the uploaded object. UploadTask putData(Uint8List data, [SettableMetadata? metadata]) { return UploadTask._( - storage, _delegate.putData(data, _withInferredContentType(metadata))); + storage, + _delegate.putData(data, _withInferredContentType(metadata)), + ); } /// Upload a [Blob]. Note; this is only supported on web platforms. @@ -140,7 +144,9 @@ class Reference { UploadTask putBlob(dynamic blob, [SettableMetadata? metadata]) { assert(blob != null); return UploadTask._( - storage, _delegate.putBlob(blob, _withInferredContentType(metadata))); + storage, + _delegate.putBlob(blob, _withInferredContentType(metadata)), + ); } /// Upload a [File] from the filesystem. The file must exist. @@ -184,9 +190,7 @@ class Reference { _data = uri.contentText; if (_metadata == null && uri.mimeType.isNotEmpty) { - _metadata = SettableMetadata( - contentType: uri.mimeType, - ); + _metadata = SettableMetadata(contentType: uri.mimeType); } // If the data_url contains a mime-type & the user has not provided it, @@ -203,7 +207,9 @@ class Reference { } } return UploadTask._( - storage, _delegate.putString(_data, _format, _metadata)); + storage, + _delegate.putString(_data, _format, _metadata), + ); } /// Updates the metadata on a storage object. diff --git a/packages/firebase_storage/firebase_storage/lib/src/task.dart b/packages/firebase_storage/firebase_storage/lib/src/task.dart index 961ad746cf88..0aaec2f40b18 100644 --- a/packages/firebase_storage/firebase_storage/lib/src/task.dart +++ b/packages/firebase_storage/firebase_storage/lib/src/task.dart @@ -24,8 +24,9 @@ abstract class Task implements Future { /// If you do not need to know about on-going stream events, you can instead /// await this [Task] directly. Stream get snapshotEvents { - return _delegate.snapshotEvents - .map((snapshotDelegate) => TaskSnapshot._(storage, snapshotDelegate)); + return _delegate.snapshotEvents.map( + (snapshotDelegate) => TaskSnapshot._(storage, snapshotDelegate), + ); } /// The latest [TaskSnapshot] for this task. @@ -56,18 +57,21 @@ abstract class Task implements Future { _delegate.onComplete.asStream().map((_) => snapshot); @override - Future catchError(Function onError, - {bool Function(Object error)? test}) async { + Future catchError( + Function onError, { + bool Function(Object error)? test, + }) async { await _delegate.onComplete.catchError(onError, test: test); return snapshot; } @override - Future then(FutureOr Function(TaskSnapshot) onValue, - {Function? onError}) => - _delegate.onComplete.then((_) { - return onValue(snapshot); - }, onError: onError); + Future then( + FutureOr Function(TaskSnapshot) onValue, { + Function? onError, + }) => _delegate.onComplete.then((_) { + return onValue(snapshot); + }, onError: onError); @override Future whenComplete(FutureOr Function() action) async { @@ -76,21 +80,22 @@ abstract class Task implements Future { } @override - Future timeout(Duration timeLimit, - {FutureOr Function()? onTimeout}) => - _delegate.onComplete - .then((_) => snapshot) - .timeout(timeLimit, onTimeout: onTimeout); + Future timeout( + Duration timeLimit, { + FutureOr Function()? onTimeout, + }) => _delegate.onComplete + .then((_) => snapshot) + .timeout(timeLimit, onTimeout: onTimeout); } /// A class which indicates an on-going upload task. class UploadTask extends Task { UploadTask._(FirebaseStorage storage, TaskPlatform delegate) - : super._(storage, delegate); + : super._(storage, delegate); } /// A class which indicates an on-going download task. class DownloadTask extends Task { DownloadTask._(FirebaseStorage storage, TaskPlatform delegate) - : super._(storage, delegate); + : super._(storage, delegate); } diff --git a/packages/firebase_storage/firebase_storage/lib/src/utils.dart b/packages/firebase_storage/firebase_storage/lib/src/utils.dart index 8100e2e8dd78..4a31fa0a0766 100644 --- a/packages/firebase_storage/firebase_storage/lib/src/utils.dart +++ b/packages/firebase_storage/firebase_storage/lib/src/utils.dart @@ -67,10 +67,7 @@ Map? partsFromHttpUrl(String url) { return null; } - return { - 'bucket': match.group(1), - 'path': match.group(3), - }; + return {'bucket': match.group(1), 'path': match.group(3)}; } else { // Google Cloud storage url RegExp cloudStorageRegExp = RegExp( @@ -84,10 +81,7 @@ Map? partsFromHttpUrl(String url) { return null; } - return { - 'bucket': match.group(1), - 'path': match.group(2), - }; + return {'bucket': match.group(1), 'path': match.group(2)}; } } diff --git a/packages/firebase_storage/firebase_storage/pubspec.yaml b/packages/firebase_storage/firebase_storage/pubspec.yaml index a446e9b1db93..4ba167080e9b 100755 --- a/packages/firebase_storage/firebase_storage/pubspec.yaml +++ b/packages/firebase_storage/firebase_storage/pubspec.yaml @@ -16,8 +16,8 @@ false_secrets: - example/** environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: firebase_core: ^4.14.0 diff --git a/packages/firebase_storage/firebase_storage/test/firebase_storage_test.dart b/packages/firebase_storage/firebase_storage/test/firebase_storage_test.dart index 3d77767c1815..31b9bf9e28e4 100644 --- a/packages/firebase_storage/firebase_storage/test/firebase_storage_test.dart +++ b/packages/firebase_storage/firebase_storage/test/firebase_storage_test.dart @@ -49,8 +49,10 @@ void main() { group('instanceFor()', () { test('instance', () async { - expect(storageSecondary.bucket, - kSecondaryBucket.replaceFirst('gs://', '')); + expect( + storageSecondary.bucket, + kSecondaryBucket.replaceFirst('gs://', ''), + ); expect(storageSecondary.app.name, 'foo'); }); @@ -109,16 +111,19 @@ void main() { group('.refFromURL()', () { test( - "throws AssertionError when value does not start with 'gs://' or 'http'", - () { - expect(() => storage.refFromURL('invalid.com'), throwsAssertionError); - }); + "throws AssertionError when value does not start with 'gs://' or 'http'", + () { + expect(() => storage.refFromURL('invalid.com'), throwsAssertionError); + }, + ); - test('throws AssertionError when http url is not a valid storage url', - () { - const String url = 'https://test.com'; - expect(() => storage.refFromURL(url), throwsAssertionError); - }); + test( + 'throws AssertionError when http url is not a valid storage url', + () { + const String url = 'https://test.com'; + expect(() => storage.refFromURL(url), throwsAssertionError); + }, + ); test('verify delegate method is called for encoded http urls', () { const String customBucket = 'test.appspot.com'; @@ -187,7 +192,9 @@ void main() { test('throws AssertionError when port is negative', () { expect( - () => storage.useStorageEmulator('foo', -10), throwsAssertionError); + () => storage.useStorageEmulator('foo', -10), + throwsAssertionError, + ); }); test('verify delegate method is called with args', () { diff --git a/packages/firebase_storage/firebase_storage/test/list_result_test.dart b/packages/firebase_storage/firebase_storage/test/list_result_test.dart index 0576a1055307..40e82b55eb0d 100644 --- a/packages/firebase_storage/firebase_storage/test/list_result_test.dart +++ b/packages/firebase_storage/firebase_storage/test/list_result_test.dart @@ -21,10 +21,14 @@ void main() { MockReferencePlatform mockReference = MockReferencePlatform(); MockListResultPlatform mockList = MockListResultPlatform(); - List items = - List.from([MockReferencePlatform(), MockReferencePlatform()]); - List prefixes = - List.from([MockReferencePlatform(), MockReferencePlatform()]); + List items = List.from([ + MockReferencePlatform(), + MockReferencePlatform(), + ]); + List prefixes = List.from([ + MockReferencePlatform(), + MockReferencePlatform(), + ]); group('$ListResult', () { setUpAll(() async { @@ -40,8 +44,9 @@ void main() { when(mockList.prefixes).thenReturn(prefixes); Reference ref = storage.ref(); - listResult = - await ref.list(const ListOptions(maxResults: 10, pageToken: 'token')); + listResult = await ref.list( + const ListOptions(maxResults: 10, pageToken: 'token'), + ); }); group('.items', () { diff --git a/packages/firebase_storage/firebase_storage/test/mock.dart b/packages/firebase_storage/firebase_storage/test/mock.dart index 377a0416ba2a..6cc628d6822f 100644 --- a/packages/firebase_storage/firebase_storage/test/mock.dart +++ b/packages/firebase_storage/firebase_storage/test/mock.dart @@ -30,7 +30,7 @@ const String testToken = 'mock-token'; const String testParent = 'test-parent'; const String testDownloadUrl = 'test-download-url'; const Map testMetadataMap = { - 'contentType': 'gif' + 'contentType': 'gif', }; const int testMaxResults = 1; const String testPageToken = 'test-page-token'; @@ -63,7 +63,7 @@ class MockFirebaseAppStorage implements TestFirebaseCoreHostApi { storageBucket: kBucket, ), pluginConstants: {}, - ) + ), ]; } @@ -85,9 +85,12 @@ void setupFirebaseStorageMocks() { TestFirebaseCoreHostApi.setUp(MockFirebaseAppStorage()); // Mock Platform Interface Methods - when(kMockStoragePlatform.delegateFor( - app: anyNamed('app'), bucket: anyNamed('bucket'))) - .thenReturn(kMockStoragePlatform); + when( + kMockStoragePlatform.delegateFor( + app: anyNamed('app'), + bucket: anyNamed('bucket'), + ), + ).thenReturn(kMockStoragePlatform); } // Platform Interface Mock Classes @@ -97,8 +100,7 @@ class MockFirebaseStorage extends Mock with // ignore: prefer_mixin, plugin_platform_interface needs to migrate to use `mixin` MockPlatformInterfaceMixin - implements - TestFirebaseStoragePlatform { + implements TestFirebaseStoragePlatform { MockFirebaseStorage() { TestFirebaseStoragePlatform(); } @@ -113,21 +115,25 @@ class MockFirebaseStorage extends Mock @override FirebaseStoragePlatform delegateFor({FirebaseApp? app, String? bucket}) { return super.noSuchMethod( - Invocation.method(#delegateFor, [], {#app: app, #bucket: bucket}), - returnValue: TestFirebaseStoragePlatform()); + Invocation.method(#delegateFor, [], {#app: app, #bucket: bucket}), + returnValue: TestFirebaseStoragePlatform(), + ); } @override ReferencePlatform ref(String? path) { - return super.noSuchMethod(Invocation.method(#ref, [path]), - returnValue: TestReferencePlatform(), - returnValueForMissingStub: TestReferencePlatform()); + return super.noSuchMethod( + Invocation.method(#ref, [path]), + returnValue: TestReferencePlatform(), + returnValueForMissingStub: TestReferencePlatform(), + ); } @override Future useStorageEmulator(String host, int port) async { - return super - .noSuchMethod(Invocation.method(#useStorageEmulator, [host, port])); + return super.noSuchMethod( + Invocation.method(#useStorageEmulator, [host, port]), + ); } } @@ -143,7 +149,7 @@ class TestFirebaseStoragePlatform extends FirebaseStoragePlatform { // ReferencePlatform Mock class TestReferencePlatform extends ReferencePlatform { TestReferencePlatform() : super(TestFirebaseStoragePlatform(), testFullPath); -// @override + // @override } // ReferencePlatform Mock @@ -151,124 +157,162 @@ class MockReferencePlatform extends Mock with // ignore: prefer_mixin, plugin_platform_interface needs to migrate to use `mixin` MockPlatformInterfaceMixin - implements - ReferencePlatform { + implements ReferencePlatform { @override Future list([ListOptions? options]) { - return super.noSuchMethod(Invocation.method(#list, [options]), - returnValue: neverEndingFuture(), - returnValueForMissingStub: neverEndingFuture()); + return super.noSuchMethod( + Invocation.method(#list, [options]), + returnValue: neverEndingFuture(), + returnValueForMissingStub: neverEndingFuture(), + ); } @override TaskPlatform putData(Uint8List data, [SettableMetadata? metadata]) { - return super.noSuchMethod(Invocation.method(#putData, [data, metadata]), - returnValue: TestUploadTaskPlatform(), - returnValueForMissingStub: TestUploadTaskPlatform()); + return super.noSuchMethod( + Invocation.method(#putData, [data, metadata]), + returnValue: TestUploadTaskPlatform(), + returnValueForMissingStub: TestUploadTaskPlatform(), + ); } @override TaskPlatform putFile(File file, [SettableMetadata? metadata]) { - return super.noSuchMethod(Invocation.method(#putFile, [file, metadata]), - returnValue: TestUploadTaskPlatform(), - returnValueForMissingStub: TestUploadTaskPlatform()); + return super.noSuchMethod( + Invocation.method(#putFile, [file, metadata]), + returnValue: TestUploadTaskPlatform(), + returnValueForMissingStub: TestUploadTaskPlatform(), + ); } @override Future updateMetadata(SettableMetadata metadata) { - return super.noSuchMethod(Invocation.method(#updateMetadata, [metadata]), - returnValue: neverEndingFuture(), - returnValueForMissingStub: neverEndingFuture()); + return super.noSuchMethod( + Invocation.method(#updateMetadata, [metadata]), + returnValue: neverEndingFuture(), + returnValueForMissingStub: neverEndingFuture(), + ); } @override String get bucket { - return super.noSuchMethod(Invocation.getter(#bucket), - returnValue: testBucket, returnValueForMissingStub: testBucket); + return super.noSuchMethod( + Invocation.getter(#bucket), + returnValue: testBucket, + returnValueForMissingStub: testBucket, + ); } @override String get fullPath { - return super.noSuchMethod(Invocation.getter(#fullPath), - returnValue: testFullPath, returnValueForMissingStub: testBucket); + return super.noSuchMethod( + Invocation.getter(#fullPath), + returnValue: testFullPath, + returnValueForMissingStub: testBucket, + ); } @override String get name { - return super.noSuchMethod(Invocation.getter(#name), - returnValue: testName, returnValueForMissingStub: testName); + return super.noSuchMethod( + Invocation.getter(#name), + returnValue: testName, + returnValueForMissingStub: testName, + ); } @override ReferencePlatform? get parent { - return super.noSuchMethod(Invocation.getter(#parent), - returnValue: TestListResultPlatform(), - returnValueForMissingStub: TestListResultPlatform()); + return super.noSuchMethod( + Invocation.getter(#parent), + returnValue: TestListResultPlatform(), + returnValueForMissingStub: TestListResultPlatform(), + ); } @override TaskPlatform putBlob(dynamic data, [SettableMetadata? metadata]) { - return super.noSuchMethod(Invocation.method(#putBlob, [data, metadata]), - returnValue: TestUploadTaskPlatform(), - returnValueForMissingStub: TestUploadTaskPlatform()); + return super.noSuchMethod( + Invocation.method(#putBlob, [data, metadata]), + returnValue: TestUploadTaskPlatform(), + returnValueForMissingStub: TestUploadTaskPlatform(), + ); } @override TaskPlatform writeToFile(File file) { - return super.noSuchMethod(Invocation.method(#writeToFile, [file]), - returnValue: TestUploadTaskPlatform(), - returnValueForMissingStub: TestUploadTaskPlatform()); + return super.noSuchMethod( + Invocation.method(#writeToFile, [file]), + returnValue: TestUploadTaskPlatform(), + returnValueForMissingStub: TestUploadTaskPlatform(), + ); } @override ReferencePlatform get root { - return super.noSuchMethod(Invocation.getter(#root), - returnValue: TestReferencePlatform(), - returnValueForMissingStub: TestListResultPlatform()); + return super.noSuchMethod( + Invocation.getter(#root), + returnValue: TestReferencePlatform(), + returnValueForMissingStub: TestListResultPlatform(), + ); } @override ReferencePlatform child(String path) { - return super.noSuchMethod(Invocation.method(#child, [], {#path: path}), - returnValue: TestReferencePlatform(), - returnValueForMissingStub: TestListResultPlatform()); + return super.noSuchMethod( + Invocation.method(#child, [], {#path: path}), + returnValue: TestReferencePlatform(), + returnValueForMissingStub: TestListResultPlatform(), + ); } @override Future delete() { - return super.noSuchMethod(Invocation.method(#delete, []), - returnValue: neverEndingFuture(), - returnValueForMissingStub: neverEndingFuture()); + return super.noSuchMethod( + Invocation.method(#delete, []), + returnValue: neverEndingFuture(), + returnValueForMissingStub: neverEndingFuture(), + ); } @override - TaskPlatform putString(String? data, PutStringFormat? format, - [SettableMetadata? metadata]) { + TaskPlatform putString( + String? data, + PutStringFormat? format, [ + SettableMetadata? metadata, + ]) { return super.noSuchMethod( - Invocation.method(#child, [data, format, metadata]), - returnValue: TestUploadTaskPlatform(), - returnValueForMissingStub: TestUploadTaskPlatform()); + Invocation.method(#child, [data, format, metadata]), + returnValue: TestUploadTaskPlatform(), + returnValueForMissingStub: TestUploadTaskPlatform(), + ); } @override Future getDownloadURL() { - return super.noSuchMethod(Invocation.method(#getDownloadURL, []), - returnValue: neverEndingFuture(), - returnValueForMissingStub: neverEndingFuture()); + return super.noSuchMethod( + Invocation.method(#getDownloadURL, []), + returnValue: neverEndingFuture(), + returnValueForMissingStub: neverEndingFuture(), + ); } @override Future getMetadata() { - return super.noSuchMethod(Invocation.method(#getMetadata, []), - returnValue: neverEndingFuture(), - returnValueForMissingStub: neverEndingFuture()); + return super.noSuchMethod( + Invocation.method(#getMetadata, []), + returnValue: neverEndingFuture(), + returnValueForMissingStub: neverEndingFuture(), + ); } @override Future listAll() { - return super.noSuchMethod(Invocation.method(#listAll, []), - returnValue: neverEndingFuture(), - returnValueForMissingStub: neverEndingFuture()); + return super.noSuchMethod( + Invocation.method(#listAll, []), + returnValue: neverEndingFuture(), + returnValueForMissingStub: neverEndingFuture(), + ); } } @@ -277,48 +321,59 @@ class MockUploadTaskPlatform extends Mock with // ignore: prefer_mixin, plugin_platform_interface needs to migrate to use `mixin` MockPlatformInterfaceMixin - implements - TaskPlatform { + implements TaskPlatform { @override TaskSnapshotPlatform get snapshot { - return super.noSuchMethod(Invocation.getter(#snapshot), - returnValue: TestTaskSnapshotPlatform(), - returnValueForMissingStub: TestTaskSnapshotPlatform()); + return super.noSuchMethod( + Invocation.getter(#snapshot), + returnValue: TestTaskSnapshotPlatform(), + returnValueForMissingStub: TestTaskSnapshotPlatform(), + ); } @override Stream get snapshotEvents { - return super.noSuchMethod(Invocation.getter(#snapshotEvents), - returnValue: const Stream.empty(), - returnValueForMissingStub: const Stream.empty()); + return super.noSuchMethod( + Invocation.getter(#snapshotEvents), + returnValue: const Stream.empty(), + returnValueForMissingStub: const Stream.empty(), + ); } @override Future get onComplete { - return super.noSuchMethod(Invocation.getter(#onComplete), - returnValue: neverEndingFuture(), - returnValueForMissingStub: neverEndingFuture()); + return super.noSuchMethod( + Invocation.getter(#onComplete), + returnValue: neverEndingFuture(), + returnValueForMissingStub: neverEndingFuture(), + ); } @override Future pause() { - return super.noSuchMethod(Invocation.method(#pause, []), - returnValue: Future.value(false), - returnValueForMissingStub: Future.value(false)); + return super.noSuchMethod( + Invocation.method(#pause, []), + returnValue: Future.value(false), + returnValueForMissingStub: Future.value(false), + ); } @override Future resume() { - return super.noSuchMethod(Invocation.method(#resume, []), - returnValue: Future.value(false), - returnValueForMissingStub: Future.value(false)); + return super.noSuchMethod( + Invocation.method(#resume, []), + returnValue: Future.value(false), + returnValueForMissingStub: Future.value(false), + ); } @override Future cancel() { - return super.noSuchMethod(Invocation.method(#cancel, []), - returnValue: Future.value(false), - returnValueForMissingStub: Future.value(false)); + return super.noSuchMethod( + Invocation.method(#cancel, []), + returnValue: Future.value(false), + returnValueForMissingStub: Future.value(false), + ); } } @@ -335,26 +390,32 @@ class MockListResultPlatform extends Mock with // ignore: prefer_mixin, plugin_platform_interface needs to migrate to use `mixin` MockPlatformInterfaceMixin - implements - ListResultPlatform { + implements ListResultPlatform { @override List get items { - return super.noSuchMethod(Invocation.getter(#items), - returnValue: [], - returnValueForMissingStub: []); + return super.noSuchMethod( + Invocation.getter(#items), + returnValue: [], + returnValueForMissingStub: [], + ); } @override String? get nextPageToken { - return super.noSuchMethod(Invocation.getter(#nextPageToken), - returnValue: testToken, returnValueForMissingStub: testToken); + return super.noSuchMethod( + Invocation.getter(#nextPageToken), + returnValue: testToken, + returnValueForMissingStub: testToken, + ); } @override List get prefixes { - return super.noSuchMethod(Invocation.getter(#prefixes), - returnValue: [], - returnValueForMissingStub: []); + return super.noSuchMethod( + Invocation.getter(#prefixes), + returnValue: [], + returnValueForMissingStub: [], + ); } } @@ -367,40 +428,48 @@ class MockDownloadTaskPlatform extends Mock with // ignore: prefer_mixin, plugin_platform_interface needs to migrate to use `mixin` MockPlatformInterfaceMixin - implements - TaskPlatform {} + implements TaskPlatform {} // TaskSnapshotPlatform Mock class MockTaskSnapshotPlatform extends Mock with // ignore: prefer_mixin, plugin_platform_interface needs to migrate to use `mixin` MockPlatformInterfaceMixin - implements - TaskSnapshotPlatform { + implements TaskSnapshotPlatform { @override int get bytesTransferred { - return super.noSuchMethod(Invocation.getter(#bytesTransferred), - returnValue: 0, returnValueForMissingStub: 0); + return super.noSuchMethod( + Invocation.getter(#bytesTransferred), + returnValue: 0, + returnValueForMissingStub: 0, + ); } @override int get totalBytes { - return super.noSuchMethod(Invocation.getter(#totalBytes), - returnValue: 0, returnValueForMissingStub: 0); + return super.noSuchMethod( + Invocation.getter(#totalBytes), + returnValue: 0, + returnValueForMissingStub: 0, + ); } @override ReferencePlatform get ref { - return super.noSuchMethod(Invocation.getter(#ref), - returnValue: TestReferencePlatform(), - returnValueForMissingStub: TestReferencePlatform()); + return super.noSuchMethod( + Invocation.getter(#ref), + returnValue: TestReferencePlatform(), + returnValueForMissingStub: TestReferencePlatform(), + ); } @override TaskState get state { - return super.noSuchMethod(Invocation.getter(#state), - returnValue: TaskState.running, - returnValueForMissingStub: TaskState.running); + return super.noSuchMethod( + Invocation.getter(#state), + returnValue: TaskState.running, + returnValueForMissingStub: TaskState.running, + ); } } diff --git a/packages/firebase_storage/firebase_storage/test/reference_test.dart b/packages/firebase_storage/firebase_storage/test/reference_test.dart index e38d3fed72bc..e4a93d00e024 100644 --- a/packages/firebase_storage/firebase_storage/test/reference_test.dart +++ b/packages/firebase_storage/firebase_storage/test/reference_test.dart @@ -26,8 +26,10 @@ Future main() async { late FirebaseStorage storage; late Reference testRef; FullMetadata testFullMetadata = FullMetadata(testMetadataMap); - ListOptions testListOptions = - const ListOptions(maxResults: testMaxResults, pageToken: testPageToken); + ListOptions testListOptions = const ListOptions( + maxResults: testMaxResults, + pageToken: testPageToken, + ); SettableMetadata testSettableMetadata = SettableMetadata(); File testFile = await createFile('foo.txt'); @@ -130,8 +132,9 @@ Future main() async { group('getDownloadURL()', () { test('verify delegate method is called', () async { - when(mockReference.getDownloadURL()) - .thenAnswer((_) => Future.value(testDownloadUrl)); + when( + mockReference.getDownloadURL(), + ).thenAnswer((_) => Future.value(testDownloadUrl)); final result = await testRef.getDownloadURL(); @@ -144,8 +147,9 @@ Future main() async { group('getMetadata()', () { test('verify delegate method is called', () async { - when(mockReference.getMetadata()) - .thenAnswer((_) => Future.value(testFullMetadata)); + when( + mockReference.getMetadata(), + ).thenAnswer((_) => Future.value(testFullMetadata)); final result = await testRef.getMetadata(); @@ -158,8 +162,9 @@ Future main() async { group('list()', () { test('verify delegate method is called', () async { - when(mockReference.list(testListOptions)) - .thenAnswer((_) => Future.value(mockListResultPlatform)); + when( + mockReference.list(testListOptions), + ).thenAnswer((_) => Future.value(mockListResultPlatform)); final result = await testRef.list(testListOptions); expect(result, isA()); @@ -168,14 +173,18 @@ Future main() async { }); test('throws AssertionError if max results is not greater than 0', () { - ListOptions listOptions = - const ListOptions(maxResults: 0, pageToken: testPageToken); + ListOptions listOptions = const ListOptions( + maxResults: 0, + pageToken: testPageToken, + ); expect(() => testRef.list(listOptions), throwsAssertionError); }); test('throws AssertionError if max results is greater than 1000', () { - ListOptions listOptions = - const ListOptions(maxResults: 1001, pageToken: testPageToken); + ListOptions listOptions = const ListOptions( + maxResults: 1001, + pageToken: testPageToken, + ); expect(() => testRef.list(listOptions), throwsAssertionError); }); @@ -183,8 +192,9 @@ Future main() async { group('listAll()', () { test('verify delegate method is called', () async { - when(mockReference.listAll()) - .thenAnswer((_) => Future.value(mockListResultPlatform)); + when( + mockReference.listAll(), + ).thenAnswer((_) => Future.value(mockListResultPlatform)); final result = await testRef.listAll(); @@ -212,8 +222,9 @@ Future main() async { group('putBlob()', () { test('verify delegate method is called', () { - when(mockReference.putBlob(testFile)) - .thenReturn(mockUploadTaskPlatform); + when( + mockReference.putBlob(testFile), + ).thenReturn(mockUploadTaskPlatform); final result = testRef.putBlob(testFile); @@ -229,8 +240,9 @@ Future main() async { group('putFile()', () { test('verify delegate method is called', () { - when(mockReference.putFile(testFile)) - .thenReturn(mockUploadTaskPlatform); + when( + mockReference.putFile(testFile), + ).thenReturn(mockUploadTaskPlatform); final result = testRef.putFile(testFile); @@ -261,31 +273,42 @@ Future main() async { test('data_url format', () { UriData uriData = UriData.fromString(testString, base64: true); Uri uri = uriData.uri; - final result = - testRef.putString(uri.toString(), format: PutStringFormat.dataUrl); + final result = testRef.putString( + uri.toString(), + format: PutStringFormat.dataUrl, + ); expect(result, isA()); // confirm data_url was converted to a Base64 format UriData uriDataExpected = UriData.fromUri(Uri.parse(uri.toString())); - verify(mockReference.putString( - uriDataExpected.contentText, PutStringFormat.base64, any)); + verify( + mockReference.putString( + uriDataExpected.contentText, + PutStringFormat.base64, + any, + ), + ); }); test('throws AssertionError if data_url is not a Base64 format', () { UriData uriData = UriData.fromString(testString); Uri uri = uriData.uri; expect( - () => testRef.putString(uri.toString(), - format: PutStringFormat.dataUrl), - throwsAssertionError); + () => testRef.putString( + uri.toString(), + format: PutStringFormat.dataUrl, + ), + throwsAssertionError, + ); }); }); group('updateMetadata()', () { test('verify delegate method is called', () async { - when(mockReference.updateMetadata(testSettableMetadata)) - .thenAnswer((_) => Future.value(testFullMetadata)); + when( + mockReference.updateMetadata(testSettableMetadata), + ).thenAnswer((_) => Future.value(testFullMetadata)); final result = await testRef.updateMetadata(testSettableMetadata); @@ -298,8 +321,9 @@ Future main() async { group('writeToFile()', () { test('verify delegate method is called', () { - when(mockReference.writeToFile(testFile)) - .thenReturn(mockDownloadTaskPlatform); + when( + mockReference.writeToFile(testFile), + ).thenReturn(mockDownloadTaskPlatform); final result = testRef.writeToFile(testFile); @@ -323,28 +347,30 @@ Future main() async { test('infers contentType from ref name when no metadata', () { List list = utf8.encode('hello'); Uint8List data = Uint8List.fromList(list); - when(mockJpgReference.putData(data, any)) - .thenReturn(mockUploadTaskPlatform); + when( + mockJpgReference.putData(data, any), + ).thenReturn(mockUploadTaskPlatform); jpgRef.putData(data); - final captured = verify(mockJpgReference.putData(data, captureAny)) - .captured - .single as SettableMetadata; + final captured = + verify(mockJpgReference.putData(data, captureAny)).captured.single + as SettableMetadata; expect(captured.contentType, 'image/jpeg'); }); test('infers contentType when metadata has no contentType', () { List list = utf8.encode('hello'); Uint8List data = Uint8List.fromList(list); - when(mockJpgReference.putData(data, any)) - .thenReturn(mockUploadTaskPlatform); + when( + mockJpgReference.putData(data, any), + ).thenReturn(mockUploadTaskPlatform); jpgRef.putData(data, SettableMetadata(contentLanguage: 'en')); - final captured = verify(mockJpgReference.putData(data, captureAny)) - .captured - .single as SettableMetadata; + final captured = + verify(mockJpgReference.putData(data, captureAny)).captured.single + as SettableMetadata; expect(captured.contentType, 'image/jpeg'); expect(captured.contentLanguage, 'en'); }); @@ -352,30 +378,36 @@ Future main() async { test('preserves explicit contentType', () { List list = utf8.encode('hello'); Uint8List data = Uint8List.fromList(list); - when(mockJpgReference.putData(data, any)) - .thenReturn(mockUploadTaskPlatform); + when( + mockJpgReference.putData(data, any), + ).thenReturn(mockUploadTaskPlatform); jpgRef.putData( - data, SettableMetadata(contentType: 'application/octet-stream')); + data, + SettableMetadata(contentType: 'application/octet-stream'), + ); - final captured = verify(mockJpgReference.putData(data, captureAny)) - .captured - .single as SettableMetadata; + final captured = + verify(mockJpgReference.putData(data, captureAny)).captured.single + as SettableMetadata; expect(captured.contentType, 'application/octet-stream'); }); test('preserves customMetadata when inferring contentType', () { List list = utf8.encode('hello'); Uint8List data = Uint8List.fromList(list); - when(mockJpgReference.putData(data, any)) - .thenReturn(mockUploadTaskPlatform); + when( + mockJpgReference.putData(data, any), + ).thenReturn(mockUploadTaskPlatform); jpgRef.putData( - data, SettableMetadata(customMetadata: {'activity': 'test'})); + data, + SettableMetadata(customMetadata: {'activity': 'test'}), + ); - final captured = verify(mockJpgReference.putData(data, captureAny)) - .captured - .single as SettableMetadata; + final captured = + verify(mockJpgReference.putData(data, captureAny)).captured.single + as SettableMetadata; expect(captured.contentType, 'image/jpeg'); expect(captured.customMetadata, {'activity': 'test'}); }); @@ -408,27 +440,31 @@ Future main() async { }); test('infers contentType from ref name when no metadata', () { - when(mockJpgReference.putBlob(any, any)) - .thenReturn(mockUploadTaskPlatform); + when( + mockJpgReference.putBlob(any, any), + ).thenReturn(mockUploadTaskPlatform); jpgRef.putBlob('blob-data'); - final captured = verify(mockJpgReference.putBlob(any, captureAny)) - .captured - .single as SettableMetadata; + final captured = + verify(mockJpgReference.putBlob(any, captureAny)).captured.single + as SettableMetadata; expect(captured.contentType, 'image/jpeg'); }); test('preserves explicit contentType', () { - when(mockJpgReference.putBlob(any, any)) - .thenReturn(mockUploadTaskPlatform); + when( + mockJpgReference.putBlob(any, any), + ).thenReturn(mockUploadTaskPlatform); jpgRef.putBlob( - 'blob-data', SettableMetadata(contentType: 'text/plain')); + 'blob-data', + SettableMetadata(contentType: 'text/plain'), + ); - final captured = verify(mockJpgReference.putBlob(any, captureAny)) - .captured - .single as SettableMetadata; + final captured = + verify(mockJpgReference.putBlob(any, captureAny)).captured.single + as SettableMetadata; expect(captured.contentType, 'text/plain'); }); }); diff --git a/packages/firebase_storage/firebase_storage/test/task_snapshot_test.dart b/packages/firebase_storage/firebase_storage/test/task_snapshot_test.dart index fb2101ff432d..3b46d9910518 100644 --- a/packages/firebase_storage/firebase_storage/test/task_snapshot_test.dart +++ b/packages/firebase_storage/firebase_storage/test/task_snapshot_test.dart @@ -15,7 +15,7 @@ const String testString = 'Hello World.'; const int testBytesTransferred = 11; const int testTotalBytes = 20; const Map testMetadata = { - 'contentType': 'gif' + 'contentType': 'gif', }; MockReferencePlatform mockReferencePlatform = MockReferencePlatform(); @@ -35,10 +35,12 @@ void main() { await Firebase.initializeApp(); storage = FirebaseStorage.instance; when(kMockStoragePlatform.ref(any)).thenReturn(mockReferencePlatform); - when(mockReferencePlatform.putString(any, any, any)) - .thenReturn(mockUploadTaskPlatform); - when(mockUploadTaskPlatform.snapshot) - .thenReturn(mockTaskSnapshotPlatform); + when( + mockReferencePlatform.putString(any, any, any), + ).thenReturn(mockUploadTaskPlatform); + when( + mockUploadTaskPlatform.snapshot, + ).thenReturn(mockTaskSnapshotPlatform); UploadTask uploadTask = storage.ref().putString(testString); taskSnapshot = uploadTask.snapshot; @@ -46,8 +48,9 @@ void main() { group('.bytesTransferred', () { test('verify delegate method is called', () { - when(mockTaskSnapshotPlatform.bytesTransferred) - .thenReturn(testBytesTransferred); + when( + mockTaskSnapshotPlatform.bytesTransferred, + ).thenReturn(testBytesTransferred); expect(taskSnapshot.bytesTransferred, testBytesTransferred); verify(mockTaskSnapshotPlatform.bytesTransferred); diff --git a/packages/firebase_storage/firebase_storage/test/task_test.dart b/packages/firebase_storage/firebase_storage/test/task_test.dart index 5c6c6bd6ad69..cb91f4922856 100644 --- a/packages/firebase_storage/firebase_storage/test/task_test.dart +++ b/packages/firebase_storage/firebase_storage/test/task_test.dart @@ -32,15 +32,17 @@ void main() { storage = FirebaseStorage.instance; when(kMockStoragePlatform.ref(any)).thenReturn(mockReferencePlatform); - when(mockReferencePlatform.putString(any, any, any)) - .thenReturn(mockUploadTaskPlatform); + when( + mockReferencePlatform.putString(any, any, any), + ).thenReturn(mockUploadTaskPlatform); uploadTask = storage.ref().putString(testString); }); group('.snapshotEvents', () { test('verify delegate method is called', () async { - when(mockUploadTaskPlatform.snapshotEvents) - .thenAnswer((_) => Stream.fromIterable([mockTaskSnapshotPlatform])); + when( + mockUploadTaskPlatform.snapshotEvents, + ).thenAnswer((_) => Stream.fromIterable([mockTaskSnapshotPlatform])); final result = uploadTask.snapshotEvents; @@ -51,8 +53,9 @@ void main() { group('.snapshot()', () { test('verify delegate method is called', () { - when(mockUploadTaskPlatform.snapshot) - .thenReturn(mockTaskSnapshotPlatform); + when( + mockUploadTaskPlatform.snapshot, + ).thenReturn(mockTaskSnapshotPlatform); final result = uploadTask.snapshot; @@ -63,8 +66,9 @@ void main() { group('onComplete()', () { test('verify delegate method is called', () async { - when(mockUploadTaskPlatform.onComplete) - .thenAnswer((_) => Future.value(mockTaskSnapshotPlatform)); + when( + mockUploadTaskPlatform.onComplete, + ).thenAnswer((_) => Future.value(mockTaskSnapshotPlatform)); final result = await uploadTask; @@ -76,8 +80,9 @@ void main() { group('pause()', () { test('verify delegate method is called', () async { - when(mockUploadTaskPlatform.pause()) - .thenAnswer((_) => Future.value(true)); + when( + mockUploadTaskPlatform.pause(), + ).thenAnswer((_) => Future.value(true)); final result = await uploadTask.pause(); @@ -90,8 +95,9 @@ void main() { group('resume()', () { test('verify delegate method is called', () async { - when(mockUploadTaskPlatform.resume()) - .thenAnswer((_) => Future.value(true)); + when( + mockUploadTaskPlatform.resume(), + ).thenAnswer((_) => Future.value(true)); final result = await uploadTask.resume(); @@ -104,8 +110,9 @@ void main() { group('cancel()', () { test('verify delegate method is called', () async { - when(mockUploadTaskPlatform.cancel()) - .thenAnswer((_) => Future.value(true)); + when( + mockUploadTaskPlatform.cancel(), + ).thenAnswer((_) => Future.value(true)); final result = await uploadTask.cancel(); diff --git a/packages/firebase_storage/firebase_storage/test/utils_test.dart b/packages/firebase_storage/firebase_storage/test/utils_test.dart index c79b24fa6197..6f7f5c32fe13 100644 --- a/packages/firebase_storage/firebase_storage/test/utils_test.dart +++ b/packages/firebase_storage/firebase_storage/test/utils_test.dart @@ -105,36 +105,41 @@ void main() { }); test( - 'parses HTTP URL correctly when using Android emulator localhost (10.0.2.2)', - () { - const androidLocalhost = '10.0.2.2'; - - final result = partsFromHttpUrl( - 'http://$androidLocalhost:9199/v0/b/myapp.appspot.com/o/path/to/foo_bar.jpg'); - - expect( - result, - isNotNull, - reason: - 'partsFromHttpUrl should not return null for Android localhost URLs', - ); - expect(result?['bucket'], 'myapp.appspot.com'); - expect(result?['path'], 'path/to/foo_bar.jpg'); - }); + 'parses HTTP URL correctly when using Android emulator localhost (10.0.2.2)', + () { + const androidLocalhost = '10.0.2.2'; + + final result = partsFromHttpUrl( + 'http://$androidLocalhost:9199/v0/b/myapp.appspot.com/o/path/to/foo_bar.jpg', + ); + + expect( + result, + isNotNull, + reason: + 'partsFromHttpUrl should not return null for Android localhost URLs', + ); + expect(result?['bucket'], 'myapp.appspot.com'); + expect(result?['path'], 'path/to/foo_bar.jpg'); + }, + ); - test('parses HTTP URL correctly when using standard localhost (127.0.0.1)', - () { - final result = partsFromHttpUrl( - 'http://localhost:9199/v0/b/myapp.appspot.com/o/path/to/foo_bar.jpg'); - - expect( - result, - isNotNull, - reason: 'partsFromHttpUrl should not return null for localhost URLs', - ); - expect(result?['bucket'], 'myapp.appspot.com'); - expect(result?['path'], 'path/to/foo_bar.jpg'); - }); + test( + 'parses HTTP URL correctly when using standard localhost (127.0.0.1)', + () { + final result = partsFromHttpUrl( + 'http://localhost:9199/v0/b/myapp.appspot.com/o/path/to/foo_bar.jpg', + ); + + expect( + result, + isNotNull, + reason: 'partsFromHttpUrl should not return null for localhost URLs', + ); + expect(result?['bucket'], 'myapp.appspot.com'); + expect(result?['path'], 'path/to/foo_bar.jpg'); + }, + ); // TODO(helenaford): regexp can't handle no paths // test('sets path to default if null', () { diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/list_options.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/list_options.dart index c89de44b679f..f70d3ed1e478 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/list_options.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/list_options.dart @@ -6,10 +6,7 @@ /// The options [FirebaseStoragePlatform.list] accepts. class ListOptions { /// Creates a new [ListOptions] instance. - const ListOptions({ - this.maxResults, - this.pageToken, - }); + const ListOptions({this.maxResults, this.pageToken}); /// If set, limits the total number of `prefixes` and `items` to return. /// diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_firebase_storage.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_firebase_storage.dart index 85cc085517c2..d68b5e7358c9 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_firebase_storage.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_firebase_storage.dart @@ -17,9 +17,10 @@ import 'method_channel_reference.dart'; class MethodChannelFirebaseStorage extends FirebaseStoragePlatform { /// Creates a new [MethodChannelFirebaseStorage] instance with an [app] and/or /// [bucket]. - MethodChannelFirebaseStorage( - {required FirebaseApp app, required String bucket}) - : super(appInstance: app, bucket: bucket); + MethodChannelFirebaseStorage({ + required FirebaseApp app, + required String bucket, + }) : super(appInstance: app, bucket: bucket); /// Internal stub class initializer. /// @@ -44,10 +45,7 @@ class MethodChannelFirebaseStorage extends FirebaseStoragePlatform { /// FirebaseApp pigeon instance InternalStorageFirebaseApp get pigeonFirebaseApp { - return InternalStorageFirebaseApp( - appName: app.name, - bucket: bucket, - ); + return InternalStorageFirebaseApp(appName: app.name, bucket: bucket); } /// Returns a unique key to identify the instance by [FirebaseApp] name and @@ -57,12 +55,10 @@ class MethodChannelFirebaseStorage extends FirebaseStoragePlatform { } /// The [MethodChannelFirebaseStorage] method channel. - static const MethodChannel channel = MethodChannel( - storageMethodChannelName, - ); + static const MethodChannel channel = MethodChannel(storageMethodChannelName); static Map - _methodChannelFirebaseStorageInstances = + _methodChannelFirebaseStorageInstances = {}; /// Returns a stub instance to allow the platform interface to access @@ -73,32 +69,37 @@ class MethodChannelFirebaseStorage extends FirebaseStoragePlatform { /// Return an instance of a [InternalStorageReference] static InternalStorageReference getPigeonReference( - String bucket, String fullPath, String name) { + String bucket, + String fullPath, + String name, + ) { return InternalStorageReference( - bucket: bucket, fullPath: fullPath, name: name); + bucket: bucket, + fullPath: fullPath, + name: name, + ); } /// Return an instance of a [InternalStorageFirebaseApp] InternalStorageFirebaseApp getPigeonFirebaseApp(String appName) { - return InternalStorageFirebaseApp( - appName: appName, - bucket: bucket, - ); + return InternalStorageFirebaseApp(appName: appName, bucket: bucket); } /// Convert a [SettableMetadata] to [InternalSettableMetadata] static InternalSettableMetadata getPigeonSettableMetaData( - SettableMetadata? metaData) { + SettableMetadata? metaData, + ) { if (metaData == null) { return InternalSettableMetadata(); } return InternalSettableMetadata( - cacheControl: metaData.cacheControl, - contentDisposition: metaData.contentDisposition, - contentEncoding: metaData.contentEncoding, - contentLanguage: metaData.contentLanguage, - contentType: metaData.contentType, - customMetadata: metaData.customMetadata); + cacheControl: metaData.cacheControl, + contentDisposition: metaData.contentDisposition, + contentEncoding: metaData.contentEncoding, + contentLanguage: metaData.contentLanguage, + contentType: metaData.contentType, + customMetadata: metaData.customMetadata, + ); } static int _methodChannelHandleId = 0; @@ -116,8 +117,10 @@ class MethodChannelFirebaseStorage extends FirebaseStoragePlatform { int maxDownloadRetryTime = const Duration(minutes: 10).inMilliseconds; @override - FirebaseStoragePlatform delegateFor( - {required FirebaseApp app, required String bucket}) { + FirebaseStoragePlatform delegateFor({ + required FirebaseApp app, + required String bucket, + }) { String key = _getInstanceKey(app.name, bucket); return _methodChannelFirebaseStorageInstances[key] ??= @@ -135,7 +138,10 @@ class MethodChannelFirebaseStorage extends FirebaseStoragePlatform { emulatorPort = port; try { return await pigeonChannel.useStorageEmulator( - pigeonFirebaseApp, host, port); + pigeonFirebaseApp, + host, + port, + ); } catch (e, s) { convertPlatformException(e, s); } diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_list_result.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_list_result.dart index 04832f03e88b..1c1c34efe08b 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_list_result.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_list_result.dart @@ -14,9 +14,9 @@ class MethodChannelListResult extends ListResultPlatform { String? nextPageToken, List? items, List? prefixes, - }) : _items = items ?? [], - _prefixes = prefixes ?? [], - super(storage, nextPageToken); + }) : _items = items ?? [], + _prefixes = prefixes ?? [], + super(storage, nextPageToken); List _items; diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_reference.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_reference.dart index bc279770919b..23b077dc1f4c 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_reference.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_reference.dart @@ -19,7 +19,7 @@ import 'utils/exception.dart'; class MethodChannelReference extends ReferencePlatform { /// Creates a [ReferencePlatform] that is implemented using [MethodChannel]. MethodChannelReference(FirebaseStoragePlatform storage, String path) - : super(storage, path); + : super(storage, path); /// FirebaseApp pigeon instance InternalStorageFirebaseApp get pigeonFirebaseApp { @@ -41,8 +41,10 @@ class MethodChannelReference extends ReferencePlatform { @override Future delete() async { try { - await MethodChannelFirebaseStorage.pigeonChannel - .referenceDelete(pigeonFirebaseApp, pigeonReference); + await MethodChannelFirebaseStorage.pigeonChannel.referenceDelete( + pigeonFirebaseApp, + pigeonReference, + ); } catch (e, stack) { convertPlatformException(e, stack); } @@ -95,7 +97,8 @@ class MethodChannelReference extends ReferencePlatform { /// Convert a [InternalListResult] to [ListResultPlatform] ListResultPlatform convertListReference( - InternalListResult pigeonReferenceList) { + InternalListResult pigeonReferenceList, + ) { List referencePaths = []; for (final reference in pigeonReferenceList.items) { referencePaths.add(reference!.fullPath); @@ -117,8 +120,11 @@ class MethodChannelReference extends ReferencePlatform { try { InternalListOptions pigeonOptions = convertOptions(options); InternalListResult pigeonReferenceList = - await MethodChannelFirebaseStorage.pigeonChannel - .referenceList(pigeonFirebaseApp, pigeonReference, pigeonOptions); + await MethodChannelFirebaseStorage.pigeonChannel.referenceList( + pigeonFirebaseApp, + pigeonReference, + pigeonOptions, + ); return convertListReference(pigeonReferenceList); } catch (e, stack) { convertPlatformException(e, stack); @@ -129,8 +135,10 @@ class MethodChannelReference extends ReferencePlatform { Future listAll() async { try { InternalListResult pigeonReferenceList = - await MethodChannelFirebaseStorage.pigeonChannel - .referenceListAll(pigeonFirebaseApp, pigeonReference); + await MethodChannelFirebaseStorage.pigeonChannel.referenceListAll( + pigeonFirebaseApp, + pigeonReference, + ); return convertListReference(pigeonReferenceList); } catch (e, stack) { convertPlatformException(e, stack); @@ -140,8 +148,11 @@ class MethodChannelReference extends ReferencePlatform { @override Future getData(int maxSize) async { try { - return await MethodChannelFirebaseStorage.pigeonChannel - .referenceGetData(pigeonFirebaseApp, pigeonReference, maxSize); + return await MethodChannelFirebaseStorage.pigeonChannel.referenceGetData( + pigeonFirebaseApp, + pigeonReference, + maxSize, + ); } catch (e, stack) { convertPlatformException(e, stack); } @@ -156,7 +167,8 @@ class MethodChannelReference extends ReferencePlatform { @override TaskPlatform putBlob(dynamic data, [SettableMetadata? metadata]) { throw UnimplementedError( - 'putBlob() is not supported on native platforms. Use [put], [putFile] or [putString] instead.'); + 'putBlob() is not supported on native platforms. Use [put], [putFile] or [putString] instead.', + ); } @override @@ -166,11 +178,20 @@ class MethodChannelReference extends ReferencePlatform { } @override - TaskPlatform putString(String data, PutStringFormat format, - [SettableMetadata? metadata]) { + TaskPlatform putString( + String data, + PutStringFormat format, [ + SettableMetadata? metadata, + ]) { int handle = MethodChannelFirebaseStorage.nextMethodChannelHandleId; return MethodChannelPutStringTask( - handle, storage, fullPath, data, format, metadata); + handle, + storage, + fullPath, + data, + format, + metadata, + ); } /// Convert a [SettableMetadata] to [InternalSettableMetadata] @@ -190,8 +211,11 @@ class MethodChannelReference extends ReferencePlatform { try { InternalFullMetaData updatedMetaData = await MethodChannelFirebaseStorage .pigeonChannel - .referenceUpdateMetadata(pigeonFirebaseApp, pigeonReference, - convertToPigeonMetaData(metadata)); + .referenceUpdateMetadata( + pigeonFirebaseApp, + pigeonReference, + convertToPigeonMetaData(metadata), + ); return convertMetadata(updatedMetaData); } catch (e, stack) { convertPlatformException(e, stack); diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_task.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_task.dart index 71524a2c441e..7bf0b91e042d 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_task.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_task.dart @@ -20,18 +20,15 @@ import 'utils/exception.dart'; /// Other implementations for specific tasks should extend this class. abstract class MethodChannelTask extends TaskPlatform { /// Creates a new [MethodChannelTask] with a given task. - MethodChannelTask( - this._handle, - this.storage, - String path, - this._initialTask, - ) : super() { + MethodChannelTask(this._handle, this.storage, String path, this._initialTask) + : super() { Stream mapNativeStream() async* { final observerId = await _initialTask; final nativePlatformStream = - MethodChannelFirebaseStorage.storageTaskChannel(observerId) - .receiveBroadcastStream(); + MethodChannelFirebaseStorage.storageTaskChannel( + observerId, + ).receiveBroadcastStream(); try { await for (final events in nativePlatformStream) { final taskState = TaskState.values[events['taskState']]; @@ -61,7 +58,7 @@ abstract class MethodChannelTask extends TaskPlatform { 'path': path, 'bytesTransferred': _snapshot.bytesTransferred, 'totalBytes': _snapshot.totalBytes, - 'metadata': _snapshot.metadata + 'metadata': _snapshot.metadata, }, ); } @@ -77,9 +74,10 @@ abstract class MethodChannelTask extends TaskPlatform { if (taskState == TaskState.canceled) { _didComplete = true; MethodChannelTaskSnapshot snapshot = MethodChannelTaskSnapshot( - storage, - taskState, - Map.from(events['snapshot'])); + storage, + taskState, + Map.from(events['snapshot']), + ); _snapshot = snapshot; break; } @@ -91,9 +89,10 @@ abstract class MethodChannelTask extends TaskPlatform { && snapshot.state != TaskState.canceled) { MethodChannelTaskSnapshot snapshot = MethodChannelTaskSnapshot( - storage, - taskState, - Map.from(events['snapshot'])); + storage, + taskState, + Map.from(events['snapshot']), + ); _snapshot = snapshot; yield snapshot; @@ -113,7 +112,9 @@ abstract class MethodChannelTask extends TaskPlatform { } _stream = mapNativeStream().asBroadcastStream( - onListen: (sub) => sub.resume(), onCancel: (sub) => sub.cancel()); + onListen: (sub) => sub.resume(), + onCancel: (sub) => sub.cancel(), + ); // Keep reference to whether the initial "start" task has completed. _snapshot = MethodChannelTaskSnapshot(storage, TaskState.running, { @@ -127,7 +128,8 @@ abstract class MethodChannelTask extends TaskPlatform { /// FirebaseApp pigeon instance static InternalStorageFirebaseApp pigeonFirebaseApp( - FirebaseStoragePlatform storage) { + FirebaseStoragePlatform storage, + ) { return InternalStorageFirebaseApp( appName: storage.app.name, bucket: storage.bucket, @@ -198,15 +200,19 @@ abstract class MethodChannelTask extends TaskPlatform { @override Future pause() async { try { - Map? data = (await MethodChannelFirebaseStorage - .pigeonChannel - .taskPause(MethodChannelTask.pigeonFirebaseApp(storage), _handle)) - .cast(); + Map? data = + (await MethodChannelFirebaseStorage.pigeonChannel.taskPause( + MethodChannelTask.pigeonFirebaseApp(storage), + _handle, + )).cast(); final success = data['status'] ?? false; if (success) { - _snapshot = MethodChannelTaskSnapshot(storage, TaskState.paused, - Map.from(data['snapshot'])); + _snapshot = MethodChannelTaskSnapshot( + storage, + TaskState.paused, + Map.from(data['snapshot']), + ); } return success; } catch (e, stack) { @@ -219,13 +225,17 @@ abstract class MethodChannelTask extends TaskPlatform { try { Map? data = (await MethodChannelFirebaseStorage.pigeonChannel.taskResume( - MethodChannelTask.pigeonFirebaseApp(storage), _handle)) - .cast(); + MethodChannelTask.pigeonFirebaseApp(storage), + _handle, + )).cast(); final success = data['status'] ?? false; if (success) { - _snapshot = MethodChannelTaskSnapshot(storage, TaskState.running, - Map.from(data['snapshot'])); + _snapshot = MethodChannelTaskSnapshot( + storage, + TaskState.running, + Map.from(data['snapshot']), + ); } return success; } catch (e, stack) { @@ -238,13 +248,17 @@ abstract class MethodChannelTask extends TaskPlatform { try { Map? data = (await MethodChannelFirebaseStorage.pigeonChannel.taskCancel( - MethodChannelTask.pigeonFirebaseApp(storage), _handle)) - .cast(); + MethodChannelTask.pigeonFirebaseApp(storage), + _handle, + )).cast(); final success = data['status'] ?? false; if (success) { - _snapshot = MethodChannelTaskSnapshot(storage, TaskState.canceled, - Map.from(data['snapshot'])); + _snapshot = MethodChannelTaskSnapshot( + storage, + TaskState.canceled, + Map.from(data['snapshot']), + ); } return success; } catch (e, stack) { @@ -256,13 +270,26 @@ abstract class MethodChannelTask extends TaskPlatform { /// Implementation for [putFile] tasks. class MethodChannelPutFileTask extends MethodChannelTask { // ignore: public_member_api_docs - MethodChannelPutFileTask(int handle, FirebaseStoragePlatform storage, - String path, File file, SettableMetadata? metadata) - : super(handle, storage, path, - _getTask(handle, storage, path, file, metadata)); + MethodChannelPutFileTask( + int handle, + FirebaseStoragePlatform storage, + String path, + File file, + SettableMetadata? metadata, + ) : super( + handle, + storage, + path, + _getTask(handle, storage, path, file, metadata), + ); - static Future _getTask(int handle, FirebaseStoragePlatform storage, - String path, File file, SettableMetadata? metadata) { + static Future _getTask( + int handle, + FirebaseStoragePlatform storage, + String path, + File file, + SettableMetadata? metadata, + ) { InternalSettableMetadata? pigeonSettableMetadata; if (defaultTargetPlatform == TargetPlatform.windows) { // TODO(russellwheatley): sending null to windows throws exception so we pass empty metadata @@ -276,7 +303,10 @@ class MethodChannelPutFileTask extends MethodChannelTask { return MethodChannelFirebaseStorage.pigeonChannel.referencePutFile( MethodChannelTask.pigeonFirebaseApp(storage), MethodChannelFirebaseStorage.getPigeonReference( - storage.bucket, path, 'putFile'), + storage.bucket, + path, + 'putFile', + ), file.path, pigeonSettableMetadata, handle, @@ -288,26 +318,34 @@ class MethodChannelPutFileTask extends MethodChannelTask { class MethodChannelPutStringTask extends MethodChannelTask { // ignore: public_member_api_docs MethodChannelPutStringTask( - int handle, - FirebaseStoragePlatform storage, - String path, - String data, - PutStringFormat format, - SettableMetadata? metadata) - : super(handle, storage, path, - _getTask(handle, storage, path, data, format, metadata)); + int handle, + FirebaseStoragePlatform storage, + String path, + String data, + PutStringFormat format, + SettableMetadata? metadata, + ) : super( + handle, + storage, + path, + _getTask(handle, storage, path, data, format, metadata), + ); static Future _getTask( - int handle, - FirebaseStoragePlatform storage, - String path, - String data, - PutStringFormat format, - SettableMetadata? metadata) { + int handle, + FirebaseStoragePlatform storage, + String path, + String data, + PutStringFormat format, + SettableMetadata? metadata, + ) { return MethodChannelFirebaseStorage.pigeonChannel.referencePutString( MethodChannelTask.pigeonFirebaseApp(storage), MethodChannelFirebaseStorage.getPigeonReference( - storage.bucket, path, 'putString'), + storage.bucket, + path, + 'putString', + ), data, format.index, MethodChannelFirebaseStorage.getPigeonSettableMetaData(metadata), @@ -319,17 +357,33 @@ class MethodChannelPutStringTask extends MethodChannelTask { /// Implementation for [put] tasks. class MethodChannelPutTask extends MethodChannelTask { // ignore: public_member_api_docs - MethodChannelPutTask(int handle, FirebaseStoragePlatform storage, String path, - Uint8List data, SettableMetadata? metadata) - : super(handle, storage, path, - _getTask(handle, storage, path, data, metadata)); + MethodChannelPutTask( + int handle, + FirebaseStoragePlatform storage, + String path, + Uint8List data, + SettableMetadata? metadata, + ) : super( + handle, + storage, + path, + _getTask(handle, storage, path, data, metadata), + ); - static Future _getTask(int handle, FirebaseStoragePlatform storage, - String path, Uint8List data, SettableMetadata? metadata) { + static Future _getTask( + int handle, + FirebaseStoragePlatform storage, + String path, + Uint8List data, + SettableMetadata? metadata, + ) { return MethodChannelFirebaseStorage.pigeonChannel.referencePutData( MethodChannelTask.pigeonFirebaseApp(storage), MethodChannelFirebaseStorage.getPigeonReference( - storage.bucket, path, 'putData'), + storage.bucket, + path, + 'putData', + ), data, MethodChannelFirebaseStorage.getPigeonSettableMetaData(metadata), handle, @@ -341,15 +395,25 @@ class MethodChannelPutTask extends MethodChannelTask { class MethodChannelDownloadTask extends MethodChannelTask { // ignore: public_member_api_docs MethodChannelDownloadTask( - int handle, FirebaseStoragePlatform storage, String path, File file) - : super(handle, storage, path, _getTask(handle, storage, path, file)); + int handle, + FirebaseStoragePlatform storage, + String path, + File file, + ) : super(handle, storage, path, _getTask(handle, storage, path, file)); static Future _getTask( - int handle, FirebaseStoragePlatform storage, String path, File file) { + int handle, + FirebaseStoragePlatform storage, + String path, + File file, + ) { return MethodChannelFirebaseStorage.pigeonChannel.referenceDownloadFile( MethodChannelTask.pigeonFirebaseApp(storage), MethodChannelFirebaseStorage.getPigeonReference( - storage.bucket, path, 'writeToFile'), + storage.bucket, + path, + 'writeToFile', + ), file.path, handle, ); diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_task_snapshot.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_task_snapshot.dart index 81dccdf0d670..b4313d516f96 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_task_snapshot.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_task_snapshot.dart @@ -10,7 +10,7 @@ import 'method_channel_reference.dart'; class MethodChannelTaskSnapshot extends TaskSnapshotPlatform { // ignore: public_member_api_docs MethodChannelTaskSnapshot(this.storage, TaskState state, this._data) - : super(state, _data); + : super(state, _data); /// The [FirebaseStoragePlatform] used to create the task. final FirebaseStoragePlatform storage; diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/utils/exception.dart index e3a37ad80f78..1bf9410e9806 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/utils/exception.dart @@ -11,10 +11,7 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and returns an [Exception]. /// /// If the [Exception] is a [PlatformException], a [FirebaseException] is returned. -Never convertPlatformException( - dynamic exception, - StackTrace stackTrace, -) { +Never convertPlatformException(dynamic exception, StackTrace stackTrace) { if (exception is! Exception || exception is! PlatformException) { Error.throwWithStackTrace(exception, stackTrace); } @@ -52,7 +49,8 @@ FirebaseException platformExceptionToFirebaseException( ) { // TODO(ehesp): Add stack trace support when it lands return FirebaseException( - plugin: 'firebase_storage', - code: platformException.code, - message: platformException.message); + plugin: 'firebase_storage', + code: platformException.code, + message: platformException.message, + ); } diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/pigeon/messages.pigeon.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/pigeon/messages.pigeon.dart index ceb6abb3e6e0..015e087a450f 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/pigeon/messages.pigeon.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/pigeon/messages.pigeon.dart @@ -37,8 +37,11 @@ Object? _extractReplyValueOrThrow( return replyList.firstOrNull; } -List wrapResponse( - {Object? result, PlatformException? error, bool empty = false}) { +List wrapResponse({ + Object? result, + PlatformException? error, + bool empty = false, +}) { if (empty) { return []; } @@ -60,8 +63,9 @@ bool _deepEquals(Object? a, Object? b) { } if (a is List && b is List) { return a.length == b.length && - a.indexed - .every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1])); + a.indexed.every( + ((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]), + ); } if (a is Map && b is Map) { if (a.length != b.length) { @@ -143,11 +147,7 @@ class InternalStorageFirebaseApp { String bucket; List _toList() { - return [ - appName, - tenantId, - bucket, - ]; + return [appName, tenantId, bucket]; } Object encode() { @@ -197,11 +197,7 @@ class InternalStorageReference { String name; List _toList() { - return [ - bucket, - fullPath, - name, - ]; + return [bucket, fullPath, name]; } Object encode() { @@ -238,16 +234,12 @@ class InternalStorageReference { } class InternalFullMetaData { - InternalFullMetaData({ - this.metadata, - }); + InternalFullMetaData({this.metadata}); Map? metadata; List _toList() { - return [ - metadata, - ]; + return [metadata]; } Object encode() { @@ -279,10 +271,7 @@ class InternalFullMetaData { } class InternalListOptions { - InternalListOptions({ - required this.maxResults, - this.pageToken, - }); + InternalListOptions({required this.maxResults, this.pageToken}); /// If set, limits the total number of `prefixes` and `items` to return. /// @@ -295,10 +284,7 @@ class InternalListOptions { String? pageToken; List _toList() { - return [ - maxResults, - pageToken, - ]; + return [maxResults, pageToken]; } Object encode() { @@ -392,8 +378,8 @@ class InternalSettableMetadata { contentEncoding: result[2] as String?, contentLanguage: result[3] as String?, contentType: result[4] as String?, - customMetadata: - (result[5] as Map?)?.cast(), + customMetadata: (result[5] as Map?) + ?.cast(), ); } @@ -437,12 +423,7 @@ class InternalStorageTaskSnapShot { int totalBytes; List _toList() { - return [ - bytesTransferred, - metadata, - state, - totalBytes, - ]; + return [bytesTransferred, metadata, state, totalBytes]; } Object encode() { @@ -494,11 +475,7 @@ class InternalListResult { List prefixs; List _toList() { - return [ - items, - pageToken, - prefixs, - ]; + return [items, pageToken, prefixs]; } Object encode() { @@ -599,11 +576,13 @@ class FirebaseStorageHostApi { /// Constructor for [FirebaseStorageHostApi]. The [binaryMessenger] named argument is /// available for dependency injection. If it is left null, the default /// BinaryMessenger will be used which routes to the host platform. - FirebaseStorageHostApi( - {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) - : pigeonVar_binaryMessenger = binaryMessenger, - pigeonVar_messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + FirebaseStorageHostApi({ + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; final BinaryMessenger? pigeonVar_binaryMessenger; static const MessageCodec pigeonChannelCodec = _PigeonCodec(); @@ -611,7 +590,10 @@ class FirebaseStorageHostApi { final String pigeonVar_messageChannelSuffix; Future getReferencebyPath( - InternalStorageFirebaseApp app, String path, String? bucket) async { + InternalStorageFirebaseApp app, + String path, + String? bucket, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.getReferencebyPath$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -619,8 +601,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, path, bucket]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, path, bucket], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -632,7 +615,9 @@ class FirebaseStorageHostApi { } Future setMaxOperationRetryTime( - InternalStorageFirebaseApp app, int time) async { + InternalStorageFirebaseApp app, + int time, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxOperationRetryTime$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -640,8 +625,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, time]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, time], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -652,7 +638,9 @@ class FirebaseStorageHostApi { } Future setMaxUploadRetryTime( - InternalStorageFirebaseApp app, int time) async { + InternalStorageFirebaseApp app, + int time, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxUploadRetryTime$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -660,8 +648,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, time]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, time], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -672,7 +661,9 @@ class FirebaseStorageHostApi { } Future setMaxDownloadRetryTime( - InternalStorageFirebaseApp app, int time) async { + InternalStorageFirebaseApp app, + int time, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxDownloadRetryTime$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -680,8 +671,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, time]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, time], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -692,7 +684,10 @@ class FirebaseStorageHostApi { } Future useStorageEmulator( - InternalStorageFirebaseApp app, String host, int port) async { + InternalStorageFirebaseApp app, + String host, + int port, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.useStorageEmulator$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -700,8 +695,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, host, port]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, host, port], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -711,8 +707,10 @@ class FirebaseStorageHostApi { ); } - Future referenceDelete(InternalStorageFirebaseApp app, - InternalStorageReference reference) async { + Future referenceDelete( + InternalStorageFirebaseApp app, + InternalStorageReference reference, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceDelete$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -720,8 +718,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, reference]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, reference], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; _extractReplyValueOrThrow( @@ -731,8 +730,10 @@ class FirebaseStorageHostApi { ); } - Future referenceGetDownloadURL(InternalStorageFirebaseApp app, - InternalStorageReference reference) async { + Future referenceGetDownloadURL( + InternalStorageFirebaseApp app, + InternalStorageReference reference, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetDownloadURL$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -740,8 +741,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, reference]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, reference], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -753,8 +755,9 @@ class FirebaseStorageHostApi { } Future referenceGetMetaData( - InternalStorageFirebaseApp app, - InternalStorageReference reference) async { + InternalStorageFirebaseApp app, + InternalStorageReference reference, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetMetaData$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -762,8 +765,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, reference]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, reference], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -774,8 +778,11 @@ class FirebaseStorageHostApi { return pigeonVar_replyValue! as InternalFullMetaData; } - Future referenceList(InternalStorageFirebaseApp app, - InternalStorageReference reference, InternalListOptions options) async { + Future referenceList( + InternalStorageFirebaseApp app, + InternalStorageReference reference, + InternalListOptions options, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceList$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -783,8 +790,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, reference, options]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, reference, options], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -795,8 +803,10 @@ class FirebaseStorageHostApi { return pigeonVar_replyValue! as InternalListResult; } - Future referenceListAll(InternalStorageFirebaseApp app, - InternalStorageReference reference) async { + Future referenceListAll( + InternalStorageFirebaseApp app, + InternalStorageReference reference, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceListAll$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -804,8 +814,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, reference]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, reference], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -816,8 +827,11 @@ class FirebaseStorageHostApi { return pigeonVar_replyValue! as InternalListResult; } - Future referenceGetData(InternalStorageFirebaseApp app, - InternalStorageReference reference, int maxSize) async { + Future referenceGetData( + InternalStorageFirebaseApp app, + InternalStorageReference reference, + int maxSize, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetData$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -825,8 +839,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, reference, maxSize]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, reference, maxSize], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -838,11 +853,12 @@ class FirebaseStorageHostApi { } Future referencePutData( - InternalStorageFirebaseApp app, - InternalStorageReference reference, - Uint8List data, - InternalSettableMetadata settableMetaData, - int handle) async { + InternalStorageFirebaseApp app, + InternalStorageReference reference, + Uint8List data, + InternalSettableMetadata settableMetaData, + int handle, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutData$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -850,8 +866,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel - .send([app, reference, data, settableMetaData, handle]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, reference, data, settableMetaData, handle], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -863,12 +880,13 @@ class FirebaseStorageHostApi { } Future referencePutString( - InternalStorageFirebaseApp app, - InternalStorageReference reference, - String data, - int format, - InternalSettableMetadata settableMetaData, - int handle) async { + InternalStorageFirebaseApp app, + InternalStorageReference reference, + String data, + int format, + InternalSettableMetadata settableMetaData, + int handle, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutString$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -877,7 +895,8 @@ class FirebaseStorageHostApi { binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [app, reference, data, format, settableMetaData, handle]); + [app, reference, data, format, settableMetaData, handle], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -889,11 +908,12 @@ class FirebaseStorageHostApi { } Future referencePutFile( - InternalStorageFirebaseApp app, - InternalStorageReference reference, - String filePath, - InternalSettableMetadata? settableMetaData, - int handle) async { + InternalStorageFirebaseApp app, + InternalStorageReference reference, + String filePath, + InternalSettableMetadata? settableMetaData, + int handle, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutFile$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -901,8 +921,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel - .send([app, reference, filePath, settableMetaData, handle]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, reference, filePath, settableMetaData, handle], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -913,8 +934,12 @@ class FirebaseStorageHostApi { return pigeonVar_replyValue! as String; } - Future referenceDownloadFile(InternalStorageFirebaseApp app, - InternalStorageReference reference, String filePath, int handle) async { + Future referenceDownloadFile( + InternalStorageFirebaseApp app, + InternalStorageReference reference, + String filePath, + int handle, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceDownloadFile$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -922,8 +947,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, reference, filePath, handle]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, reference, filePath, handle], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -935,9 +961,10 @@ class FirebaseStorageHostApi { } Future referenceUpdateMetadata( - InternalStorageFirebaseApp app, - InternalStorageReference reference, - InternalSettableMetadata metadata) async { + InternalStorageFirebaseApp app, + InternalStorageReference reference, + InternalSettableMetadata metadata, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceUpdateMetadata$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -945,8 +972,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, reference, metadata]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, reference, metadata], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -958,7 +986,9 @@ class FirebaseStorageHostApi { } Future> taskPause( - InternalStorageFirebaseApp app, int handle) async { + InternalStorageFirebaseApp app, + int handle, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskPause$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -966,8 +996,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, handle]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, handle], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -980,7 +1011,9 @@ class FirebaseStorageHostApi { } Future> taskResume( - InternalStorageFirebaseApp app, int handle) async { + InternalStorageFirebaseApp app, + int handle, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskResume$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -988,8 +1021,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, handle]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, handle], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( @@ -1002,7 +1036,9 @@ class FirebaseStorageHostApi { } Future> taskCancel( - InternalStorageFirebaseApp app, int handle) async { + InternalStorageFirebaseApp app, + int handle, + ) async { final pigeonVar_channelName = 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskCancel$pigeonVar_messageChannelSuffix'; final pigeonVar_channel = BasicMessageChannel( @@ -1010,8 +1046,9 @@ class FirebaseStorageHostApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = - pigeonVar_channel.send([app, handle]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send( + [app, handle], + ); final pigeonVar_replyList = await pigeonVar_sendFuture as List?; final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_firebase_storage.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_firebase_storage.dart index 2cac970cc692..0c6388887a78 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_firebase_storage.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_firebase_storage.dart @@ -17,13 +17,17 @@ import '../method_channel/method_channel_firebase_storage.dart'; abstract class FirebaseStoragePlatform extends PlatformInterface { /// Create an instance using [app] FirebaseStoragePlatform({this.appInstance, required this.bucket}) - : super(token: _token); + : super(token: _token); /// Returns a [FirebaseStoragePlatform] with the provided arguments. - factory FirebaseStoragePlatform.instanceFor( - {required FirebaseApp app, required String bucket}) { - return FirebaseStoragePlatform.instance - .delegateFor(app: app, bucket: bucket); + factory FirebaseStoragePlatform.instanceFor({ + required FirebaseApp app, + required String bucket, + }) { + return FirebaseStoragePlatform.instance.delegateFor( + app: app, + bucket: bucket, + ); } @protected @@ -88,8 +92,10 @@ abstract class FirebaseStoragePlatform extends PlatformInterface { /// Enables delegates to create new instances of themselves if a none default /// [FirebaseApp] instance is required by the user. @protected - FirebaseStoragePlatform delegateFor( - {required FirebaseApp app, required String bucket}) { + FirebaseStoragePlatform delegateFor({ + required FirebaseApp app, + required String bucket, + }) { throw UnimplementedError('delegateFor() is not implemented'); } diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_reference.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_reference.dart index 86e005220308..8eab31d3aa61 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_reference.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_reference.dart @@ -16,8 +16,8 @@ import '../internal/pointer.dart'; abstract class ReferencePlatform extends PlatformInterface { // ignore: public_member_api_docs ReferencePlatform(this.storage, String path) - : _pointer = Pointer(path), - super(token: _token); + : _pointer = Pointer(path), + super(token: _token); Pointer _pointer; @@ -159,8 +159,11 @@ abstract class ReferencePlatform extends PlatformInterface { /// argument, the [mimeType] will be automatically set. /// - [PutStringFormat.base64] will be encoded as a Base64 string. /// - [PutStringFormat.base64Url] will be encoded as a Base64 string safe URL. - TaskPlatform putString(String data, PutStringFormat format, - [SettableMetadata? metadata]) { + TaskPlatform putString( + String data, + PutStringFormat format, [ + SettableMetadata? metadata, + ]) { throw UnimplementedError('putString() is not implemented'); } diff --git a/packages/firebase_storage/firebase_storage_platform_interface/pigeons/messages.dart b/packages/firebase_storage/firebase_storage_platform_interface/pigeons/messages.dart index 2cade8ddbef5..3f1a0c73cf39 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/pigeons/messages.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/pigeons/messages.dart @@ -68,17 +68,12 @@ class InternalStorageReference { } class InternalFullMetaData { - const InternalFullMetaData({ - required this.metadata, - }); + const InternalFullMetaData({required this.metadata}); final Map? metadata; } class InternalListOptions { - const InternalListOptions({ - required this.maxResults, - this.pageToken, - }); + const InternalListOptions({required this.maxResults, this.pageToken}); /// If set, limits the total number of `prefixes` and `items` to return. /// @@ -166,20 +161,11 @@ abstract class FirebaseStorageHostApi { String? bucket, ); @async - void setMaxOperationRetryTime( - InternalStorageFirebaseApp app, - int time, - ); + void setMaxOperationRetryTime(InternalStorageFirebaseApp app, int time); @async - void setMaxUploadRetryTime( - InternalStorageFirebaseApp app, - int time, - ); + void setMaxUploadRetryTime(InternalStorageFirebaseApp app, int time); @async - void setMaxDownloadRetryTime( - InternalStorageFirebaseApp app, - int time, - ); + void setMaxDownloadRetryTime(InternalStorageFirebaseApp app, int time); @async void useStorageEmulator( @@ -273,20 +259,11 @@ abstract class FirebaseStorageHostApi { // APIs for Task class @async - Map taskPause( - InternalStorageFirebaseApp app, - int handle, - ); + Map taskPause(InternalStorageFirebaseApp app, int handle); @async - Map taskResume( - InternalStorageFirebaseApp app, - int handle, - ); + Map taskResume(InternalStorageFirebaseApp app, int handle); @async - Map taskCancel( - InternalStorageFirebaseApp app, - int handle, - ); + Map taskCancel(InternalStorageFirebaseApp app, int handle); } diff --git a/packages/firebase_storage/firebase_storage_platform_interface/pubspec.yaml b/packages/firebase_storage/firebase_storage_platform_interface/pubspec.yaml index 4a07bcec5e2c..111d1b571c15 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/pubspec.yaml +++ b/packages/firebase_storage/firebase_storage_platform_interface/pubspec.yaml @@ -6,8 +6,8 @@ homepage: https://github.com/firebase/flutterfire/tree/main/packages/firebase_st repository: https://github.com/firebase/flutterfire/tree/main/packages/firebase_storage/firebase_storage_platform_interface environment: - sdk: '^3.6.0' - flutter: '>=3.27.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_storage/firebase_storage_platform_interface/test/method_channel_tests/method_channel_firebase_storage_test.dart b/packages/firebase_storage/firebase_storage_platform_interface/test/method_channel_tests/method_channel_firebase_storage_test.dart index 0bf48127a2cd..1e81c1543200 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/test/method_channel_tests/method_channel_firebase_storage_test.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/test/method_channel_tests/method_channel_firebase_storage_test.dart @@ -37,42 +37,56 @@ void main() { group('constructor', () { test('should create an instance with no args', () { - MethodChannelFirebaseStorage test = - MethodChannelFirebaseStorage(app: app, bucket: kBucket); + MethodChannelFirebaseStorage test = MethodChannelFirebaseStorage( + app: app, + bucket: kBucket, + ); expect(test.app, equals(Firebase.app())); }); test('create an instance with default app', () { - MethodChannelFirebaseStorage test = - MethodChannelFirebaseStorage(app: Firebase.app(), bucket: ''); + MethodChannelFirebaseStorage test = MethodChannelFirebaseStorage( + app: Firebase.app(), + bucket: '', + ); expect(test.app, equals(Firebase.app())); }); test('create an instance with a secondary app', () { - MethodChannelFirebaseStorage test = - MethodChannelFirebaseStorage(app: secondaryApp, bucket: ''); + MethodChannelFirebaseStorage test = MethodChannelFirebaseStorage( + app: secondaryApp, + bucket: '', + ); expect(test.app, equals(secondaryApp)); }); test('allow multiple instances', () { - MethodChannelFirebaseStorage test1 = - MethodChannelFirebaseStorage(app: Firebase.app(), bucket: ''); - MethodChannelFirebaseStorage test2 = - MethodChannelFirebaseStorage(app: secondaryApp, bucket: ''); + MethodChannelFirebaseStorage test1 = MethodChannelFirebaseStorage( + app: Firebase.app(), + bucket: '', + ); + MethodChannelFirebaseStorage test2 = MethodChannelFirebaseStorage( + app: secondaryApp, + bucket: '', + ); expect(test1.app, equals(Firebase.app())); expect(test2.app, equals(secondaryApp)); }); }); test('instance', () { - expect(MethodChannelFirebaseStorage.instance, - isInstanceOf()); + expect( + MethodChannelFirebaseStorage.instance, + isInstanceOf(), + ); }); test('nextMethodChannelHandleId', () { final handleId = MethodChannelFirebaseStorage.nextMethodChannelHandleId; expect( - MethodChannelFirebaseStorage.nextMethodChannelHandleId, handleId + 1); + MethodChannelFirebaseStorage.nextMethodChannelHandleId, + handleId + 1, + ); nextMockHandleId; nextMockHandleId; @@ -103,5 +117,5 @@ void main() { class TestMethodChannelFirebaseStorage extends MethodChannelFirebaseStorage { TestMethodChannelFirebaseStorage(FirebaseApp app) - : super(app: app, bucket: ''); + : super(app: app, bucket: ''); } diff --git a/packages/firebase_storage/firebase_storage_platform_interface/test/method_channel_tests/method_channel_list_result_test.dart b/packages/firebase_storage/firebase_storage_platform_interface/test/method_channel_tests/method_channel_list_result_test.dart index 9a3cacdeb25b..11b11f47f433 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/test/method_channel_tests/method_channel_list_result_test.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/test/method_channel_tests/method_channel_list_result_test.dart @@ -19,8 +19,10 @@ void main() { group('$MethodChannelListResult', () { setUpAll(() async { FirebaseApp app = await Firebase.initializeApp(); - FirebaseStoragePlatform storage = - MethodChannelFirebaseStorage(app: app, bucket: ''); + FirebaseStoragePlatform storage = MethodChannelFirebaseStorage( + app: app, + bucket: '', + ); testListResult = MethodChannelListResult( storage, nextPageToken: '123', diff --git a/packages/firebase_storage/firebase_storage_platform_interface/test/method_channel_tests/method_channel_reference_test.dart b/packages/firebase_storage/firebase_storage_platform_interface/test/method_channel_tests/method_channel_reference_test.dart index 32d96c068d30..10a47633c0e1 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/test/method_channel_tests/method_channel_reference_test.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/test/method_channel_tests/method_channel_reference_test.dart @@ -24,8 +24,9 @@ void main() { const String bucketParam = 'bucket-test'; final kMetadata = SettableMetadata( - contentLanguage: 'en', - customMetadata: {'activity': 'test'}); + contentLanguage: 'en', + customMetadata: {'activity': 'test'}, + ); const kListOptions = ListOptions(maxResults: 20); group('$MethodChannelReference', () { @@ -49,52 +50,57 @@ void main() { group('delete', () { test( - 'catch a [PlatformException] error and throws a [FirebaseException] error', - () async { - Function callMethod; - callMethod = () => ref.delete(); - await testExceptionHandling('PLATFORM', callMethod); - }); + 'catch a [PlatformException] error and throws a [FirebaseException] error', + () async { + Function callMethod; + callMethod = () => ref.delete(); + await testExceptionHandling('PLATFORM', callMethod); + }, + ); }); group('getDownloadURL', () { test( - 'catch a [PlatformException] error and throws a [FirebaseException] error', - () async { - Function callMethod; - callMethod = () => ref.getDownloadURL(); - await testExceptionHandling('PLATFORM', callMethod); - }); + 'catch a [PlatformException] error and throws a [FirebaseException] error', + () async { + Function callMethod; + callMethod = () => ref.getDownloadURL(); + await testExceptionHandling('PLATFORM', callMethod); + }, + ); }); group('getMetadata', () { test( - 'catch a [PlatformException] error and throws a [FirebaseStorageException] error', - () async { - Function callMethod; - callMethod = () => ref.getMetadata(); - await testExceptionHandling('PLATFORM', callMethod); - }); + 'catch a [PlatformException] error and throws a [FirebaseStorageException] error', + () async { + Function callMethod; + callMethod = () => ref.getMetadata(); + await testExceptionHandling('PLATFORM', callMethod); + }, + ); }); group('list', () { test( - 'catch a [PlatformException] error and throws a [FirebaseStorageException] error', - () async { - Function callMethod; - callMethod = () => ref.list(kListOptions); - await testExceptionHandling('PLATFORM', callMethod); - }); + 'catch a [PlatformException] error and throws a [FirebaseStorageException] error', + () async { + Function callMethod; + callMethod = () => ref.list(kListOptions); + await testExceptionHandling('PLATFORM', callMethod); + }, + ); }); group('listAll', () { test( - 'catch a [PlatformException] error and throws a [FirebaseStorageException] error', - () async { - Function callMethod; - callMethod = () => ref.listAll(); - await testExceptionHandling('PLATFORM', callMethod); - }); + 'catch a [PlatformException] error and throws a [FirebaseStorageException] error', + () async { + Function callMethod; + callMethod = () => ref.listAll(); + await testExceptionHandling('PLATFORM', callMethod); + }, + ); }); group('putBlob', () { @@ -108,12 +114,13 @@ void main() { group('updateMetadata', () { test( - 'catch a [PlatformException] error and throws a [FirebaseException] error', - () async { - Function callMethod; - callMethod = () => ref.updateMetadata(kMetadata); - await testExceptionHandling('PLATFORM', callMethod); - }); + 'catch a [PlatformException] error and throws a [FirebaseException] error', + () async { + Function callMethod; + callMethod = () => ref.updateMetadata(kMetadata); + await testExceptionHandling('PLATFORM', callMethod); + }, + ); }); }); } diff --git a/packages/firebase_storage/firebase_storage_platform_interface/test/mock.dart b/packages/firebase_storage/firebase_storage_platform_interface/test/mock.dart index 7e6328a0a6c8..ca5ce433f58d 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/test/mock.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/test/mock.dart @@ -23,10 +23,11 @@ void setupFirebaseStorageMocks([Callback? customHandlers]) { void handleMethodCall(MethodCallCallback methodCallCallback) => TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(MethodChannelFirebaseStorage.channel, - (call) async { - return await methodCallCallback(call); - }); + .setMockMethodCallHandler(MethodChannelFirebaseStorage.channel, ( + call, + ) async { + return await methodCallCallback(call); + }); Future testExceptionHandling(String type, Function testMethod) async { try { @@ -37,7 +38,8 @@ Future testExceptionHandling(String type, Function testMethod) async { return; } fail( - 'testExceptionHandling: $testMethod threw unexpected FirebaseException'); + 'testExceptionHandling: $testMethod threw unexpected FirebaseException', + ); } catch (e) { fail('testExceptionHandling: $testMethod threw invalid exception $e'); } diff --git a/packages/firebase_storage/firebase_storage_platform_interface/test/pigeon/test_api.dart b/packages/firebase_storage/firebase_storage_platform_interface/test/pigeon/test_api.dart index 13214ad904ab..04e0487f9fd9 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/test/pigeon/test_api.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/test/pigeon/test_api.dart @@ -81,665 +81,853 @@ abstract class TestFirebaseStorageHostApi { static const MessageCodec pigeonChannelCodec = _PigeonCodec(); Future getReferencebyPath( - InternalStorageFirebaseApp app, String path, String? bucket); + InternalStorageFirebaseApp app, + String path, + String? bucket, + ); Future setMaxOperationRetryTime( - InternalStorageFirebaseApp app, int time); + InternalStorageFirebaseApp app, + int time, + ); Future setMaxUploadRetryTime(InternalStorageFirebaseApp app, int time); Future setMaxDownloadRetryTime( - InternalStorageFirebaseApp app, int time); + InternalStorageFirebaseApp app, + int time, + ); Future useStorageEmulator( - InternalStorageFirebaseApp app, String host, int port); + InternalStorageFirebaseApp app, + String host, + int port, + ); Future referenceDelete( - InternalStorageFirebaseApp app, InternalStorageReference reference); + InternalStorageFirebaseApp app, + InternalStorageReference reference, + ); Future referenceGetDownloadURL( - InternalStorageFirebaseApp app, InternalStorageReference reference); + InternalStorageFirebaseApp app, + InternalStorageReference reference, + ); Future referenceGetMetaData( - InternalStorageFirebaseApp app, InternalStorageReference reference); + InternalStorageFirebaseApp app, + InternalStorageReference reference, + ); - Future referenceList(InternalStorageFirebaseApp app, - InternalStorageReference reference, InternalListOptions options); + Future referenceList( + InternalStorageFirebaseApp app, + InternalStorageReference reference, + InternalListOptions options, + ); Future referenceListAll( - InternalStorageFirebaseApp app, InternalStorageReference reference); + InternalStorageFirebaseApp app, + InternalStorageReference reference, + ); - Future referenceGetData(InternalStorageFirebaseApp app, - InternalStorageReference reference, int maxSize); + Future referenceGetData( + InternalStorageFirebaseApp app, + InternalStorageReference reference, + int maxSize, + ); Future referencePutData( - InternalStorageFirebaseApp app, - InternalStorageReference reference, - Uint8List data, - InternalSettableMetadata settableMetaData, - int handle); + InternalStorageFirebaseApp app, + InternalStorageReference reference, + Uint8List data, + InternalSettableMetadata settableMetaData, + int handle, + ); Future referencePutString( - InternalStorageFirebaseApp app, - InternalStorageReference reference, - String data, - int format, - InternalSettableMetadata settableMetaData, - int handle); + InternalStorageFirebaseApp app, + InternalStorageReference reference, + String data, + int format, + InternalSettableMetadata settableMetaData, + int handle, + ); Future referencePutFile( - InternalStorageFirebaseApp app, - InternalStorageReference reference, - String filePath, - InternalSettableMetadata? settableMetaData, - int handle); + InternalStorageFirebaseApp app, + InternalStorageReference reference, + String filePath, + InternalSettableMetadata? settableMetaData, + int handle, + ); - Future referenceDownloadFile(InternalStorageFirebaseApp app, - InternalStorageReference reference, String filePath, int handle); + Future referenceDownloadFile( + InternalStorageFirebaseApp app, + InternalStorageReference reference, + String filePath, + int handle, + ); Future referenceUpdateMetadata( - InternalStorageFirebaseApp app, - InternalStorageReference reference, - InternalSettableMetadata metadata); + InternalStorageFirebaseApp app, + InternalStorageReference reference, + InternalSettableMetadata metadata, + ); Future> taskPause( - InternalStorageFirebaseApp app, int handle); + InternalStorageFirebaseApp app, + int handle, + ); Future> taskResume( - InternalStorageFirebaseApp app, int handle); + InternalStorageFirebaseApp app, + int handle, + ); Future> taskCancel( - InternalStorageFirebaseApp app, int handle); + InternalStorageFirebaseApp app, + int handle, + ); static void setUp( TestFirebaseStorageHostApi? api, { BinaryMessenger? binaryMessenger, String messageChannelSuffix = '', }) { - messageChannelSuffix = - messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + messageChannelSuffix = messageChannelSuffix.isNotEmpty + ? '.$messageChannelSuffix' + : ''; { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.getReferencebyPath$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.getReferencebyPath$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final String arg_path = args[1]! as String; - final String? arg_bucket = args[2] as String?; - try { - final InternalStorageReference output = - await api.getReferencebyPath(arg_app, arg_path, arg_bucket); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final String arg_path = args[1]! as String; + final String? arg_bucket = args[2] as String?; + try { + final InternalStorageReference output = await api + .getReferencebyPath(arg_app, arg_path, arg_bucket); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxOperationRetryTime$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxOperationRetryTime$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final int arg_time = args[1]! as int; - try { - await api.setMaxOperationRetryTime(arg_app, arg_time); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final int arg_time = args[1]! as int; + try { + await api.setMaxOperationRetryTime(arg_app, arg_time); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxUploadRetryTime$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxUploadRetryTime$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final int arg_time = args[1]! as int; - try { - await api.setMaxUploadRetryTime(arg_app, arg_time); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final int arg_time = args[1]! as int; + try { + await api.setMaxUploadRetryTime(arg_app, arg_time); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxDownloadRetryTime$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxDownloadRetryTime$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final int arg_time = args[1]! as int; - try { - await api.setMaxDownloadRetryTime(arg_app, arg_time); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final int arg_time = args[1]! as int; + try { + await api.setMaxDownloadRetryTime(arg_app, arg_time); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.useStorageEmulator$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.useStorageEmulator$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final String arg_host = args[1]! as String; - final int arg_port = args[2]! as int; - try { - await api.useStorageEmulator(arg_app, arg_host, arg_port); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final String arg_host = args[1]! as String; + final int arg_port = args[2]! as int; + try { + await api.useStorageEmulator(arg_app, arg_host, arg_port); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceDelete$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceDelete$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final InternalStorageReference arg_reference = - args[1]! as InternalStorageReference; - try { - await api.referenceDelete(arg_app, arg_reference); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final InternalStorageReference arg_reference = + args[1]! as InternalStorageReference; + try { + await api.referenceDelete(arg_app, arg_reference); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetDownloadURL$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetDownloadURL$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final InternalStorageReference arg_reference = - args[1]! as InternalStorageReference; - try { - final String output = - await api.referenceGetDownloadURL(arg_app, arg_reference); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final InternalStorageReference arg_reference = + args[1]! as InternalStorageReference; + try { + final String output = await api.referenceGetDownloadURL( + arg_app, + arg_reference, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetMetaData$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetMetaData$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final InternalStorageReference arg_reference = - args[1]! as InternalStorageReference; - try { - final InternalFullMetaData output = - await api.referenceGetMetaData(arg_app, arg_reference); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final InternalStorageReference arg_reference = + args[1]! as InternalStorageReference; + try { + final InternalFullMetaData output = await api + .referenceGetMetaData(arg_app, arg_reference); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceList$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceList$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final InternalStorageReference arg_reference = - args[1]! as InternalStorageReference; - final InternalListOptions arg_options = - args[2]! as InternalListOptions; - try { - final InternalListResult output = - await api.referenceList(arg_app, arg_reference, arg_options); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final InternalStorageReference arg_reference = + args[1]! as InternalStorageReference; + final InternalListOptions arg_options = + args[2]! as InternalListOptions; + try { + final InternalListResult output = await api.referenceList( + arg_app, + arg_reference, + arg_options, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceListAll$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceListAll$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final InternalStorageReference arg_reference = - args[1]! as InternalStorageReference; - try { - final InternalListResult output = - await api.referenceListAll(arg_app, arg_reference); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final InternalStorageReference arg_reference = + args[1]! as InternalStorageReference; + try { + final InternalListResult output = await api.referenceListAll( + arg_app, + arg_reference, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetData$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetData$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final InternalStorageReference arg_reference = - args[1]! as InternalStorageReference; - final int arg_maxSize = args[2]! as int; - try { - final Uint8List? output = - await api.referenceGetData(arg_app, arg_reference, arg_maxSize); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final InternalStorageReference arg_reference = + args[1]! as InternalStorageReference; + final int arg_maxSize = args[2]! as int; + try { + final Uint8List? output = await api.referenceGetData( + arg_app, + arg_reference, + arg_maxSize, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutData$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutData$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final InternalStorageReference arg_reference = - args[1]! as InternalStorageReference; - final Uint8List arg_data = args[2]! as Uint8List; - final InternalSettableMetadata arg_settableMetaData = - args[3]! as InternalSettableMetadata; - final int arg_handle = args[4]! as int; - try { - final String output = await api.referencePutData(arg_app, - arg_reference, arg_data, arg_settableMetaData, arg_handle); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final InternalStorageReference arg_reference = + args[1]! as InternalStorageReference; + final Uint8List arg_data = args[2]! as Uint8List; + final InternalSettableMetadata arg_settableMetaData = + args[3]! as InternalSettableMetadata; + final int arg_handle = args[4]! as int; + try { + final String output = await api.referencePutData( + arg_app, + arg_reference, + arg_data, + arg_settableMetaData, + arg_handle, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutString$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutString$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final InternalStorageReference arg_reference = - args[1]! as InternalStorageReference; - final String arg_data = args[2]! as String; - final int arg_format = args[3]! as int; - final InternalSettableMetadata arg_settableMetaData = - args[4]! as InternalSettableMetadata; - final int arg_handle = args[5]! as int; - try { - final String output = await api.referencePutString( - arg_app, - arg_reference, - arg_data, - arg_format, - arg_settableMetaData, - arg_handle); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final InternalStorageReference arg_reference = + args[1]! as InternalStorageReference; + final String arg_data = args[2]! as String; + final int arg_format = args[3]! as int; + final InternalSettableMetadata arg_settableMetaData = + args[4]! as InternalSettableMetadata; + final int arg_handle = args[5]! as int; + try { + final String output = await api.referencePutString( + arg_app, + arg_reference, + arg_data, + arg_format, + arg_settableMetaData, + arg_handle, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutFile$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutFile$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final InternalStorageReference arg_reference = - args[1]! as InternalStorageReference; - final String arg_filePath = args[2]! as String; - final InternalSettableMetadata? arg_settableMetaData = - args[3] as InternalSettableMetadata?; - final int arg_handle = args[4]! as int; - try { - final String output = await api.referencePutFile(arg_app, - arg_reference, arg_filePath, arg_settableMetaData, arg_handle); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final InternalStorageReference arg_reference = + args[1]! as InternalStorageReference; + final String arg_filePath = args[2]! as String; + final InternalSettableMetadata? arg_settableMetaData = + args[3] as InternalSettableMetadata?; + final int arg_handle = args[4]! as int; + try { + final String output = await api.referencePutFile( + arg_app, + arg_reference, + arg_filePath, + arg_settableMetaData, + arg_handle, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceDownloadFile$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceDownloadFile$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final InternalStorageReference arg_reference = - args[1]! as InternalStorageReference; - final String arg_filePath = args[2]! as String; - final int arg_handle = args[3]! as int; - try { - final String output = await api.referenceDownloadFile( - arg_app, arg_reference, arg_filePath, arg_handle); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final InternalStorageReference arg_reference = + args[1]! as InternalStorageReference; + final String arg_filePath = args[2]! as String; + final int arg_handle = args[3]! as int; + try { + final String output = await api.referenceDownloadFile( + arg_app, + arg_reference, + arg_filePath, + arg_handle, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceUpdateMetadata$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceUpdateMetadata$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final InternalStorageReference arg_reference = - args[1]! as InternalStorageReference; - final InternalSettableMetadata arg_metadata = - args[2]! as InternalSettableMetadata; - try { - final InternalFullMetaData output = await api - .referenceUpdateMetadata(arg_app, arg_reference, arg_metadata); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final InternalStorageReference arg_reference = + args[1]! as InternalStorageReference; + final InternalSettableMetadata arg_metadata = + args[2]! as InternalSettableMetadata; + try { + final InternalFullMetaData output = await api + .referenceUpdateMetadata( + arg_app, + arg_reference, + arg_metadata, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskPause$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskPause$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final int arg_handle = args[1]! as int; - try { - final Map output = - await api.taskPause(arg_app, arg_handle); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final int arg_handle = args[1]! as int; + try { + final Map output = await api.taskPause( + arg_app, + arg_handle, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskResume$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskResume$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final int arg_handle = args[1]! as int; - try { - final Map output = - await api.taskResume(arg_app, arg_handle); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final int arg_handle = args[1]! as int; + try { + final Map output = await api.taskResume( + arg_app, + arg_handle, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } { final pigeonVar_channel = BasicMessageChannel( - 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskCancel$messageChannelSuffix', - pigeonChannelCodec, - binaryMessenger: binaryMessenger); + 'dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskCancel$messageChannelSuffix', + pigeonChannelCodec, + binaryMessenger: binaryMessenger, + ); if (api == null) { _testBinaryMessengerBinding!.defaultBinaryMessenger .setMockDecodedMessageHandler(pigeonVar_channel, null); } else { _testBinaryMessengerBinding!.defaultBinaryMessenger - .setMockDecodedMessageHandler(pigeonVar_channel, - (Object? message) async { - final List args = message! as List; - final InternalStorageFirebaseApp arg_app = - args[0]! as InternalStorageFirebaseApp; - final int arg_handle = args[1]! as int; - try { - final Map output = - await api.taskCancel(arg_app, arg_handle); - return [output]; - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse( - error: PlatformException(code: 'error', message: e.toString())); - } - }); + .setMockDecodedMessageHandler(pigeonVar_channel, ( + Object? message, + ) async { + final List args = message! as List; + final InternalStorageFirebaseApp arg_app = + args[0]! as InternalStorageFirebaseApp; + final int arg_handle = args[1]! as int; + try { + final Map output = await api.taskCancel( + arg_app, + arg_handle, + ); + return [output]; + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException( + code: 'error', + message: e.toString(), + ), + ); + } + }); } } } diff --git a/packages/firebase_storage/firebase_storage_platform_interface/test/platform_interface_tests/platform_interface_firebase_storage_test.dart b/packages/firebase_storage/firebase_storage_platform_interface/test/platform_interface_tests/platform_interface_firebase_storage_test.dart index 0341f250c042..3ae1a51e9fd6 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/test/platform_interface_tests/platform_interface_firebase_storage_test.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/test/platform_interface_tests/platform_interface_firebase_storage_test.dart @@ -59,17 +59,22 @@ void main() { test('get.instance', () { expect(FirebaseStoragePlatform.instance, isA()); - expect(FirebaseStoragePlatform.instance.app.name, - equals(defaultFirebaseAppName)); + expect( + FirebaseStoragePlatform.instance.app.name, + equals(defaultFirebaseAppName), + ); }); group('set.instance', () { test('sets the current instance', () { - FirebaseStoragePlatform.instance = - TestFirebaseStoragePlatform(secondaryApp); + FirebaseStoragePlatform.instance = TestFirebaseStoragePlatform( + secondaryApp, + ); expect( - FirebaseStoragePlatform.instance, isA()); + FirebaseStoragePlatform.instance, + isA(), + ); expect(FirebaseStoragePlatform.instance.app.name, equals('testApp2')); }); }); @@ -89,7 +94,9 @@ void main() { firebaseStoragePlatform!.maxOperationRetryTime; } on UnimplementedError catch (e) { expect( - e.message, equals('get.maxOperationRetryTime is not implemented')); + e.message, + equals('get.maxOperationRetryTime is not implemented'), + ); return; } fail('Should have thrown an [UnimplementedError]'); @@ -110,7 +117,9 @@ void main() { firebaseStoragePlatform!.maxDownloadRetryTime; } on UnimplementedError catch (e) { expect( - e.message, equals('get.maxDownloadRetryTime is not implemented')); + e.message, + equals('get.maxDownloadRetryTime is not implemented'), + ); return; } fail('Should have thrown an [UnimplementedError]'); @@ -121,7 +130,9 @@ void main() { firebaseStoragePlatform!.setMaxOperationRetryTime(100); } on UnimplementedError catch (e) { expect( - e.message, equals('setMaxOperationRetryTime() is not implemented')); + e.message, + equals('setMaxOperationRetryTime() is not implemented'), + ); return; } fail('Should have thrown an [UnimplementedError]'); @@ -142,7 +153,9 @@ void main() { firebaseStoragePlatform!.setMaxDownloadRetryTime(100); } on UnimplementedError catch (e) { expect( - e.message, equals('setMaxDownloadRetryTime() is not implemented')); + e.message, + equals('setMaxDownloadRetryTime() is not implemented'), + ); return; } fail('Should have thrown an [UnimplementedError]'); @@ -172,7 +185,7 @@ void main() { class TestFirebaseStoragePlatform extends FirebaseStoragePlatform { TestFirebaseStoragePlatform(FirebaseApp? app) - : super(appInstance: app, bucket: ''); + : super(appInstance: app, bucket: ''); FirebaseStoragePlatform testDelegateFor({FirebaseApp? app}) { return delegateFor(app: Firebase.app(), bucket: ''); } diff --git a/packages/firebase_storage/firebase_storage_platform_interface/test/platform_interface_tests/platform_interface_list_result_test.dart b/packages/firebase_storage/firebase_storage_platform_interface/test/platform_interface_tests/platform_interface_list_result_test.dart index 677611620b40..3c1d0fe7aa6e 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/test/platform_interface_tests/platform_interface_list_result_test.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/test/platform_interface_tests/platform_interface_list_result_test.dart @@ -23,8 +23,10 @@ void main() { setUpAll(() async { app = await Firebase.initializeApp(); firebaseStoragePlatform = TestFirebaseStoragePlatform(app); - listResultPlatform = - TestListResultPlatform(firebaseStoragePlatform, 'foo'); + listResultPlatform = TestListResultPlatform( + firebaseStoragePlatform, + 'foo', + ); }); test('Constructor', () { @@ -67,11 +69,12 @@ void main() { class TestListResultPlatform extends ListResultPlatform { TestListResultPlatform( - FirebaseStoragePlatform? storage, String? nextPageToken) - : super(storage, nextPageToken); + FirebaseStoragePlatform? storage, + String? nextPageToken, + ) : super(storage, nextPageToken); } class TestFirebaseStoragePlatform extends FirebaseStoragePlatform { TestFirebaseStoragePlatform(FirebaseApp? app) - : super(appInstance: app, bucket: ''); + : super(appInstance: app, bucket: ''); } diff --git a/packages/firebase_storage/firebase_storage_platform_interface/test/platform_interface_tests/platform_interface_reference_test.dart b/packages/firebase_storage/firebase_storage_platform_interface/test/platform_interface_tests/platform_interface_reference_test.dart index 6fe7654183c1..c65ac3efca0a 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/test/platform_interface_tests/platform_interface_reference_test.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/test/platform_interface_tests/platform_interface_reference_test.dart @@ -23,8 +23,10 @@ void main() { setUpAll(() async { app = await Firebase.initializeApp(); firebaseStoragePlatform = TestFirebaseStoragePlatform(app, 'foo'); - referencePlatform = - TestReferencePlatform(firebaseStoragePlatform, '/foo'); + referencePlatform = TestReferencePlatform( + firebaseStoragePlatform, + '/foo', + ); }); test('Constructor', () { @@ -162,10 +164,10 @@ void main() { class TestReferencePlatform extends ReferencePlatform { TestReferencePlatform(FirebaseStoragePlatform storage, String path) - : super(storage, path); + : super(storage, path); } class TestFirebaseStoragePlatform extends FirebaseStoragePlatform { TestFirebaseStoragePlatform(FirebaseApp? app, String bucket) - : super(appInstance: app, bucket: bucket); + : super(appInstance: app, bucket: bucket); } diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/firebase_storage_web.dart b/packages/firebase_storage/firebase_storage_web/lib/src/firebase_storage_web.dart index 506e8cf75451..11bcfc3b0847 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/firebase_storage_web.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/firebase_storage_web.dart @@ -18,27 +18,27 @@ import 'utils/errors.dart'; /// The type for functions that implement the `ref` method of the [FirebaseStorageWeb] class. @visibleForTesting -typedef ReferenceBuilder = ReferencePlatform Function( - FirebaseStorageWeb storage, String path); +typedef ReferenceBuilder = + ReferencePlatform Function(FirebaseStorageWeb storage, String path); /// The Web implementation of the FirebaseStoragePlatform. class FirebaseStorageWeb extends FirebaseStoragePlatform { /// Construct the plugin. FirebaseStorageWeb({FirebaseApp? app, required String bucket}) - : _bucket = bucket, - super(appInstance: app, bucket: bucket); + : _bucket = bucket, + super(appInstance: app, bucket: bucket); /// Create a FirebaseStorageWeb injecting a [fb.Storage] object. @visibleForTesting - FirebaseStorageWeb.forMock(this._webStorage, - {required String bucket, FirebaseApp? app}) - : super(appInstance: app, bucket: bucket); + FirebaseStorageWeb.forMock( + this._webStorage, { + required String bucket, + FirebaseApp? app, + }) : super(appInstance: app, bucket: bucket); // Empty constructor. This is only used by the registerWith method. // superclass also needs to be initialized and 'bucket' param is required. - FirebaseStorageWeb._nullInstance() - : _webStorage = null, - super(bucket: ''); + FirebaseStorageWeb._nullInstance() : _webStorage = null, super(bucket: ''); static const String _libraryName = 'flutter-fire-gcs'; /// The js-interop layer for Firebase Storage @@ -49,8 +49,10 @@ class FirebaseStorageWeb extends FirebaseStoragePlatform { /// Lazily initialize [webStorage] on first method call storage_interop.Storage get delegate { - return _webStorage ??= - storage_interop.getStorageInstance(core_interop.app(app.name), _bucket); + return _webStorage ??= storage_interop.getStorageInstance( + core_interop.app(app.name), + _bucket, + ); } // Same default as the method channel implementation @@ -69,8 +71,10 @@ class FirebaseStorageWeb extends FirebaseStoragePlatform { /// Returns a [FirebaseStorageWeb] with the provided arguments. @override - FirebaseStoragePlatform delegateFor( - {FirebaseApp? app, required String bucket}) { + FirebaseStoragePlatform delegateFor({ + FirebaseApp? app, + required String bucket, + }) { return FirebaseStorageWeb(app: app, bucket: bucket); } diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage.dart b/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage.dart index b4b830d7db72..92c304ea6f56 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage.dart @@ -25,12 +25,15 @@ enum TaskState { RUNNING, PAUSED, SUCCESS, CANCELED, ERROR } /// Given an AppJSImp, return the Storage instance. Storage getStorageInstance([App? app, String? bucket]) { - core_interop.App appImpl = - app != null ? core_interop.app(app.name) : core_interop.app(); - - return Storage.getInstance(bucket != null - ? storage_interop.getStorage(appImpl.jsObject, bucket.toJS) - : storage_interop.getStorage(appImpl.jsObject)); + core_interop.App appImpl = app != null + ? core_interop.app(app.name) + : core_interop.app(); + + return Storage.getInstance( + bucket != null + ? storage_interop.getStorage(appImpl.jsObject, bucket.toJS) + : storage_interop.getStorage(appImpl.jsObject), + ); } /// A service for uploading and downloading large objects to and from the @@ -39,7 +42,7 @@ Storage getStorageInstance([App? app, String? bucket]) { /// See: class Storage extends JsObjectWrapper { Storage._fromJsObject(storage_interop.StorageJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); static final _expando = Expando(); @@ -60,11 +63,13 @@ class Storage extends JsObjectWrapper { /// Returns a [StorageReference] for the given [path] in the default bucket. StorageReference ref([String? path]) => StorageReference.getInstance( - storage_interop.ref(jsObject as JSAny, path?.toJS)); + storage_interop.ref(jsObject as JSAny, path?.toJS), + ); /// Returns a [StorageReference] for the given absolute [url]. StorageReference refFromURL(String url) => StorageReference.getInstance( - storage_interop.ref(jsObject as JSAny, url.toJS)); + storage_interop.ref(jsObject as JSAny, url.toJS), + ); /// Sets the maximum operation retry time to a value of [time]. set maxOperationRetryTime(int time) { @@ -92,7 +97,7 @@ class Storage extends JsObjectWrapper { class StorageReference extends JsObjectWrapper { StorageReference._fromJsObject(storage_interop.ReferenceJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); static final _expando = Expando(); @@ -119,14 +124,16 @@ class StorageReference /// Creates a new StorageReference from a [jsObject]. static StorageReference getInstance( - storage_interop.ReferenceJsImpl jsObject) { + storage_interop.ReferenceJsImpl jsObject, + ) { return _expando[jsObject] ??= StorageReference._fromJsObject(jsObject); } /// Returns a child StorageReference to a relative [path] /// from the actual reference. StorageReference child(String path) => StorageReference.getInstance( - storage_interop.ref(jsObject as JSAny, path.toJS)); + storage_interop.ref(jsObject as JSAny, path.toJS), + ); /// Deletes the object at the actual location. Future delete() => storage_interop.deleteObject(jsObject).toDart; @@ -184,7 +191,10 @@ class StorageReference storage_interop.UploadTaskJsImpl taskImpl; if (metadata != null) { taskImpl = storage_interop.uploadBytesResumable( - jsObject, blob, metadata.jsObject); + jsObject, + blob, + metadata.jsObject, + ); } else { taskImpl = storage_interop.uploadBytesResumable(jsObject, blob); } @@ -252,14 +262,15 @@ class FullMetadata class UploadMetadata extends _UploadMetadataBase { /// Creates a new UploadMetadata with optional metadata parameters. - factory UploadMetadata( - {String? md5Hash, - String? cacheControl, - String? contentDisposition, - String? contentEncoding, - String? contentLanguage, - String? contentType, - Map? customMetadata}) { + factory UploadMetadata({ + String? md5Hash, + String? cacheControl, + String? contentDisposition, + String? contentEncoding, + String? contentLanguage, + String? contentType, + Map? customMetadata, + }) { final metadata = storage_interop.UploadMetadataJsImpl(); if (md5Hash != null) { @@ -288,13 +299,14 @@ class UploadMetadata /// Creates a new UploadMetadata from a [jsObject]. UploadMetadata.fromJsObject(storage_interop.UploadMetadataJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); } // TODO(kevmoo) - figure out if a settable md5Hash makes any sense // See https://stackoverflow.com/q/44959703/39827 abstract class _UploadMetadataBase< - T extends storage_interop.UploadMetadataJsImpl> + T extends storage_interop.UploadMetadataJsImpl +> extends _SettableMetadataBase { _UploadMetadataBase.fromJsObject(T jsObject) : super.fromJsObject(jsObject); @@ -312,7 +324,7 @@ abstract class _UploadMetadataBase< /// See: . class UploadTask extends JsObjectWrapper { UploadTask._fromJsObject(storage_interop.UploadTaskJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); static final _expando = Expando(); @@ -321,9 +333,11 @@ class UploadTask extends JsObjectWrapper { /// Returns the UploadTaskSnapshot when the upload successfully completes. Future get future async { return _future ??= jsObject - .then(((JSAny value) { - return value as storage_interop.UploadTaskSnapshotJsImpl; - }).toJS) + .then( + ((JSAny value) { + return value as storage_interop.UploadTaskSnapshotJsImpl; + }).toJS, + ) .toDart .then( (value) => UploadTaskSnapshot.getInstance( @@ -390,10 +404,7 @@ class UploadTask extends JsObjectWrapper { errorWrapper, onCompletion, ); - setWindowsListener( - windowsKey, - onStateChangedUnsubscribe, - ); + setWindowsListener(windowsKey, onStateChangedUnsubscribe); } void stopListen() { @@ -403,7 +414,10 @@ class UploadTask extends JsObjectWrapper { } changeController = StreamController.broadcast( - onListen: startListen, onCancel: stopListen, sync: true); + onListen: startListen, + onCancel: stopListen, + sync: true, + ); return changeController.stream; } @@ -423,8 +437,8 @@ class UploadTask extends JsObjectWrapper { class UploadTaskSnapshot extends JsObjectWrapper { UploadTaskSnapshot._fromJsObject( - storage_interop.UploadTaskSnapshotJsImpl jsObject) - : super.fromJsObject(jsObject); + storage_interop.UploadTaskSnapshotJsImpl jsObject, + ) : super.fromJsObject(jsObject); static final _expando = Expando(); @@ -454,7 +468,8 @@ class UploadTaskSnapshot return TaskState.ERROR; default: throw UnsupportedError( - "Unknown state '${jsObject.state}' please file a bug."); + "Unknown state '${jsObject.state}' please file a bug.", + ); } } @@ -466,7 +481,8 @@ class UploadTaskSnapshot /// Creates a new UploadTaskSnapshot from a [jsObject]. static UploadTaskSnapshot getInstance( - storage_interop.UploadTaskSnapshotJsImpl jsObject) { + storage_interop.UploadTaskSnapshotJsImpl jsObject, + ) { return _expando[jsObject] ??= UploadTaskSnapshot._fromJsObject(jsObject); } } @@ -477,13 +493,14 @@ class UploadTaskSnapshot class SettableMetadata extends _SettableMetadataBase { /// Creates a new SettableMetadata with optional metadata parameters. - factory SettableMetadata( - {String? cacheControl, - String? contentDisposition, - String? contentEncoding, - String? contentLanguage, - String? contentType, - Map? customMetadata}) { + factory SettableMetadata({ + String? cacheControl, + String? contentDisposition, + String? contentEncoding, + String? contentLanguage, + String? contentType, + Map? customMetadata, + }) { final metadata = storage_interop.SettableMetadataJsImpl(); if (cacheControl != null) { @@ -509,11 +526,12 @@ class SettableMetadata /// Creates a new SettableMetadata from a [jsObject]. SettableMetadata.fromJsObject(storage_interop.SettableMetadataJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); } abstract class _SettableMetadataBase< - T extends storage_interop.SettableMetadataJsImpl> + T extends storage_interop.SettableMetadataJsImpl +> extends JsObjectWrapper { _SettableMetadataBase.fromJsObject(T jsObject) : super.fromJsObject(jsObject); @@ -569,12 +587,16 @@ abstract class _SettableMetadataBase< /// The options [StorageReference.list] accepts. class ListOptions extends JsObjectWrapper { factory ListOptions({int? maxResults, String? pageToken}) { - return ListOptions._fromJsObject(storage_interop.ListOptionsJsImpl( - maxResults: maxResults, pageToken: pageToken?.toJS)); + return ListOptions._fromJsObject( + storage_interop.ListOptionsJsImpl( + maxResults: maxResults, + pageToken: pageToken?.toJS, + ), + ); } ListOptions._fromJsObject(storage_interop.ListOptionsJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); /// If set, limits the total number of prefixes and items to return. /// The default and maximum maxResults is 1000. @@ -593,7 +615,7 @@ class ListOptions extends JsObjectWrapper { /// Result returned by [StorageReference.list]. class ListResult extends JsObjectWrapper { ListResult._fromJsObject(storage_interop.ListResultJsImpl jsObject) - : super.fromJsObject(jsObject); + : super.fromJsObject(jsObject); static final _expando = Expando(); diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage_interop.dart b/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage_interop.dart index 575d234c816f..1e4e6ea924aa 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage_interop.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage_interop.dart @@ -19,8 +19,11 @@ external StorageJsImpl getStorage([AppJsImpl? app, JSString? bucketUrl]); @JS() @staticInterop external void connectStorageEmulator( - StorageJsImpl storage, JSString host, JSNumber port, - [EmulatorOptions? options]); + StorageJsImpl storage, + JSString host, + JSNumber port, [ + EmulatorOptions? options, +]); @JS() @staticInterop @@ -28,13 +31,17 @@ external JSPromise /* void */ deleteObject(ReferenceJsImpl ref); @JS() @staticInterop -external JSPromise getBlob(ReferenceJsImpl ref, - [JSNumber? maxDownloadSizeBytes]); +external JSPromise getBlob( + ReferenceJsImpl ref, [ + JSNumber? maxDownloadSizeBytes, +]); @JS() @staticInterop -external JSPromise> getBytes(ReferenceJsImpl ref, - [JSNumber? maxDownloadSizeBytes]); +external JSPromise> getBytes( + ReferenceJsImpl ref, [ + JSNumber? maxDownloadSizeBytes, +]); @JS() @staticInterop @@ -46,8 +53,10 @@ external JSPromise getMetadata(ReferenceJsImpl ref); @JS() @staticInterop -external JSPromise list(ReferenceJsImpl ref, - [ListOptionsJsImpl? listOptions]); +external JSPromise list( + ReferenceJsImpl ref, [ + ListOptionsJsImpl? listOptions, +]); @JS() @staticInterop @@ -62,13 +71,17 @@ external ReferenceJsImpl ref(JSAny storageOrRef, [JSString? urlOrPath]); @JS() @staticInterop external JSPromise updateMetadata( - ReferenceJsImpl ref, SettableMetadataJsImpl settableMetadata); + ReferenceJsImpl ref, + SettableMetadataJsImpl settableMetadata, +); @JS() @staticInterop external UploadTaskJsImpl uploadBytesResumable( - ReferenceJsImpl ref, JSAny /* Blob | Uint8Array | ArrayBuffer */ data, - [UploadMetadataJsImpl? metadata]); + ReferenceJsImpl ref, + JSAny /* Blob | Uint8Array | ArrayBuffer */ data, [ + UploadMetadataJsImpl? metadata, +]); @JS() @staticInterop @@ -145,14 +158,15 @@ extension type FullMetadataJsImpl._(JSObject _) @JS('UploadMetadata') extension type UploadMetadataJsImpl._(JSObject _) implements SettableMetadataJsImpl, JSObject { - external factory UploadMetadataJsImpl( - {JSString? md5Hash, - JSString? cacheControl, - JSString? contentDisposition, - JSString? contentEncoding, - JSString? contentLanguage, - JSString? contentType, - JSAny? customMetadata}); + external factory UploadMetadataJsImpl({ + JSString? md5Hash, + JSString? cacheControl, + JSString? contentDisposition, + JSString? contentEncoding, + JSString? contentLanguage, + JSString? contentType, + JSAny? customMetadata, + }); external JSString? get md5Hash; external set md5Hash(JSString? s); @@ -162,12 +176,18 @@ extension type UploadTaskJsImpl._(JSObject _) implements JSObject { external UploadTaskSnapshotJsImpl get snapshot; external set snapshot(UploadTaskSnapshotJsImpl t); external JSBoolean cancel(); - external JSFunction on(JSString event, - [JSAny nextOrObserver, JSFunction? error, JSFunction? complete]); + external JSFunction on( + JSString event, [ + JSAny nextOrObserver, + JSFunction? error, + JSFunction? complete, + ]); external JSBoolean pause(); external JSBoolean resume(); - external JSPromise /* void */ then( - [JSFunction? onResolve, JSFunction? onReject]); + external JSPromise /* void */ then([ + JSFunction? onResolve, + JSFunction? onReject, + ]); } extension type UploadTaskSnapshotJsImpl._(JSObject _) implements JSObject { @@ -181,13 +201,14 @@ extension type UploadTaskSnapshotJsImpl._(JSObject _) implements JSObject { @JS('SettableMetadata') extension type SettableMetadataJsImpl._(JSObject _) implements JSObject { - external factory SettableMetadataJsImpl( - {JSString? cacheControl, - JSString? contentDisposition, - JSString? contentEncoding, - JSString? contentLanguage, - JSString? contentType, - JSAny? customMetadata}); + external factory SettableMetadataJsImpl({ + JSString? cacheControl, + JSString? contentDisposition, + JSString? contentEncoding, + JSString? contentLanguage, + JSString? contentType, + JSAny? customMetadata, + }); external JSString? get cacheControl; external set cacheControl(JSString? s); diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/list_result_web.dart b/packages/firebase_storage/firebase_storage_web/lib/src/list_result_web.dart index 269b34594a39..6c48f9fc07b8 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/list_result_web.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/list_result_web.dart @@ -13,9 +13,9 @@ class ListResultWeb extends ListResultPlatform { String? nextPageToken, List? items, List? prefixes, - }) : _items = items ?? [], - _prefixes = prefixes ?? [], - super(storage, nextPageToken); + }) : _items = items ?? [], + _prefixes = prefixes ?? [], + super(storage, nextPageToken); List _items; diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/reference_web.dart b/packages/firebase_storage/firebase_storage_web/lib/src/reference_web.dart index 0f65fbc49817..8ea8664afb99 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/reference_web.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/reference_web.dart @@ -26,8 +26,8 @@ final _storageUrlPrefix = RegExp(r'^(?:gs|https?):\//'); class ReferenceWeb extends ReferencePlatform { /// Constructor for this ref ReferenceWeb(FirebaseStorageWeb storage, String path) - : _path = path, - super(storage, path) { + : _path = path, + super(storage, path) { if (_path.startsWith(_storageUrlPrefix)) { _ref = storage.delegate.refFromURL(_path); } else { @@ -144,9 +144,7 @@ class ReferenceWeb extends ReferencePlatform { this, _ref.put( data.toJS, - settableMetadataToFbUploadMetadata( - _cache.store(metadata), - ), + settableMetadataToFbUploadMetadata(_cache.store(metadata)), ), ); } @@ -223,8 +221,8 @@ class ReferenceWeb extends ReferencePlatform { }); } -// Purposefully left unimplemented because of lack of dart:io support in web: + // Purposefully left unimplemented because of lack of dart:io support in web: -// TaskPlatform writeToFile(File file) {} -// TaskPlatform putFile(File file, [SettableMetadata metadata]) {} + // TaskPlatform writeToFile(File file) {} + // TaskPlatform putFile(File file, [SettableMetadata metadata]) {} } diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/task_snapshot_web.dart b/packages/firebase_storage/firebase_storage_web/lib/src/task_snapshot_web.dart index 9d19d1dba13b..69332c3e02d6 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/task_snapshot_web.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/task_snapshot_web.dart @@ -13,10 +13,11 @@ import 'utils/task.dart'; class TaskSnapshotWeb extends TaskSnapshotPlatform { /// Create a TaskSnapshotWeb from its [ReferencePlatform] and a native [fb.UploadTaskSnapshot] TaskSnapshotWeb( - ReferencePlatform ref, storage_interop.UploadTaskSnapshot snapshot) - : _reference = ref, - _snapshot = snapshot, - super(fbTaskStateToTaskState(snapshot.state), {}); + ReferencePlatform ref, + storage_interop.UploadTaskSnapshot snapshot, + ) : _reference = ref, + _snapshot = snapshot, + super(fbTaskStateToTaskState(snapshot.state), {}); /// The [FirebaseStoragePlatform] used to create the task. final ReferencePlatform _reference; diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/task_web.dart b/packages/firebase_storage/firebase_storage_web/lib/src/task_web.dart index 2403e54475eb..86935c5aba52 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/task_web.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/task_web.dart @@ -20,9 +20,9 @@ class TaskWeb extends TaskPlatform { /// Creates a Task for web from a [ReferencePlatform] object and a native [storage_interop.UploadTask]. /// The `reference` is used when creating [TaskSnapshotWeb] of this task. TaskWeb(ReferencePlatform reference, storage_interop.UploadTask task) - : _reference = reference, - _task = task, - super(); + : _reference = reference, + _task = task, + super(); final ReferencePlatform _reference; @@ -50,26 +50,30 @@ class TaskWeb extends TaskPlatform { // It can also throw a FirebaseError internally, so we handle it. final onStateChangedStream = _task .onStateChanged( - _reference.storage.app.name, - _reference.bucket, - _reference.fullPath, - ) + _reference.storage.app.name, + _reference.bucket, + _reference.fullPath, + ) .map((snapshot) { - return fbUploadTaskSnapshotToTaskSnapshot(_reference, snapshot); - }); + return fbUploadTaskSnapshotToTaskSnapshot(_reference, snapshot); + }); group.add(onStateChangedStream); - onComplete.asStream().last.then((value) async { - // If successful, we add a final snapshot with the state "success" - await group.add(onComplete.asStream()); - await group.close(); - }).catchError((e) async { - // We don't care about the error here as it has already propagated via `guard()` - // We need to remove the onStateChangedStream from the group and close group for onDone callback to be called - await group.remove(onStateChangedStream); - await group.close(); - }); + onComplete + .asStream() + .last + .then((value) async { + // If successful, we add a final snapshot with the state "success" + await group.add(onComplete.asStream()); + await group.close(); + }) + .catchError((e) async { + // We don't care about the error here as it has already propagated via `guard()` + // We need to remove the onStateChangedStream from the group and close group for onDone callback to be called + await group.remove(onStateChangedStream); + await group.close(); + }); return group.stream; }); @@ -84,10 +88,7 @@ class TaskWeb extends TaskPlatform { @override Future get onComplete { return guard(() async { - return fbUploadTaskSnapshotToTaskSnapshot( - _reference, - await _task.future, - ); + return fbUploadTaskSnapshotToTaskSnapshot(_reference, await _task.future); }); } @@ -136,8 +137,9 @@ class TaskWeb extends TaskPlatform { final canceled = _task.cancel(); // The snapshotEvents will eventually throw an exception when the user cancels. // Wait for that signal, and then return the value of "canceled" (or true). - return snapshotEvents - .drain() - .then((_) => canceled, onError: (_) => canceled); + return snapshotEvents.drain().then( + (_) => canceled, + onError: (_) => canceled, + ); } } diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/utils/list.dart b/packages/firebase_storage/firebase_storage_web/lib/src/utils/list.dart index b8e94272fa13..c5e76cf8df7a 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/utils/list.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/utils/list.dart @@ -22,7 +22,9 @@ storage_interop.ListOptions? listOptionsToFbListOptions(ListOptions? options) { /// Converts a ListResult from the JS interop layer to a ListResultWeb for the plugin. ListResultWeb fbListResultToListResultWeb( - FirebaseStoragePlatform storage, storage_interop.ListResult result) { + FirebaseStoragePlatform storage, + storage_interop.ListResult result, +) { return ListResultWeb( storage, nextPageToken: result.nextPageToken, diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/utils/metadata.dart b/packages/firebase_storage/firebase_storage_web/lib/src/utils/metadata.dart index adfc027d59f0..128647f5989f 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/utils/metadata.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/utils/metadata.dart @@ -11,7 +11,8 @@ import '../interop/storage.dart' as storage_interop; /// Converts FullMetadata coming from the JS Interop layer to FullMetadata for the plugin. FullMetadata fbFullMetadataToFullMetadata( - storage_interop.FullMetadata metadata) { + storage_interop.FullMetadata metadata, +) { return FullMetadata({ 'bucket': metadata.bucket, 'cacheControl': metadata.cacheControl, @@ -33,7 +34,8 @@ FullMetadata fbFullMetadataToFullMetadata( /// Converts SettableMetadata from the plugin to SettableMetadata for the JS Interop layer. storage_interop.SettableMetadata settableMetadataToFbSettableMetadata( - SettableMetadata metadata) { + SettableMetadata metadata, +) { return storage_interop.SettableMetadata( cacheControl: metadata.cacheControl, contentDisposition: metadata.contentDisposition, @@ -46,8 +48,9 @@ storage_interop.SettableMetadata settableMetadataToFbSettableMetadata( /// Converts SettableMetadata from the plugin and an additional MD5 hash (as String) to an UploadMetadata for the JS Interop layer. storage_interop.UploadMetadata settableMetadataToFbUploadMetadata( - SettableMetadata metadata, - {String? md5Hash}) { + SettableMetadata metadata, { + String? md5Hash, +}) { return storage_interop.UploadMetadata( cacheControl: metadata.cacheControl, contentDisposition: metadata.contentDisposition, diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/utils/task.dart b/packages/firebase_storage/firebase_storage_web/lib/src/utils/task.dart index 752c1f0f9ffd..8dcae4dfef3a 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/utils/task.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/utils/task.dart @@ -23,6 +23,8 @@ TaskState fbTaskStateToTaskState(storage_interop.TaskState state) { /// Converts UploadTaskSnapshot from the JS interop layer to TaskSnapshotWeb for the plugin. TaskSnapshotWeb fbUploadTaskSnapshotToTaskSnapshot( - ReferencePlatform reference, storage_interop.UploadTaskSnapshot snapshot) { + ReferencePlatform reference, + storage_interop.UploadTaskSnapshot snapshot, +) { return TaskSnapshotWeb(reference, snapshot); } diff --git a/packages/firebase_storage/firebase_storage_web/pubspec.yaml b/packages/firebase_storage/firebase_storage_web/pubspec.yaml index 7109b506b2ff..5e18dc0b3eca 100644 --- a/packages/firebase_storage/firebase_storage_web/pubspec.yaml +++ b/packages/firebase_storage/firebase_storage_web/pubspec.yaml @@ -6,8 +6,8 @@ version: 3.11.13 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.22.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: _flutterfire_internals: ^1.3.77 diff --git a/packages/firebase_storage/firebase_storage_web/test/metadata_cache_test.dart b/packages/firebase_storage/firebase_storage_web/test/metadata_cache_test.dart index 07f121689192..0b9447b22b42 100644 --- a/packages/firebase_storage/firebase_storage_web/test/metadata_cache_test.dart +++ b/packages/firebase_storage/firebase_storage_web/test/metadata_cache_test.dart @@ -8,14 +8,13 @@ import 'package:firebase_storage_platform_interface/firebase_storage_platform_in import 'package:firebase_storage_web/src/utils/metadata_cache.dart'; import 'package:flutter_test/flutter_test.dart'; -final someMetadata = SettableMetadata(contentLanguage: 'es', customMetadata: { - 'testing': '123', -}); - -final otherMetadata = SettableMetadata( - contentType: 'image/png', +final someMetadata = SettableMetadata( + contentLanguage: 'es', + customMetadata: {'testing': '123'}, ); +final otherMetadata = SettableMetadata(contentType: 'image/png'); + void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -37,30 +36,34 @@ void main() { final setMetadata = cache!.store(otherMetadata); expect( - setMetadata.contentLanguage, equals(someMetadata.contentLanguage)); + setMetadata.contentLanguage, + equals(someMetadata.contentLanguage), + ); expect(setMetadata.contentType, equals(otherMetadata.contentType)); }); test( - "Shallowly merges extendedMetadata without overwriting what's already set", - () { - final withCustomMetadata = SettableMetadata(customMetadata: { - 'testing': '456', - 'more-testing': 'yes', - }); - - final setMetadata = cache!.store(withCustomMetadata); - final customMetadata = setMetadata.customMetadata; - expect(customMetadata, containsPair('testing', '123')); - expect(customMetadata, containsPair('more-testing', 'yes')); - expect(customMetadata, isNot(containsPair('testing', '456'))); - }); + "Shallowly merges extendedMetadata without overwriting what's already set", + () { + final withCustomMetadata = SettableMetadata( + customMetadata: {'testing': '456', 'more-testing': 'yes'}, + ); + + final setMetadata = cache!.store(withCustomMetadata); + final customMetadata = setMetadata.customMetadata; + expect(customMetadata, containsPair('testing', '123')); + expect(customMetadata, containsPair('more-testing', 'yes')); + expect(customMetadata, isNot(containsPair('testing', '456'))); + }, + ); test('Storing null returns the current cache', () { final setMetadata = cache!.store(null); expect( - setMetadata.contentLanguage, equals(someMetadata.contentLanguage)); + setMetadata.contentLanguage, + equals(someMetadata.contentLanguage), + ); }); }); diff --git a/pubspec.yaml b/pubspec.yaml index e3d6f3195b02..63a4dc487fa6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: flutterfire_workspace environment: - sdk: '^3.6.0' + sdk: '^3.10.0' workspace: - packages/_flutterfire_internals diff --git a/tests/integration_test/firebase_core/firebase_core_e2e_test.dart b/tests/integration_test/firebase_core/firebase_core_e2e_test.dart index 8204337cd553..d74f1ea2c591 100644 --- a/tests/integration_test/firebase_core/firebase_core_e2e_test.dart +++ b/tests/integration_test/firebase_core/firebase_core_e2e_test.dart @@ -36,31 +36,24 @@ void main() { }); test('Firebase.app() Exception', () async { - expect( - () => Firebase.app('NoApp'), - throwsA(noAppExists('NoApp')), - ); + expect(() => Firebase.app('NoApp'), throwsA(noAppExists('NoApp'))); }); - test( - 'FirebaseApp.delete()', - () async { - await Firebase.initializeApp( - name: 'SecondaryApp', - options: DefaultFirebaseOptions.currentPlatform, - ); + test('FirebaseApp.delete()', () async { + await Firebase.initializeApp( + name: 'SecondaryApp', + options: DefaultFirebaseOptions.currentPlatform, + ); - expect(Firebase.apps.length, 2); + expect(Firebase.apps.length, 2); - FirebaseApp app = Firebase.app('SecondaryApp'); + FirebaseApp app = Firebase.app('SecondaryApp'); - await app.delete(); + await app.delete(); - expect(Firebase.apps.length, 1); - // TODO(russellwheatley): test randomly causes an auth sign-in failure due to duplicate accounts. - }, - skip: TargetPlatform.android == defaultTargetPlatform, - ); + expect(Firebase.apps.length, 1); + // TODO(russellwheatley): test randomly causes an auth sign-in failure due to duplicate accounts. + }, skip: TargetPlatform.android == defaultTargetPlatform); test('FirebaseApp.setAutomaticDataCollectionEnabled()', () async { FirebaseApp app = Firebase.app(testAppName); diff --git a/tests/integration_test/report_test_results.dart b/tests/integration_test/report_test_results.dart index fb80e3ba19f7..db17f5dab066 100644 --- a/tests/integration_test/report_test_results.dart +++ b/tests/integration_test/report_test_results.dart @@ -26,8 +26,9 @@ void reportTestResultsToDriver(IntegrationTestWidgetsFlutterBinding binding) { for (final entry in binding.results.entries) if (entry.value is Failure) entry.key, ]; - bool didFail(String name) => failures - .any((failure) => name == failure || name.endsWith(' $failure')); + bool didFail(String name) => failures.any( + (failure) => name == failure || name.endsWith(' $failure'), + ); binding.reportData ??= {}; binding.reportData!['testResults'] = { diff --git a/tests/lib/main.dart b/tests/lib/main.dart index 664d3dc6b6b4..0faac89c43c3 100644 --- a/tests/lib/main.dart +++ b/tests/lib/main.dart @@ -15,9 +15,7 @@ import 'firebase_options.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); + await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); runApp(const MyApp()); } @@ -29,9 +27,7 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), + theme: ThemeData(primarySwatch: Colors.blue), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } @@ -45,9 +41,7 @@ class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text(title), - ), + appBar: AppBar(title: Text(title)), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, diff --git a/tests/pubspec.yaml b/tests/pubspec.yaml index 6f13eae3ddf1..f337cb136cb2 100644 --- a/tests/pubspec.yaml +++ b/tests/pubspec.yaml @@ -6,8 +6,8 @@ version: 1.0.0+1 resolution: workspace environment: - sdk: '^3.6.0' - flutter: '>=3.22.0' + sdk: '^3.10.0' + flutter: '>=3.38.0' dependencies: cloud_functions: ^6.4.0 diff --git a/tests/test_driver/integration_test.dart b/tests/test_driver/integration_test.dart index 691723cbbfe1..9ccbcc26ab97 100644 --- a/tests/test_driver/integration_test.dart +++ b/tests/test_driver/integration_test.dart @@ -7,28 +7,32 @@ import 'dart:io'; import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver( - writeResponseOnFailure: true, - responseDataCallback: (Map? data) async { - final results = - (data?['testResults'] as Map?)?.cast() ?? - const {}; - var passed = 0; - var failed = 0; - for (final entry in results.entries) { - final ok = entry.value == 'success'; - ok ? passed++ : failed++; - // ignore: avoid_print - print('${ok ? '✅' : '❌'} ${entry.key}'); - } - // ignore: avoid_print - print('Web e2e summary: $passed passed, $failed failed, ' - '${results.length} total'); - if (results.isEmpty) { - // ignore: avoid_print - print('[E] No tests reported by the app - treating as ' - 'infrastructure failure.'); - exit(1); - } - await writeResponseData(data); - }, + writeResponseOnFailure: true, + responseDataCallback: (Map? data) async { + final results = + (data?['testResults'] as Map?)?.cast() ?? + const {}; + var passed = 0; + var failed = 0; + for (final entry in results.entries) { + final ok = entry.value == 'success'; + ok ? passed++ : failed++; + // ignore: avoid_print + print('${ok ? '✅' : '❌'} ${entry.key}'); + } + // ignore: avoid_print + print( + 'Web e2e summary: $passed passed, $failed failed, ' + '${results.length} total', ); + if (results.isEmpty) { + // ignore: avoid_print + print( + '[E] No tests reported by the app - treating as ' + 'infrastructure failure.', + ); + exit(1); + } + await writeResponseData(data); + }, +);