pusher / push-notifications-flutter

Official Pusher Beams Flutter client plugin (iOS, Android and Web), receive notifications easily on your Flutter application with Pusher Beams.
https://pub.dev/packages/pusher_beams
MIT License
10 stars 27 forks source link

[Bug] RangeError (index): Invalid value: Valid value range is empty: 0 #41

Open gonciuu opened 1 year ago

gonciuu commented 1 year ago

When I use the following method:

await beams.setUserId(
  userId,
  provider,
  (String? error) {
    debugPrint('Error setting user id');
  },
);

Everything works as expected - the notifications are consistently received. However, an error appears in the console:

======== Exception caught by services library ======================================================
The following RangeError was thrown during a platform message callback:
RangeError (index): Invalid value: Valid value range is empty: 0

When the exception was thrown, this was the stack: 
#0      _Array.[] (dart:core-patch/array.dart:10:36)
#1      PusherBeams.handleCallback (package:pusher_beams/pusher_beams.dart:336:22)
#2      CallbackHandlerApi.setup.<anonymous closure> (package:pusher_beams_platform_interface/method_channel_pusher_beams.dart:430:15)
#3      BasicMessageChannel.setMessageHandler.<anonymous closure> (package:flutter/src/services/platform_channel.dart:214:49)
#4      _DefaultBinaryMessenger.setMessageHandler.<anonymous closure> (package:flutter/src/services/binding.dart:393:35)
#5      _invoke2 (dart:ui/hooks.dart:183:13)
#6      _ChannelCallbackRecord.invoke (dart:ui/channel_buffers.dart:40:5)
#7      _Channel.push (dart:ui/channel_buffers.dart:130:31)
#8      ChannelBuffers.push (dart:ui/channel_buffers.dart:326:17)
#9      PlatformDispatcher._dispatchPlatformMessage (dart:ui/platform_dispatcher.dart:664:22)
#10     _dispatchPlatformMessage (dart:ui/hooks.dart:86:31)`

I have attempted to find a solution, but it seems to be an issue with the library itself.

1encore commented 1 year ago

getting the same error

flutter 3.7.11 platform ios 16 package version 1.1.1

CoolDude53 commented 1 year ago

bumping this @fbenevides

anyab5 commented 1 year ago

Getting the same error, it looks that if the auth succeed the platform handles it incorrectly at the callback handling. If I am attempting to send notification to the user after this error the notification received susccessfully.

I believe the reason for this error is this code:

 @override
  void handleCallback(String callbackId, String callbackName, List args) {
    final callback = _callbacks[callbackId]!;

    switch (callbackName) {
      case "onInterestChanges":
        callback((args[0] as List<Object?>).cast<String>());
        return;
      case "setUserId":
        callback(args[0] as String?);
        return;
      case "onMessageReceivedInTheForeground":
        callback((args[0] as Map<Object?, Object?>));
        return;
      default:
        callback();
        return;
    }
  }

for setUserId when there is no error there is an attempt to access args[0] in callback(args[0] as String?) but the args are empty so we get Array range error. Since the callback params setUesrId should be not empty only if error is happened the list being empty is an expected behavior for success. The code should probably change to something like this:

callback(args.isEmpty ? null : args[0] as String?);

FM1337 commented 1 year ago

Getting the same error, it looks that if the auth succeed the platform handles it incorrectly at the callback handling. If I am attempting to send notification to the user after this error the notification received susccessfully.

I believe the reason for this error is this code:

 @override
  void handleCallback(String callbackId, String callbackName, List args) {
    final callback = _callbacks[callbackId]!;

    switch (callbackName) {
      case "onInterestChanges":
        callback((args[0] as List<Object?>).cast<String>());
        return;
      case "setUserId":
        callback(args[0] as String?);
        return;
      case "onMessageReceivedInTheForeground":
        callback((args[0] as Map<Object?, Object?>));
        return;
      default:
        callback();
        return;
    }
  }

for setUserId when there is no error there is an attempt to access args[0] in callback(args[0] as String?) but the args are empty so we get Array range error. Since the callback params setUesrId should be not empty only if error is happened the list being empty is an expected behavior for success. The code should probably change to something like this:

callback(args.isEmpty ? null : args[0] as String?);

Should be a simple enough fix, perhaps if the main devs don't have time to implement it, someone could open a PR to fix it?

benjamin-tang-pusher commented 1 year ago

Hi, I'd like to merge https://github.com/pusher/push-notifications-flutter/pull/44, but I'd also like to reproduce the original issue. When I call setUserId(), it authorizes fine for me without throwing RangeError. I'm testing on Android however, are you using iOS or web browser target?

CoolDude53 commented 1 year ago

@benjamin-tang-pusher I'm using iOS, it seems to be the only platform affected (to my knowledge, I've tested android and iOS, but not web).

gonciuu commented 1 year ago

@benjamin-tang-pusher I was testing this on iOS simulator and real iOS device like half year ago and this Error occurs only on iOS (I've also tested android and everything worked fine).

dankhan-helmet commented 4 months ago

Just run into this today, still an issue on iOS using simulator or real device. The setUserid function doesn't return any args on iOS when successfully authenticating, causing the array index bug in the handleCallback function @anyab5 and others mentioned. Trying not to maintain my own local fork if possible :) Any news on merging @CoolDude53's PR? Thanks.