brim-borium / spotify_sdk

Flutter Package to connect the spotify sdk
https://pub.dev/packages/spotify_sdk
Apache License 2.0
143 stars 81 forks source link

Web SDK subscribePlayerState `Uncaught TypeError: null: type 'minified:p1' is not a subtype of type 'bool'` #118

Closed nzoschke closed 2 years ago

nzoschke commented 3 years ago

Describe the bug

The Web SDK subscribePlayerState method is no longer streaming player state events. Instead its returning an error in the JS console:

Uncaught TypeError: null: type 'minified:p1' is not a subtype of type 'bool'
    at Object.b (js_helper.dart:1130)
    at Object.dy (rti.dart:1108)
    at a4L.$1 (player_restrictions.g.dart:11)
    at a4X.$1 (stream.dart:554)
    at Nm.k8 (zone.dart:1546)
    at nv.i1 (stream_impl.dart:341)
    at ny.Br (stream_impl.dart:591)
    at rP.KN (stream_impl.dart:706)
    at aaZ.$0 (stream_impl.dart:663)
    at Object.aBJ (schedule_microtask.dart:40)

To Reproduce Steps to reproduce the behavior:

Follow the docs for the web SDK and define a

SpotifySdk.subscribePlayerState().forEach((s) async {
  print('subscribePlayerState $s');
}

Expected behavior

I expect the player state stream function to be called with player state events;

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

Additional context

This was working just fine and suddenly broke today.

It looks like we're getting null values in the Web Playback State object, but the Dart SDK is not prepared to handle them.

The docs do state that these properties can be null:

https://developer.spotify.com/documentation/web-playback-sdk/reference/#object-web-playback-state

  disallows: {                // A simplified set of restriction controls for
    pausing: false,           // The current track. By default, these fields
    peeking_next: false,      // will either be set to false or undefined, which
    peeking_prev: false,      // indicates that the particular operation is
    resuming: false,          // allowed. When the field is set to `true`, this
    seeking: false,           // means that the operation is not permitted. For
    skipping_next: false,     // example, `skipping_next`, `skipping_prev` and
    skipping_prev: false      // `seeking` will be set to `true` when playing an
                              // ad track.

Here's a diff that helps confirm what is happening and works as a quick fix

diff --git a/lib/models/player_restrictions.g.dart b/lib/models/player_restrictions.g.dart
index 25b2f36..4ac608b 100644
--- a/lib/models/player_restrictions.g.dart
+++ b/lib/models/player_restrictions.g.dart
@@ -7,6 +7,7 @@ part of 'player_restrictions.dart';
 // **************************************************************************

 PlayerRestrictions _$PlayerRestrictionsFromJson(Map<String, dynamic> json) {
+  print('PlayerRestrictionsFromJson $json');
   return PlayerRestrictions(
     canSkipNext: json['can_skip_next'] as bool,
     canSkipPrevious: json['can_skip_prev'] as bool,
diff --git a/lib/spotify_sdk_web.dart b/lib/spotify_sdk_web.dart
index 2913876..143a6c1 100644
--- a/lib/spotify_sdk_web.dart
+++ b/lib/spotify_sdk_web.dart
@@ -714,9 +714,9 @@ class SpotifySdkPlugin {
       state.position,
       options.PlayerOptions(repeatMode, isShuffling: state.shuffle),
       PlayerRestrictions(
-          canSkipNext: restrictionsRaw.skipping_next,
-          canSkipPrevious: restrictionsRaw.skipping_prev,
-          canSeek: restrictionsRaw.seeking,
+          canSkipNext: restrictionsRaw.skipping_next || true,
+          canSkipPrevious: restrictionsRaw.skipping_prev || true,
+          canSeek: restrictionsRaw.seeking || true,
           canRepeatTrack: true,
           canRepeatContext: true,
           canToggleShuffle: true),

This prints:

PlayerRestrictionsFromJson {can_skip_next: null, can_skip_prev: true, can_repeat_track: true, can_repeat_context: true, can_toggle_shuffle: true, can_seek: null}