When you cancel the StreamSubscription listener of a Firebase and sign out right after, there is a chance to get a race condition where FirebaseDatabase throws a permission denied error when the listener should already be cancelled.
Actual results : In my real app, i am cancelling all the listeners i have to my FirebaseDatabase instance, then i sign out the user when he clicks on Sign out.
That works fine most of the time, but among my few thousands active users, i have few hundreds of "Permission denied" logs in Crashlytics.
Moreover, i have managed to reproduce it on my local machine, this happens often enough on both Android and iOS to be noticeable.
Expected results : When calling await _listener?.cancel() on a FirebaseDatabase.instance.ref().onValue.listen((d) {})StreamSubscription, i would like the stream to be canceled at 100% when the await completes, which would avoid all these scenarios with permission denied errors.
Reproducing the issue
Run the sample code
Write a read rule to auth.uid != null in the Firebase console on the testing node
Play around with the sign in / sign out but always in the correct order until you saw the 0
See the race condition after some time depending on the "bug"
Is there an existing issue for this?
Which plugins are affected?
Database
Which platforms are affected?
Android, iOS
Description
When you
cancel
theStreamSubscription
listener of a Firebase and sign out right after, there is a chance to get a race condition where FirebaseDatabase throws apermission denied
error when the listener should already be cancelled.Actual results : In my real app, i am cancelling all the listeners i have to my
FirebaseDatabase
instance, then i sign out the user when he clicks onSign out
. That works fine most of the time, but among my few thousands active users, i have few hundreds of "Permission denied" logs in Crashlytics.Moreover, i have managed to reproduce it on my local machine, this happens often enough on both Android and iOS to be noticeable.
Expected results : When calling
await _listener?.cancel()
on aFirebaseDatabase.instance.ref().onValue.listen((d) {})
StreamSubscription
, i would like the stream to be canceled at 100% when theawait
completes, which would avoid all these scenarios with permission denied errors.Reproducing the issue
auth.uid != null
in the Firebase console on the testing nodeFirebase Core version
3.8.0
Flutter Version
3.24.5
Relevant Log Output
Flutter dependencies
Expand
Flutter dependencies
snippet```yaml Dart SDK 3.5.4 Flutter SDK 3.24.5 test_database 1.0.0+1 dependencies: - firebase_auth 5.3.3 [firebase_auth_platform_interface firebase_auth_web firebase_core firebase_core_platform_interface flutter meta] - firebase_core 3.8.0 [firebase_core_platform_interface firebase_core_web flutter meta] - firebase_database 11.1.6 [firebase_core firebase_core_platform_interface firebase_database_platform_interface firebase_database_web flutter] - flutter 0.0.0 [characters collection material_color_utilities meta vector_math sky_engine] dev dependencies: - flutter_lints 4.0.0 [lints] - flutter_test 0.0.0 [flutter test_api matcher path fake_async clock stack_trace vector_math leak_tracker_flutter_testing async boolean_selector characters collection leak_tracker leak_tracker_testing material_color_utilities meta source_span stream_channel string_scanner term_glyph vm_service] transitive dependencies: - _flutterfire_internals 1.3.46 [collection firebase_core firebase_core_platform_interface flutter meta] - async 2.11.0 [collection meta] - boolean_selector 2.1.1 [source_span string_scanner] - characters 1.3.0 - clock 1.1.1 - collection 1.18.0 - fake_async 1.3.1 [clock collection] - firebase_auth_platform_interface 7.4.9 [_flutterfire_internals collection firebase_core flutter meta plugin_platform_interface] - firebase_auth_web 5.13.4 [firebase_auth_platform_interface firebase_core firebase_core_web flutter flutter_web_plugins http_parser meta web] - firebase_core_platform_interface 5.3.0 [collection flutter flutter_test meta plugin_platform_interface] - firebase_core_web 2.18.1 [firebase_core_platform_interface flutter flutter_web_plugins meta web] - firebase_database_platform_interface 0.2.5+46 [_flutterfire_internals collection firebase_core flutter meta plugin_platform_interface] - firebase_database_web 0.2.6+4 [collection firebase_core firebase_core_web firebase_database_platform_interface flutter flutter_web_plugins] - flutter_web_plugins 0.0.0 [flutter characters collection material_color_utilities meta vector_math] - http_parser 4.0.2 [collection source_span string_scanner typed_data] - leak_tracker 10.0.5 [clock collection meta path vm_service] - leak_tracker_flutter_testing 3.0.5 [flutter leak_tracker leak_tracker_testing matcher meta] - leak_tracker_testing 3.0.1 [leak_tracker matcher meta] - lints 4.0.0 - matcher 0.12.16+1 [async meta stack_trace term_glyph test_api] - material_color_utilities 0.11.1 [collection] - meta 1.15.0 - path 1.9.0 - plugin_platform_interface 2.1.8 [meta] - sky_engine 0.0.99 - source_span 1.10.0 [collection path term_glyph] - stack_trace 1.11.1 [path] - stream_channel 2.1.2 [async] - string_scanner 1.2.0 [source_span] - term_glyph 1.2.1 - test_api 0.7.2 [async boolean_selector collection meta source_span stack_trace stream_channel string_scanner term_glyph] - typed_data 1.4.0 [collection] - vector_math 2.1.4 - vm_service 14.2.5 - web 1.1.0 ```
Additional context and comments
No response