firebase / flutterfire

🔥 A collection of Firebase plugins for Flutter apps.
https://firebase.google.com/docs/flutter/setup
BSD 3-Clause "New" or "Revised" License
8.51k stars 3.92k forks source link

🐛 [firebase_database] Using once() in a query without `orderBy()`,app throws `PlatformException(error, No active stream to cancel, null, null)` exception #7758

Closed TheHypnoo closed 2 years ago

TheHypnoo commented 2 years ago

Bug report

Describe the bug This is a call to perform an once(), in this case if I don't add any orderBy ... (), it tells me this error I am using firebase database version ^9.0.4

final List<String> direcciones = await databaseReference
          .child("Usuarios")
          .child(uid!)
          .child("Reservas")
          .once()
          .then((response) {
        final data = response.snapshot.value as Map;
        print(data.keys);
        return [];
      });
      return direcciones;

image

darshankawar commented 2 years ago

@TheHypnoo Can you provide flutter doctor -v, pubpsec.yaml and the error message in text format instead of in screenshots ? Thanks.

TheHypnoo commented 2 years ago

@darshankawar Here is what you asked me:

Flutter doctor -v ``` > flutter doctor -v [✓] Flutter (Channel stable, 2.8.1, on macOS 12.1 21C52 darwin-arm, locale es-ES) • Flutter version 2.8.1 at /Users/sergigonzalez/.asdf/installs/flutter/2.8.1-stable • Upstream repository https://github.com/flutter/flutter.git • Framework revision 77d935af4d (hace 3 semanas), 2021-12-16 08:37:33 -0800 • Engine revision 890a5fca2e • Dart version 2.15.1 [✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0) • Android SDK at /Users/sergigonzalez/Library/Android/sdk • Platform android-31, build-tools 31.0.0 • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 13.2.1) • Xcode at /Applications/Xcode.app/Contents/Developer • CocoaPods version 1.11.2 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2020.3) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189) [✓] VS Code (version 1.63.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.32.0 [✓] Connected device (2 available) • sdk gphone64 arm64 (mobile) • emulator-5554 • android-arm64 • Android 12 (API 31) (emulator) • Chrome (web) • chrome • web-javascript • Google Chrome 96.0.4664.110 • No issues found! ```
pubspec.yaml ``` name: altaguardia description: A new Flutter project. publish_to: "none" version: 1.0.0+1 environment: sdk: ">=2.15.0 <3.0.0" dependencies: android_intent_plus: ^3.0.2 another_flushbar: ^1.10.28 connectivity_plus: ^2.2.0 cupertino_icons: ^1.0.4 firebase_auth: ^3.3.4 firebase_core: ^1.10.6 firebase_crashlytics: ^2.4.4 firebase_database: ^9.0.4 firebase_messaging: ^11.2.4 flutter: sdk: flutter flutter_localizations: sdk: flutter flutter_svg: ^1.0.0 intl: ^0.17.0 libphonenumber: ^2.0.2 provider: ^6.0.2 url_launcher: ^6.0.17 webview_flutter: ^3.0.0 awesome_notifications: ^0.6.19 video_player: ^2.2.10 cloud_functions: ^3.2.4 http: ^0.13.4 dev_dependencies: flutter_launcher_icons: ^0.9.2 flutter_lints: ^1.0.4 flutter_native_splash: ^1.3.3 flutter: uses-material-design: true assets: - assets/activity/arrow_down_icon.svg - assets/activity/calendar_icon_last.svg - assets/activity/calendar_icon_last.svg - assets/activity/calendar_icon.svg - assets/activity/no_activity.svg - assets/activity/register_camera_icon.svg - assets/alerts/no_face_no_alerts.svg - assets/alerts/warning_alert.svg - assets/home/business_icon_card.svg - assets/home/no_devices.svg - assets/home/padlock_activate.png - assets/home/padlock_desactivate.png - assets/home/user_icon_card.svg - assets/logos/logo_alta_guardia_gold.png - assets/logos/logo_alta_guardia_grey.png - assets/logos/logo_alta_guardia_white_clean.png - assets/logos/logo_alta_guardia_white.png - assets/logos/logo_grandient.png - assets/nav_icons/home_active.svg - assets/nav_icons/home_inactive.svg - assets/nav_icons/menu_active.svg - assets/nav_icons/menu_inactive.svg - assets/nav_icons/notification_active.svg - assets/nav_icons/notification_inactive_no_bookings.svg - assets/nav_icons/notification_inactive.svg - assets/nav_icons/sos_active.svg - assets/nav_icons/sos_inactive_no_bookings.svg - assets/nav_icons/sos_inactive.svg - assets/register/mail_animated.gif - assets/settings/info_user_icon.svg - assets/settings/invoice_icon.svg - assets/settings/phone_icon.svg - assets/settings/send_email_icon.svg - assets/settings/settings_icon.svg - assets/settings/whatsapp_icon.svg flutter_native_splash: image: assets/splash.png color: "#1D1F21" android: true ios: true android_gravity: center ios_content_mode: center flutter_icons: android: true ios: true remove_alpha_ios: true image_path: "assets/logos/logo_grandient.png" adaptive_icon_background: "#D1B82A" adaptive_icon_foreground: "assets/logos/logo_grandient_foreground.png" ```

ERROR IN TEXT:

════════ Exception caught by services library ══════════════════════════════════
The following PlatformException was thrown while de-activating platform stream on channel Usuarios/S51kvNax1YWMKS7ENGPicAsfSOi2/Reservas-[DEFAULT]-null-DatabaseEventType.value-[]#2:
PlatformException(error, No active stream to cancel, null, null)

When the exception was thrown, this was the stack
#0      StandardMethodCodec.decodeEnvelope
package:flutter/…/services/message_codecs.dart:607
#1      MethodChannel._invokeMethod
package:flutter/…/services/platform_channel.dart:167
<asynchronous suspension>
#2      EventChannel.receiveBroadcastStream.<anonymous closure>
package:flutter/…/services/platform_channel.dart:518
<asynchronous suspension>
════════════════════════════════════════════════════════════════════════════════
darshankawar commented 2 years ago

@TheHypnoo Can you also provide a complete minimal reproducible code sample that we can directly use to verify this behavior ?

TheHypnoo commented 2 years ago

@darshankawar For ease of use, maybe adding the database structure and the function I use which shows the error?

Future<List<String>> getNameDirections() async {
  try {
    final List<String> directions = await databaseReference
        .child("Users")
        .child(uid!)
        .child("Bookings") // If you don't add an OrderBy .. () it won't work, it will show the error I show in the comment above
        .once()
        .then((response) {
      final data = response.snapshot.children; // Return: (Instance of 'DataSnapshot', Instance of 'DataSnapshot')
      if (data.isEmpty) return [];
      final List<String> listDirections = [];
      for (var element in data) {
        final Map<dynamic, dynamic> data = element.value as Map;
        listDirections.add(data["direccion"]);
      }
      return listDirections;
    });
    return directions;
  } catch (e) {
    return [];
  }
 }

Although it shows the error, the try catch does not perform its function I need to read each Reservation to be able to read the name of the address. It only happens to me with this call.

STRUCTURE DATABASE:

/
 Users/
      uidUser/
           Bookings/
                   uidBooking/
                        direction: "Direction ..."
darshankawar commented 2 years ago

Verified this using the plugin example and using below code snippet:

void _queryWithOnce() async {
    DataSnapshot snapshot = (await FirebaseDatabase.instance
        .reference()
        .child("messages")
        .equalTo("message1")
        .once()) as DataSnapshot;
    if (snapshot.exists) {
      print("Snap : ${snapshot.value}");
      Map<String, dynamic> result = Map<String, dynamic>.from(snapshot.value);
      result.forEach((key, value) {
        _messageList.add(Map<String, dynamic>.from(value));
      });
      setState(() {});
    }
  }

With which, I get below exception:

PlatformException(error, No active stream to cancel, null, null)

When the exception was thrown, this was the stack
#0      StandardMethodCodec.decodeEnvelope
package:flutter/…/services/message_codecs.dart:607
#1      MethodChannel._invokeMethod
package:flutter/…/services/platform_channel.dart:167
<asynchronous suspension>
#2      EventChannel.receiveBroadcastStream.<anonymous closure>
package:flutter/…/services/platform_channel.dart:518
<asynchronous suspension>

firebase_database: ^9.0.4

russellwheatley commented 2 years ago

Hey @TheHypnoo, I used your initial code snippet and I found no problems. Looking at the stack trace, I would be inclined to think there is something unusual within the map returned from the database. Could you try with a Reservas map that has a property with a simple string and see if that works at least?

@darshankawar, That is an outdated code snippet. Here it is updated which does not return an error for me:

DatabaseEvent event = await FirebaseDatabase.instance
                  .ref()
                  .child("messages")
                  .equalTo("message1")
                  .once();
              if (event.snapshot.exists) {
                print("Snap : ${event.snapshot.value}");
                Map<String, dynamic> result = Map<String, dynamic>.from(event.snapshot.value as Map);
                result.forEach((key, value) {
                  _messageList.add(Map<String, dynamic>.from(value));
                });
                setState(() {});
              }
TheHypnoo commented 2 years ago

@russellwheatley & @darshankawar I think that after so much thinking and testing, I have realized the possible failure that causes it to show that error.

Can it happen that if you make two different calls to two "different" functions but to the same identical children, that error happens? Could someone check it out?

darshankawar commented 2 years ago

Can it happen that if you make two different calls to two "different" functions but to the same identical children, that error happens? Could someone check it out?

If you asking this scenario in context of .once() method, then that function listens for exactly one event of the specified event type and then stops listening. If doing so, you may be getting the said exception.

TheHypnoo commented 2 years ago

So there was the problem. I used two functions where the children were the same, and was trying to listen twice.

Although before closing the issue, I have another question.

snapshot.children only performs the order to the root, but to the lower objects it does not order them. Example:

/
 Users/ 
      uidUser/
         personal-information/
                 name: "Josh"
                 surname: "Smith"
                     phone/
                        t0: "+34 123456789"
                        t1: "+34 1234567812"
                        t2: "+34 123243243"

The phone data is not sorted, what would be the way to sort it from the root of that user?

darshankawar commented 2 years ago

what would be the way to sort it from the root of that user?

I guess this question is better suited for support channels like Stackoverflow, so please ask the same there. Closing this issue.