SharezoneApp / sharezone-app

Sharezone is a collaborative school organization app for iOS, Android, macOS and web with +500,000 downloads. Built with Flutter & Firebase.
https://sharezone.net
European Union Public License 1.2
254 stars 46 forks source link

`Could not save term: Bad state: No element` #1568

Closed nilsreichardt closed 2 months ago

nilsreichardt commented 2 months ago
Non-fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: Could not save term: Bad state: No element
       at ListBase.singleWhere(dart:collection)
       at L.singleWhere(ilist.dart:1899)
       at IList.singleWhere(ilist.dart:906)
       at GradesService._term(grades_service.dart:229)
       at GradesService.changeGradeTypeWeightForTerm(grades_service.dart:328)
       at CreateTermPageController.save(create_term_page_controller.dart:76)

https://console.firebase.google.com/u/0/project/sharezone-c2bd8/crashlytics/app/android:de.codingbrain.sharezone/issues/70b99289ed0259892c4b1ed3ac6e0e45

I think it happens when creating a term and immediately changing the grade type weight, but the term isn't returned from the reading stream. Therefore, it's not part of the GradeService:

https://github.com/SharezoneApp/sharezone-app/blob/99c7e293a6984d703effa7aedbacbfcb48d44066/app/lib/grades/pages/create_term_page/create_term_page_controller.dart#L75-L76

nilsreichardt commented 2 months ago

@Jonas-Sander Any ideas how to fix this (in case this happens what I think)?

Jonas-Sander commented 2 months ago

but the term isn't returned from the reading screen

I'm not sure what you mean with "reading screen".
Yeah I'd guess the GradesStateRepository doesn't return the new state with the new term fast enough before the weights are changed. Which is weird, since we're even calling await _waitForFirestoreLimit() before.

Couldn't this be the issue with creating the first term while being offline? In this case the await gradesDocumentRef.get(); would not complete until the user is online and the write is acknowledged by Firestore. Because of this no new state with the added term is published by the FirestoreGradesStateRepository and so the call to gradesService.changeGradeTypeWeightForTerm will fail as the current state is still without the term to be created.

https://github.com/SharezoneApp/sharezone-app/blob/d217d9a9b9f534c1432922449ad449e88759e0fd/app/lib/grades/grades_service/src/grades_repository.dart#L117-L124

Jonas-Sander commented 2 months ago

Maybe we could use a bool _hasTopLevelCreatedOn that is set here https://github.com/SharezoneApp/sharezone-app/blob/d217d9a9b9f534c1432922449ad449e88759e0fd/app/lib/grades/grades_service/src/grades_repository.dart#L74-L88

and in updateState we add the top-level createdOn if that bool is false (and thus create a doc if not already existing)