Closed johnwargo closed 1 year ago
Hi @johnwargo Could you please provide a minimal complete reproducible code sample? Thank you
@markusaksli-nc here ya go:
my main.dart
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:firebase_analytics/observer.dart';
import 'pages/home.dart';
// Toggle this to cause an async error to be thrown during initialization
// and to test that runZonedGuarded() catches the error
const _kShouldTestAsyncErrorOnInit = false;
// Toggle this for testing Crashlytics in your app locally.
const _kTestingCrashlytics = true;
const appName = 'Flutter Firebase Demo';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// runApp(const MyApp());
runZonedGuarded(() {
runApp(MyApp());
}, FirebaseCrashlytics.instance.recordError);
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
static FirebaseAnalytics analytics = FirebaseAnalytics();
static FirebaseAnalyticsObserver observer =
FirebaseAnalyticsObserver(analytics: analytics);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late Future<void> _initializeFlutterFireFuture;
Future<void> _testAsyncErrorOnInit() async {
Future<void>.delayed(const Duration(seconds: 2), () {
final List<int> list = <int>[];
print(list[100]);
});
}
// Define an async function to initialize FlutterFire
Future<void> _initializeFlutterFire() async {
// Wait for Firebase to initialize
if (_kTestingCrashlytics) {
// Force enable crashlytics collection enabled if we're testing it.
await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
} else {
// Else only enable it in non-debug builds.
// You could additionally extend this to allow users to opt-in.
await FirebaseCrashlytics.instance
.setCrashlyticsCollectionEnabled(!kDebugMode);
}
// Pass all uncaught errors to Crashlytics.
Function originalOnError = FlutterError.onError as Function;
FlutterError.onError = (FlutterErrorDetails errorDetails) async {
await FirebaseCrashlytics.instance.recordFlutterError(errorDetails);
// Forward to original handler.
originalOnError(errorDetails);
};
if (_kShouldTestAsyncErrorOnInit) {
await _testAsyncErrorOnInit();
}
}
@override
void initState() {
super.initState();
_initializeFlutterFireFuture = _initializeFlutterFire();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: appName,
debugShowCheckedModeBanner: false,
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
home: FirebaseDemoHome(
title: appName,
analytics: MyApp.analytics,
observer: MyApp.observer,
),
navigatorObservers: [
FirebaseAnalyticsObserver(analytics: MyApp.analytics),
],
);
}
}
and home.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_analytics/observer.dart';
import 'package:firebase_database/ui/firebase_animated_list.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:intl/intl.dart';
import 'package:random_string/random_string.dart';
final GoogleSignIn _googleSignIn = GoogleSignIn();
late Future initFuture;
class FirebaseDemoHome extends StatefulWidget {
const FirebaseDemoHome({
Key? key,
required this.title,
required this.analytics,
required this.observer,
}) : super(key: key);
final String title;
final FirebaseAnalytics analytics;
final FirebaseAnalyticsObserver observer;
@override
State<FirebaseDemoHome> createState() => _FirebaseDemoHomeState();
}
class _FirebaseDemoHomeState extends State<FirebaseDemoHome> {
late DatabaseReference _recordsRef;
late StreamSubscription<Event> _recordsSubscription;
late bool isLoggedIn;
final ScrollController _scrollController = ScrollController();
Future<UserCredential> _signInWithGoogle() async {
// move this into the login method
print("Signing-in with Google");
await widget.analytics.logEvent(name: "login");
// Trigger the authentication flow
final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn();
print("signed in");
// Obtain the auth details from the request
final GoogleSignInAuthentication googleAuth =
await googleUser!.authentication;
print("got auth details");
// Create a new credential
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
print("got credentials, executing Firebase sign-in");
// Once signed in, return the UserCredential
return await FirebaseAuth.instance.signInWithCredential(credential);
}
_doLogin() {
print('Home: Login button tapped');
_signInWithGoogle().then((UserCredential theUser) {
print("UID: ${theUser.user!.uid}");
setState(() {
isLoggedIn = theUser.user!.uid.isNotEmpty;
});
});
}
_doLogout() {
// logs out of Firebase and Google
print('Home: Logout button tapped');
FirebaseAuth.instance.signOut().then((value) {
_googleSignIn.disconnect();
setState(() {
isLoggedIn = (FirebaseAuth.instance.currentUser != null);
});
}).catchError((error) {
print("Unable to logout");
print(error);
});
}
// https://www.raywenderlich.com/24346128-firebase-realtime-database-tutorial-for-flutter
Query getRecordsQuery() {
return _recordsRef;
}
// Initialize the Config class (loading data) for the FutureBuilder
Future<bool> initializeApp() async {
print('HomePage: initializeApp()');
// Initialize the Records database (Firebase)
_recordsRef = FirebaseDatabase.instance.reference().child('records');
FirebaseAuth.instance.authStateChanges().listen((User? user) {
print("Auth State Change detected");
if (user == null) {
print('User is currently signed out!');
try {
// Cancel the records subscription (if we have one)
_recordsSubscription.cancel();
} catch (e) {}
} else {
print('User is signed in!');
// setup the home page data listener
_recordsSubscription = _recordsRef.onValue.listen((Event event) {
print('Records: ${event.snapshot.value.toString()}');
}); // Tell FutureBuilder we're ready to go...
}
});
return true;
}
void _addRecord() async {
late String userName;
print("Adding record");
userName = 'Unknown';
// TODO: Fix this ASAP
// All this does is prove that I don't truly understand null safety
// in Dart/Flutter
if (FirebaseAuth.instance.currentUser != null) {
if (FirebaseAuth.instance.currentUser!.displayName != null) {
userName = FirebaseAuth.instance.currentUser!.displayName!;
}
}
Record record = Record(randomAlphaNumeric(20), userName,
DateTime.now().millisecondsSinceEpoch);
try {
await _recordsRef.push().set(record.toJson());
} catch (e) {
print("Error: $e");
}
}
@override
void initState() {
print('HomePage: initState()');
isLoggedIn = false;
super.initState();
initFuture = initializeApp();
}
Widget recordList() {
final DateFormat formatter = DateFormat('yyyy-MM-dd @ hh:mm:ss');
return FirebaseAnimatedList(
controller: _scrollController,
query: getRecordsQuery(),
// https://stackoverflow.com/questions/69377110/flutter-firebaseanimatedlist-assertion-error-on-push-in-sorted-list
// https://github.com/FirebaseExtended/flutterfire/issues/7100
sort: (a, b) {
return a.value['timestamp'].compareTo(b.value['timestamp']);
},
itemBuilder: (context, snapshot, animation, index) {
final json = snapshot.value as Map<dynamic, dynamic>;
final record = Record.fromJson(json);
var date = DateTime.fromMicrosecondsSinceEpoch(record.timestamp * 1000);
return ListTile(
title: Text("Message: ${record.msg}"),
subtitle: Text("${record.user} (${formatter.format(date)}))"),
);
},
);
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: initFuture,
builder: (context, snapshot) {
if (snapshot.hasData) {
if (isLoggedIn) {
return Scaffold(
appBar: AppBar(title: Text(widget.title), actions: <Widget>[
IconButton(
icon: const Icon(Icons.logout_outlined),
onPressed: _doLogout,
),
]),
body: SafeArea(child: recordList()),
floatingActionButton: FloatingActionButton(
onPressed: _addRecord,
tooltip: 'Add Record',
child: const Icon(Icons.add),
),
);
} else {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SafeArea(
child: ListView(
padding: const EdgeInsets.all(16.0),
children: [
const Text(
"Access to this application is restricted to Authorized users only."),
const SizedBox(height: 15),
ConstrainedBox(
constraints: const BoxConstraints.tightFor(
width: 300, height: 75),
child: ElevatedButton(
child: const Text('Login'),
onPressed: _doLogin,
),
)
])));
}
} else {
// Display the initialization message
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: const SafeArea(
child: Center(child: Text('Reading application data'))));
} // if (!snapshot.hasData)
});
}
}
class Record {
final String msg;
final String user;
final int timestamp;
Record(this.msg, this.user, this.timestamp);
Record.fromJson(Map<dynamic, dynamic> json)
: msg = json['msg'],
user = json['user'],
timestamp = json['timestamp'];
Map<dynamic, dynamic> toJson() =>
{'msg': msg, 'user': user, 'timestamp': timestamp};
}
By a minimal complete reproducible code sample I mean something we can just paste in main.dart
and run to reproduce the issue. This example has too many other dependencies and obfuscates the issue a bit.
I tried reproducing this with just the official example but did not see the error.
My sincerest and most humble apologies for not delivering the smallest possible sample, I didn't know whether the issue was caused by Analytics or Crashes, so I left them in there. Here's a single file you can copy into a project's main.dart.
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_database/ui/firebase_animated_list.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:intl/intl.dart';
import 'package:random_string/random_string.dart';
const appName = 'Flutter Firebase Demo';
final GoogleSignIn _googleSignIn = GoogleSignIn();
late Future initFuture;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late Future<void> _initializeFlutterFireFuture;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: appName,
debugShowCheckedModeBanner: false,
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
home: FirebaseDemoHome(title: appName));
}
}
class FirebaseDemoHome extends StatefulWidget {
const FirebaseDemoHome({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<FirebaseDemoHome> createState() => _FirebaseDemoHomeState();
}
class _FirebaseDemoHomeState extends State<FirebaseDemoHome> {
late DatabaseReference _recordsRef;
late StreamSubscription<Event> _recordsSubscription;
late bool isLoggedIn;
final ScrollController _scrollController = ScrollController();
Future<UserCredential> _signInWithGoogle() async {
// Trigger the authentication flow
final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn();
// Obtain the auth details from the request
final GoogleSignInAuthentication googleAuth =
await googleUser!.authentication;
// Create a new credential
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
// Once signed in, return the UserCredential
return await FirebaseAuth.instance.signInWithCredential(credential);
}
_doLogin() {
_signInWithGoogle().then((UserCredential theUser) {
print("UID: ${theUser.user!.uid}");
setState(() {
isLoggedIn = theUser.user!.uid.isNotEmpty;
});
});
}
_doLogout() {
// logs out of Firebase and Google
FirebaseAuth.instance.signOut().then((value) {
_googleSignIn.disconnect();
setState(() {
isLoggedIn = (FirebaseAuth.instance.currentUser != null);
});
}).catchError((error) {
print("Unable to logout");
print(error);
});
}
// https://www.raywenderlich.com/24346128-firebase-realtime-database-tutorial-for-flutter
Query getRecordsQuery() {
return _recordsRef;
}
// Initialize the Config class (loading data) for the FutureBuilder
Future<bool> initializeApp() async {
print('HomePage: initializeApp()');
// Initialize the Records database (Firebase)
_recordsRef = FirebaseDatabase.instance.reference().child('records');
FirebaseAuth.instance.authStateChanges().listen((User? user) {
print("Auth State Change detected");
if (user == null) {
print('User is currently signed out!');
try {
// Cancel the records subscription (if we have one)
_recordsSubscription.cancel();
} catch (e) {}
} else {
print('User is signed in!');
// setup the home page data listener
_recordsSubscription = _recordsRef.onValue.listen((Event event) {
print('Records: ${event.snapshot.value.toString()}');
}); // Tell FutureBuilder we're ready to go...
}
});
return true;
}
void _addRecord() async {
late String userName;
print("Adding record");
userName = 'Unknown';
// TODO: Fix this ASAP
// All this does is prove that I don't truly understand null safety
// in Dart/Flutter
if (FirebaseAuth.instance.currentUser != null) {
if (FirebaseAuth.instance.currentUser!.displayName != null) {
userName = FirebaseAuth.instance.currentUser!.displayName!;
}
}
Record record = Record(randomAlphaNumeric(20), userName,
DateTime.now().millisecondsSinceEpoch);
try {
await _recordsRef.push().set(record.toJson());
} catch (e) {
print("Error: $e");
}
}
@override
void initState() {
print('HomePage: initState()');
isLoggedIn = false;
super.initState();
initFuture = initializeApp();
}
Widget recordList() {
final DateFormat formatter = DateFormat('yyyy-MM-dd @ hh:mm:ss');
return FirebaseAnimatedList(
controller: _scrollController,
query: getRecordsQuery(),
// https://stackoverflow.com/questions/69377110/flutter-firebaseanimatedlist-assertion-error-on-push-in-sorted-list
// https://github.com/FirebaseExtended/flutterfire/issues/7100
sort: (a, b) {
return a.value['timestamp'].compareTo(b.value['timestamp']);
},
itemBuilder: (context, snapshot, animation, index) {
final json = snapshot.value as Map<dynamic, dynamic>;
final record = Record.fromJson(json);
var date = DateTime.fromMicrosecondsSinceEpoch(record.timestamp * 1000);
return ListTile(
title: Text("Message: ${record.msg}"),
subtitle: Text("${record.user} (${formatter.format(date)}))"),
);
},
);
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: initFuture,
builder: (context, snapshot) {
if (snapshot.hasData) {
if (isLoggedIn) {
return Scaffold(
appBar: AppBar(title: Text(widget.title), actions: <Widget>[
IconButton(
icon: const Icon(Icons.logout_outlined),
onPressed: _doLogout,
),
]),
body: SafeArea(child: recordList()),
floatingActionButton: FloatingActionButton(
onPressed: _addRecord,
tooltip: 'Add Record',
child: const Icon(Icons.add),
),
);
} else {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SafeArea(
child: ListView(
padding: const EdgeInsets.all(16.0),
children: [
const Text(
"Access to this application is restricted to Authorized users only."),
const SizedBox(height: 15),
ConstrainedBox(
constraints: const BoxConstraints.tightFor(
width: 300, height: 75),
child: ElevatedButton(
child: const Text('Login'),
onPressed: _doLogin,
),
)
])));
}
} else {
// Display the initialization message
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: const SafeArea(
child: Center(child: Text('Reading application data'))));
} // if (!snapshot.hasData)
});
}
}
class Record {
final String msg;
final String user;
final int timestamp;
Record(this.msg, this.user, this.timestamp);
Record.fromJson(Map<dynamic, dynamic> json)
: msg = json['msg'],
user = json['user'],
timestamp = json['timestamp'];
Map<dynamic, dynamic> toJson() =>
{'msg': msg, 'user': user, 'timestamp': timestamp};
}
When I try to add a document to the collection with the sort in place, it crashes with the following error:
I/flutter (17228): Adding record
E/flutter (17228): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: 'package:flutter/src/widgets/animated_list.dart': Failed assertion: line 959 pos 12: 'index != null && index >= 0': is not true.
E/flutter (17228): #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
E/flutter (17228): #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
E/flutter (17228): #2 SliverAnimatedListState.insertItem (package:flutter/src/widgets/animated_list.dart:959:12)
E/flutter (17228): #3 AnimatedListState.insertItem (package:flutter/src/widgets/animated_list.dart:484:42)
E/flutter (17228): #4 FirebaseAnimatedListState._onChildAdded (package:firebase_database/ui/firebase_animated_list.dart:175:36)
E/flutter (17228): #5 FirebaseSortedList._onChildAdded (package:firebase_database/ui/firebase_sorted_list.dart:97:18)
E/flutter (17228): #6 _rootRunUnary (dart:async/zone.dart:1436:47)
E/flutter (17228): #7 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter (17228): #8 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
E/flutter (17228): #9 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
E/flutter (17228): #10 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
E/flutter (17228): #11 _ForwardingStreamSubscription._add (dart:async/stream_pipe.dart:123:11)
E/flutter (17228): #12 _MapStream._handleData (dart:async/stream_pipe.dart:218:10)
E/flutter (17228): #13 _ForwardingStreamSubscription._handleData (dart:async/stream_pipe.dart:153:13)
E/flutter (17228): #14 _rootRunUnary (dart:async/zone.dart:1436:47)
E/flutter (17228): #15 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter (17228): #16 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
E/flutter (17228): #17 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
E/flutter (17228): #18 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
E/flutter (17228): #19 _ForwardingStreamSubscription._add (dart:async/stream_pipe.dart:123:11)
E/flutter (17228): #20 _HandleErrorStream._handleData (dart:async/stream_pipe.dart:253:10)
E/flutter (17228): #21 _ForwardingStreamSubscription._handleData (dart:async/stream_pipe.dart:153:13)
E/flutter (17228): #22 _rootRunUnary (dart:async/zone.dart:1436:47)
E/flutter (17228): #23 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter (17228): #24 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
E/flutter (17228): #25 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
E/flutter (17228): #26 _DelayedData.perform (dart:async/stream_impl.dart:591:14)
E/flutter (17228): #27 _StreamImplEvents.handleNext (dart:async/stream_impl.dart:706:11)
E/flutter (17228): #28 _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:663:7)
E/flutter (17228): #29 _rootRun (dart:async/zone.dart:1420:47)
E/flutter (17228): #30 _CustomZone.run (dart:async/zone.dart:1328:19)
E/flutter (17228): #31 _CustomZone.runGuarded (dart:async/zone.dart:1236:7)
E/flutter (17228): #32 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1276:23)
E/flutter (17228): #33 _rootRun (dart:async/zone.dart:1428:13)
E/flutter (17228): #34 _CustomZone.run (dart:async/zone.dart:1328:19)
E/flutter (17228): #35 _CustomZone.runGuarded (dart:async/zone.dart:1236:7)
E/flutter (17228): #36 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1276:23)
E/flutter (17228): #37 _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
E/flutter (17228): #38 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
If I comment out the sort, it works as expected.
I left the login details in there, because the whole point of this partcular application is to use Auth and Realtime database and my Firebase project has the following realtime database access rules:
{
"rules": {
"records": {
".read": "auth != null",
".write": "auth != null"
}
}
}
but that shouldn't affect the operation of the sort method.
I have the same issue. And I have the FirebaseAnimatedList and sort and once there is a push on the database, I get an error
yeah, it sure feels like a bug.
Reproduces with firebase_database: ^8.0.0
https://github.com/FirebaseExtended/flutterfire/blob/110a79c5505dc818ba017cc4a46144170830f352/packages/firebase_database/firebase_database/lib/ui/firebase_sorted_list.dart#L97
indexOf
is returning -1 here
Any workaround for this? I need to update my app asap. FlutterFire please show love to this package!
It works fine on release build. Can someone else confirm that?
It works fine on release build. Can someone else confirm that?
Unfortunately, I have the same error on the release build too.
Hi I'm also experiencing the same issue for firebase_database: ^8.0.1
[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: 'package:flutter/src/widgets/animated_list.dart': Failed assertion: line 959 pos 12: 'index != null && index >= 0': is not true. package:flutter/…/widgets/animated_list.dart:1 E/flutter ( 5515): # 0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39) E/flutter ( 5515): # 1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5) E/flutter ( 5515): # 2 SliverAnimatedListState.insertItem package:flutter/…/widgets/animated_list.dart:959 E/flutter ( 5515): # 3 AnimatedListState.insertItem package:flutter/…/widgets/animated_list.dart:484 E/flutter ( 5515): # 4 FirebaseAnimatedListState._onChildAdded package:firebase_database/ui/firebase_animated_list.dart:175 E/flutter ( 5515): # 5 FirebaseSortedList._onChildAdded package:firebase_database/ui/firebase_sorted_list.dart:97
any news on the bug fix ? thanks in advance :)
This widget will be dropped from firebase_database
plugin. A successor would be implemented as a part of firebase_ui instead.
@lesnitsky can you please provide more detail? Dropped when? Successor implemented when? Is the team going to fix this now or do we have to wait for firebase_UI?
We're trying to get this working in the apps we have now, so future plans don't help us very much without the right context.
I'm having the same issue, Does FirebaseUI replaced this widget?
E/flutter ( 3187): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: 'package:flutter/src/widgets/animated_list.dart': Failed assertion: line 959 pos 12: 'index != null && index >= 0': is not true. package:flutter/…/widgets/animated_list.dart:1
@lesnitsky thanks for the drive-by promoting your new project but I don't see how your comment directly affects us now and it doesn't help us resolve the issue with the current library.
@markusaksli-nc its been a while, anything being done on this issue?
Reproduces with firebase_database: ^8.0.0 flutterfire/packages/firebase_database/firebase_database/lib/ui/firebase_sorted_list.dart
Line 97 in 110a79c
onChildAdded!(_snapshots.indexOf(event.snapshot), event.snapshot);
indexOf is returning -1 here
solution is here:
`void _onChildAdded(DatabaseEvent event) { //adding this will solve your issue DataSnapshot dataSnapshot = event.snapshot as DataSnapshot;
_snapshots.add(dataSnapshot); _snapshots.sort(comparator);`
onChildAdded(_snapshots.indexOf(dataSnapshot), dataSnapshot); }
Same issue here!
still broken in 9.0.15
@markusaksli-nc what happened? Will someone look at this?
@johnwargo check my last comment for solution.
Bug report
Describe the bug I build a Flutter application using the firebase database plugin against the Firebase Realtime Database. I'm using the FirebaseAnimatedList to render the documents from a collection and when I add a sort to the FirebaseAnimatedList, I get an assertion error whenever I add a new document to the collection using
_recordsRef.push().set(record.toJson());
Here's the error I get from Crashalytics:
When I comment out the sort everything works as expected
Steps to reproduce
Create an app with the plugin. Create a document list using:
add a document to the collection using:
my record looks like this:
Expected behavior
Its an assertion error, so I assume something's going on inside the package. I expect there to be no assertion errors when I insert a document into the collection while using an FirebaseAnimatedList with a sort method.
Sample project
Providing a minimal example project which demonstrates the bug in isolation from your main App greatly enhances the chance of a timely fix. Please link to the public repository URL.
Additional context
Add any other context about the problem here.
Flutter doctor
Run
flutter doctor
and paste the output below:Click To Expand
``` Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, 2.5.1, on macOS 11.6 20G165 darwin-x64, locale en-US) [✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0) [✓] Xcode - develop for iOS and macOS [✓] Chrome - develop for the web [✓] Android Studio (version 2020.3) [✓] VS Code (version 1.60.2) [✓] Connected device (2 available) • No issues found! ```Flutter dependencies
Run
flutter pub deps -- --style=compact
and paste the output below:Click To Expand
``` Dart SDK 2.14.2 Flutter SDK 2.5.1 fb_demo_flutter 1.0.0+1 dependencies: - firebase_analytics 8.3.2 [firebase_analytics_platform_interface firebase_analytics_web firebase_core flutter meta] - firebase_auth 3.1.1 [firebase_auth_platform_interface firebase_auth_web firebase_core firebase_core_platform_interface flutter meta] - firebase_core 1.6.0 [firebase_core_platform_interface firebase_core_web flutter meta] - firebase_crashlytics 2.2.1 [firebase_core firebase_core_platform_interface firebase_crashlytics_platform_interface flutter stack_trace] - firebase_database 8.0.0 [firebase_core firebase_database_platform_interface firebase_database_web flutter] - flutter 0.0.0 [characters collection meta typed_data vector_math sky_engine] - fluttertoast 8.0.8 [flutter flutter_web_plugins] - google_sign_in 5.1.0 [flutter google_sign_in_platform_interface google_sign_in_web meta] - package_info 2.0.2 [flutter] - random_string 2.3.1 - shared_preferences 2.0.8 [flutter meta shared_preferences_linux shared_preferences_macos shared_preferences_platform_interface shared_preferences_web shared_preferences_windows] - url_launcher 6.0.11 [flutter meta url_launcher_linux url_launcher_macos url_launcher_platform_interface url_launcher_web url_launcher_windows] dev dependencies: - flutter_lints 1.0.4 [lints] - flutter_test 0.0.0 [flutter test_api path fake_async clock stack_trace vector_math async boolean_selector characters charcode collection matcher meta source_span stream_channel string_scanner term_glyph typed_data] transitive dependencies: - async 2.8.1 [collection meta] - boolean_selector 2.1.0 [source_span string_scanner] - characters 1.1.0 - charcode 1.3.1 - clock 1.1.0 - collection 1.15.0 - fake_async 1.2.0 [clock collection] - ffi 1.1.2 - file 6.1.2 [meta path] - firebase 9.0.2 [http http_parser js] - firebase_analytics_platform_interface 2.0.1 [flutter meta] - firebase_analytics_web 0.3.0+1 [firebase firebase_analytics_platform_interface flutter flutter_web_plugins meta] - firebase_auth_platform_interface 6.1.0 [firebase_core flutter meta plugin_platform_interface] - firebase_auth_web 3.1.0 [firebase_auth_platform_interface firebase_core firebase_core_web flutter flutter_web_plugins http_parser intl js meta] - firebase_core_platform_interface 4.0.1 [collection flutter meta plugin_platform_interface] - firebase_core_web 1.1.0 [firebase_core_platform_interface flutter flutter_web_plugins js meta] - firebase_crashlytics_platform_interface 3.1.2 [collection firebase_core flutter meta plugin_platform_interface] - firebase_database_platform_interface 0.1.0 [collection firebase_core flutter meta plugin_platform_interface] - firebase_database_web 0.1.0 [firebase_core firebase_core_web firebase_database_platform_interface flutter flutter_web_plugins js] - flutter_web_plugins 0.0.0 [flutter js characters collection meta typed_data vector_math] - google_sign_in_platform_interface 2.0.1 [flutter meta quiver] - google_sign_in_web 0.10.0+3 [flutter flutter_web_plugins google_sign_in_platform_interface js meta] - http 0.13.3 [async http_parser meta path pedantic] - http_parser 4.0.0 [charcode collection source_span string_scanner typed_data] - intl 0.17.0 [clock path] - js 0.6.3 - lints 1.0.1 - matcher 0.12.10 [stack_trace] - meta 1.7.0 - path 1.8.0 - path_provider_linux 2.1.0 [flutter path path_provider_platform_interface xdg_directories] - path_provider_platform_interface 2.0.1 [flutter meta platform plugin_platform_interface] - path_provider_windows 2.0.3 [ffi flutter meta path path_provider_platform_interface win32] - pedantic 1.11.1 - platform 3.0.2 - plugin_platform_interface 2.0.1 [meta] - process 4.2.3 [file path platform] - quiver 3.0.1 [matcher] - shared_preferences_linux 2.0.2 [file meta flutter path path_provider_linux shared_preferences_platform_interface] - shared_preferences_macos 2.0.2 [flutter shared_preferences_platform_interface] - shared_preferences_platform_interface 2.0.0 [flutter] - shared_preferences_web 2.0.2 [flutter flutter_web_plugins meta shared_preferences_platform_interface] - shared_preferences_windows 2.0.2 [flutter file meta path path_provider_platform_interface path_provider_windows shared_preferences_platform_interface] - sky_engine 0.0.99 - source_span 1.8.1 [collection path term_glyph] - stack_trace 1.10.0 [path] - stream_channel 2.1.0 [async] - string_scanner 1.1.0 [charcode source_span] - term_glyph 1.2.0 - test_api 0.4.2 [async boolean_selector collection meta source_span stack_trace stream_channel string_scanner term_glyph matcher] - typed_data 1.3.0 [collection] - url_launcher_linux 2.0.2 [flutter] - url_launcher_macos 2.0.2 [flutter] - url_launcher_platform_interface 2.0.4 [flutter plugin_platform_interface] - url_launcher_web 2.0.4 [flutter flutter_web_plugins meta url_launcher_platform_interface] - url_launcher_windows 2.0.2 [flutter] - vector_math 2.1.0 - win32 2.2.9 [ffi] - xdg_directories 0.2.0 [meta path process] ```