Getting CANCELLED error after successful Spotify authentication in Flutter

I’m working on a Flutter app that integrates with Spotify’s authentication system. Everything seems to work fine during the login process, but after the user successfully logs in, my app receives a CANCELLED error message instead of proceeding with the authentication flow.

The issue happens right after the redirect URI brings the user back to my application. Instead of getting the expected response, I see a “user has canceled the login” message even though the login was completed successfully.

Here’s my authentication service code:

class SpotifyAuthService {
  static const appId = '//your-client-id';
  static const appSecret = '//your-client-secret';
  static const callbackUri = 'myflutterapp://auth-callback';

  static const String loginEndpoint = 'https://accounts.spotify.com/authorize';
  static const String accessTokenEndpoint = 'https://accounts.spotify.com/api/token';
  static const String profileEndpoint = 'https://api.spotify.com/v1/me';

  static Future<String?> performLogin() async {
    final loginUrlComplete =
        '$loginEndpoint?response_type=code&client_id=$appId&scope=user-read-private user-read-email&redirect_uri=$callbackUri';

    try {
      final authResult = await FlutterWebAuth.authenticate(
          url: loginUrlComplete, callbackUrlScheme: 'myflutterapp');

      final authCode = Uri.parse(authResult).queryParameters['code'];

      if (authCode != null) {
        return await _getAccessTokenFromCode(authCode);
      } else {
         return null;
      }
    } catch (error) {
      if (error.toString().contains('CANCELLED')) {
         print('User cancelled the authentication process.');
        return null;
      } else {
        print('Authentication error occurred: $error');
        return null;
      }
    }
  }

  static Future<String?> _getAccessTokenFromCode(String authCode) async {
    try {
      final httpClient = Dio();
      final tokenResponse = await httpClient.post(
        accessTokenEndpoint,
        data: {
          'grant_type': 'authorization_code',
          'code': authCode,
          'redirect_uri': callbackUri,
        },
        options: Options(
          headers: {
            'Authorization': 'Basic ' + base64Encode(utf8.encode('$appId:$appSecret')),
          },
        ),
      );

      if (tokenResponse.statusCode == 200) {
        return tokenResponse.data['access_token'];
      } else {
        print('Failed to retrieve access token: ${tokenResponse.statusCode}');
        return null;
      }
    } catch (error) {
      print('Token exchange error: $error');
      return null;
    }
  }

  static Future<Map<String, dynamic>?> fetchUserData(String accessToken) async {
///
}

After successful authentication, I need to navigate to the main screen and display user information. Any ideas on what might be causing this CANCELLED error?

had this exact issue last month! the prob’s prbly your callback url scheme in the android manifest. make sure you added the intent filter correctly with the scheme ‘myflutterapp’ - without it, the redirect gets treated as cancelled even tho login worked.

I hit the same CANCELLED error with Spotify auth. The problem was FlutterWebAuth’s result parsing - there’s a delay between successful auth and your app processing the callback URL. Here’s what worked: don’t treat every exception as cancellation. Add specific error type checks instead. Sometimes Spotify auth actually succeeds, but the callback URL gets mangled or has error parameters during redirect. Log the raw authResult string before parsing it. I found the callback URL was getting truncated or modified by the system, which broke parsing and triggered the CANCELLED exception. Also consider adding a retry mechanism - this issue comes and goes depending on system load and network conditions.

This usually happens when the authentication flow has timing issues. FlutterWebAuth sometimes thinks a slow redirect means the user canceled. I ran into this when Spotify’s redirect took too long to get back to my app. Try adding a longer timeout to your authenticate call and double-check that your app’s URL scheme is set up correctly in both Android and iOS. Also, make sure your redirect URI in the Spotify developer console matches exactly what you’re using in code - even trailing slashes can break things. One more thing: test on a real device instead of the simulator since URL schemes can act weird in simulators.