gbwisx / msal_mobile

Flutter plugin for single client authentication using the Microsoft Authentication Library (MSAL)
MIT License
10 stars 26 forks source link

Flutter - Unhandled Exception: NoSuchMethodError: The method '<optimized out>' was called on null #10

Open Faizan-sts opened 3 years ago

Faizan-sts commented 3 years ago

I've a simple app that generates pin for authentication. It has two views, First login screen with a login button and Second view simply shows the pin.

I'm using msal_mobile to authenticate user which redirects the control to Microsoft Authentication view and once authenticated the pin screen shows up. That's it.

Problem Is

I'm getting following error when pressing 'SignIn' button.

adb Logs ````bash 01-27 00:24:12.030 7107 10824 E flutter : [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: type '_AssertionError' is not a subtype of type 'Ca' in type cast 01-27 00:24:12.030 7107 10824 E flutter : Warning: This VM has been configured to produce stack traces that violate the Dart standard. 01-27 00:24:12.030 7107 10824 E flutter : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 01-27 00:24:12.030 7107 10824 E flutter : pid: 7107, tid: 10824, name 1.ui 01-27 00:24:12.030 7107 10824 E flutter : isolate_dso_base: 7e2b0c7000, vm_dso_base: 7e2b0c7000 01-27 00:24:12.030 7107 10824 E flutter : isolate_instructions: 7e2b0d6000, vm_instructions: 7e2b0c9000 01-27 00:24:12.030 7107 10824 E flutter : #00 abs 0000007e2b2d890b virt 000000000021190b _kDartIsolateSnapshotInstructions+0x20290b 01-27 00:24:12.030 7107 10824 E flutter : #01 abs 0000007e2b0f7e23 virt 0000000000030e23 _kDartIsolateSnapshotInstructions+0x21e23 01-27 00:24:12.030 7107 10824 E flutter : #02 abs 0000007e2b26d303 virt 00000000001a6303 _kDartIsolateSnapshotInstructions+0x197303 01-27 00:24:12.030 7107 10824 E flutter : #03 abs 0000007e2b0ed5b7 virt 00000000000265b7 _kDartIsolateSnapshotInstructions+0x175b7 01-27 00:24:12.030 7107 10824 E flutter : #04 abs 0000007e2b2ef353 virt 0000000000228353 _kDartIsolateSnapshotInstructions+0x219353 01-27 00:24:12.030 7107 10824 E flutter : #05 abs 0000007e2b0ee3ef virt 00000000000273ef _kDartIsolateSnapshotInstructions+0x183ef 01-27 00:24:12.030 7107 10824 E flutter : #06 abs 0000007e2b26d813 virt 00000000001a6813 _kDartIsolateSnapshotInstructions+0x197813 01-27 00:24:12.030 7107 10824 E flutter : #07 abs 0000007e2b26d77b virt 00000000001a677b _kDartIsolateSnapshotInstructions+0x19777b 01-27 00:24:12.030 7107 10824 E flutter : #08 abs 0000007e2b2d8473 virt 0000000000211473 _kDartIsolateSnapshotInstructions+0x202473 01-27 00:24:12.030 7107 10824 E flutter : 01-27 00:24:12.030 7107 10824 E flutter : 01-27 00:24:12.036 7107 10824 I flutter : fun() - initState - caught exception 01-27 00:24:12.036 7107 10824 E flutter : [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: type '_AssertionError' is not a subtype of type 'Ca' in type cast 01-27 00:24:12.036 7107 10824 E flutter : Warning: This VM has been configured to produce stack traces that violate the Dart standard. 01-27 00:24:12.036 7107 10824 E flutter : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 01-27 00:24:12.036 7107 10824 E flutter : pid: 7107, tid: 10824, name 1.ui 01-27 00:24:12.036 7107 10824 E flutter : isolate_dso_base: 7e2b0c7000, vm_dso_base: 7e2b0c7000 01-27 00:24:12.036 7107 10824 E flutter : isolate_instructions: 7e2b0d6000, vm_instructions: 7e2b0c9000 01-27 00:24:12.036 7107 10824 E flutter : #00 abs 0000007e2b2b938b virt 00000000001f238b _kDartIsolateSnapshotInstructions+0x1e338b 01-27 00:24:12.036 7107 10824 E flutter : #01 abs 0000007e2b0f7e23 virt 0000000000030e23 _kDartIsolateSnapshotInstructions+0x21e23 01-27 00:24:12.036 7107 10824 E flutter : #02 abs 0000007e2b26d303 virt 00000000001a6303 _kDartIsolateSnapshotInstructions+0x197303 01-27 00:24:12.036 7107 10824 E flutter : #03 abs 0000007e2b0ed5b7 virt 00000000000265b7 _kDartIsolateSnapshotInstructions+0x175b7 01-27 00:24:12.036 7107 10824 E flutter : #04 abs 0000007e2b2ef353 virt 0000000000228353 _kDartIsolateSnapshotInstructions+0x219353 01-27 00:24:12.036 7107 10824 E flutter : #05 abs 0000007e2b0ee3ef virt 00000000000273ef _kDartIsolateSnapshotInstructions+0x183ef 01-27 00:24:12.036 7107 10824 E flutter : #06 abs 0000007e2b26d813 virt 00000000001a6813 _kDartIsolateSnapshotInstructions+0x197813 01-27 00:24:12.036 7107 10824 E flutter : #07 abs 0000007e2b26d77b virt 00000000001a677b _kDartIsolateSnapshotInstructions+0x19777b 01-27 00:24:12.036 7107 10824 E flutter : #08 abs 0000007e2b2d8473 virt 0000000000211473 _kDartIsolateSnapshotInstructions+0x202473 01-27 00:24:12.036 7107 10824 E flutter : 01-27 00:24:12.036 7107 10824 E flutter : 01-22 18:28:54.242 8414 18547 E flutter : [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: NoSuchMethodError: The method '' was called on null. 01-22 18:28:54.242 8414 18547 E flutter : Receiver: null 01-22 18:28:54.242 8414 18547 E flutter : Tried calling: () 01-22 18:28:54.242 8414 18547 E flutter : Warning: This VM has been configured to produce stack traces that violate the Dart standard. 01-22 18:28:54.242 8414 18547 E flutter : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 01-22 18:28:54.242 8414 18547 E flutter : pid: 8414, tid: 18547, name 2.ui 01-22 18:28:54.242 8414 18547 E flutter : isolate_dso_base: 7e2b144000, vm_dso_base: 7e2b144000 01-22 18:28:54.242 8414 18547 E flutter : isolate_instructions: 7e2b153000, vm_instructions: 7e2b146000 01-22 18:28:54.242 8414 18547 E flutter : #00 abs 0000007e2b31f18b virt 00000000001db18b _kDartIsolateSnapshotInstructions+0x1cc18b 01-22 18:28:54.242 8414 18547 E flutter : #01 abs 0000007e2b252e9b virt 000000000010ee9b _kDartIsolateSnapshotInstructions+0xffe9b 01-22 18:28:54.242 8414 18547 E flutter : #02 abs 0000007e2b2cd16b virt 000000000018916b _kDartIsolateSnapshotInstructions+0x17a16b 01-22 18:28:54.242 8414 18547 E flutter : #03 abs 0000007e2b28e067 virt 000000000014a067 _kDartIsolateSnapshotInstructions+0x13b067 01-22 18:28:54.242 8414 18547 E flutter : #04 abs 0000007e2b28dacb virt 0000000000149acb _kDartIsolateSnapshotInstructions+0x13aacb 01-22 18:28:54.242 8414 18547 E flutter : #05 abs 0000007e2b291e9f virt 000000000014de9f _kDartIsolateSnapshotInstructions+0x13ee9f 01-22 18:28:54.242 8414 18547 E flutter : #06 abs 0000007e2b28cff7 virt 0000000000148ff7 _kDartIsolateSnapshotInstructions+0x139ff7 01-22 18:28:54.242 8414 18547 E flutter : #07 abs 0000007e2b28cf87 virt 0000000000148f87 _kDartIsolateSnapshotInstructions+0x139f87 01-22 18:28:54.242 8414 18547 E flutter : #08 abs 0000007e2b333037 virt 00000000001ef037 _kDartIsolateSnapshotInstructions+0x1e0037 01-22 18:28:54.242 8414 18547 E flutter : #09 abs 0000007e2b167a9f virt 0000000000023a9f _kDartIsolateSnapshotInstructions+0x14a9f 01-22 18:28:54.242 8414 18547 E flutter : #10 abs 0000007e2b1a5047 virt 0000000000061047 _kDartIsolateSnapshotInstructions+0x52047 01-22 18:28:54.242 8414 18547 E flutter : #11 abs 0000007e2b33321b virt 00000000001ef21b _kDartIsolateSnapshotInstructions+0x1e021b 01-22 18:28:54.242 8414 18547 E flutter : #12 abs 0000007e2b33313f virt 00000000001ef13f _kDartIsolateSnapshotInstructions+0x1e013f 01-22 18:28:54.242 8414 18547 E flutter : #13 abs 0000007e2b16a6d3 virt 00000000000266d3 _kDartIsolateSnapshotInstructions+0x176d3 01-22 18:28:54.242 8414 18547 E flutter : #14 abs 0000007e2b2d5383 virt 0000000000191383 _kDartIsolateSnapshotInstructions+0x182383 01-22 18:28:54.242 8414 18547 E flutter : #15 abs 0000007e2b2d57af virt 00000000001917af _kDartIsolateSnapshotInstructions+0x1827af 01-22 18:28:54.242 8414 18547 E flutter : #16 abs 0000007e2b32115b virt 00000000001dd15b _kDartIsolateSnapshotInstructions+0x1ce15b 01-22 18:28:54.242 8414 18547 E flutter : #17 abs 0000007e2b16a737 virt 0000000000026737 _kDartIsolateSnapshotInstructions+0x17737 01-22 18:28:54.242 8414 18547 E flutter : #18 abs 0000007e2b2d5383 virt 0000000000191383 _kDartIsolateSnapshotInstructions+0x182383 01-22 18:28:54.242 8414 18547 E flutter : #19 abs 0000007e2b32103f virt 00000000001dd03f _kDartIsolateSnapshotInstructions+0x1ce03f 01-22 18:28:54.242 8414 18547 E flutter : #20 abs 0000007e2b30f95b virt 00000000001cb95b _kDartIsolateSnapshotInstructions+0x1bc95b 01-22 18:28:54.242 8414 18547 E flutter : #21 abs 0000007e2b32038f virt 00000000001dc38f _kDartIsolateSnapshotInstructions+0x1cd38f 01-22 18:28:54.242 8414 18547 E flutter : #22 abs 0000007e2b3200b3 virt 00000000001dc0b3 _kDartIsolateSnapshotInstructions+0x1cd0b3 01-22 18:28:54.242 8414 18547 E flutter : #23 abs 0000007e2b1839fb virt 000000000003f9fb _kDartIsolateSnapshotInstructions+0x309fb 01-22 18:28:54.242 8414 18547 E flutter : ```` ``` [√] Flutter (Channel stable, 1.22.5, on Microsoft Windows [Version 10.0.17763.1697], locale en-GB) • Flutter version 1.22.5 at C:\Programs\flutter • Framework revision 7891006299 (6 weeks ago), 2020-12-10 11:54:40 -0800 • Engine revision ae90085a84 • Dart version 2.10.4 [!] Android toolchain - develop for Android devices (Android SDK version 30.0.2) • Android SDK at C:\Users\Dev.Admin\AppData\Local\Android\sdk • Platform android-30, build-tools 30.0.2 • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01) X Android license status unknown. Run `flutter doctor --android-licenses` to accept the SDK licenses. See https://flutter.dev/docs/get-started/install/windows#android-setup for more details. [√] Android Studio (version 4.0) • Android Studio at C:\Program Files\Android\Android Studio • Flutter plugin version 49.0.2 • Dart plugin version 193.7547 • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01) [√] Connected device (1 available) • SM G975F (mobile) • R58M90Z6B5X • android-arm64 • Android 10 (API 29) ! Doctor found issues in 1 category. ```

Don't know where's <optimized out> method coming from but It seems like the msalAuth.handleSignIn gets called when it's not initialised. Although app works fine if i don't obfuscate the build like flutter build apk --release --no-shrink. But I'm running into this problem now if Obfuscate the build like flutter build apk --obfuscate --split-debug-info=/<directory>.

As you can see i've msalAuth & isUserSignedIn properties in main. I'm trying to initialise MsalAuth class in main's initState() mehtod. And then passing msalAuth.handleSignin function reference to loginScreen. Which should be called on pressing SignIn button.

main.dart

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _MyAppState();
  }
}

class _MyAppState extends State<MyApp> {
  MsalAuth msalAuth;
  bool isUserSignedIn = false;
  PageController _controller = PageController(
    initialPage: 1,
  );

  @override
  void initState() {
    print('fun() - initState');
    print('SignedIn: ' + isUserSignedIn.toString());
    super.initState();
    msalAuth = new MsalAuth(this.refreshSignedInStatus);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  /// Updates the signed in state
  refreshSignedInStatus() {
    msalAuth.msalMobile.getSignedIn().then((loggedIn) {
      print('refreshing -  SignedIn: ' + loggedIn.toString());
      setState(() {
        isUserSignedIn = loggedIn;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(primaryColor: Colors.black),
      home: isUserSignedIn
          ? PageView(
              controller: _controller,
              children: [
                YesterdaysScreen(),
                TodaysScreen(msalAuth.activeUser),
                TomorrowsScreen()
              ],
            )
          : LoginScreen(
              msalAuth.handleSignIn,
              msalAuth.handleSignOut,
            ),
    );
  }
}

Login Screen

class LoginScreen extends StatelessWidget {
  final Function handleSignIn;
  final Function handleSignOut;

  LoginScreen(this.handleSignIn, this.handleSignOut);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('App Pin'),
      ),
      backgroundColor: Colors.black,
      body: Center(
        child: Column(
          children: <Widget>[
            Container(
              margin: EdgeInsets.only(top: 20, bottom: 40),
              child: Image.asset(
                'assets/app-logo.png',
                height: 150.0,
                fit: BoxFit.cover,
              ),
            ),
            Container(
              margin: EdgeInsets.all(10),
              height: 50.0,
              child: RaisedButton(
                onPressed: handleSignIn,
                child: Text("Sign In", style: TextStyle(fontSize: 15)),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

MsalAuth

class MsalAuth {
  static const String SCOPE = 'https://graph.microsoft.com/User.Read';
  static const String TENANT_ID = 'blahblah-blah-blah-blah-blah';
  static String authority = "https://login.microsoftonline.com/$TENANT_ID";
  Function refreshSignedinStatus;
  MsalMobile msalMobile;
  String activeUser = '-----';

  MsalAuth(this.refreshSignedinStatus) {
    MsalMobile.create(
      'assets/auth_config.json',
      authority,
    ).then((value) => msalMobile = value).catchError((exception) {
      print('fun() - initState - caught exception');
      if (exception is MsalMobileException) {
        logMsalMobileError(exception);
      } else {
        final ex = exception as Exception;
        print('exception occurred');
        print(ex.toString());
      }
    });
  }

  /// Signs a user in
  handleSignIn() async {
    await msalMobile.signIn(null, [SCOPE]).then((result) {
      refreshSignedinStatus();
    }).catchError((exception) {
      if (exception is MsalMobileException) {
        if (exception.errorCode == "already_signed_in") {
          refreshSignedinStatus();
        }
        logMsalMobileError(exception);
      } else {
        final ex = exception as Exception;
        print('exception occurred');
        print(ex.toString());
      }
    });

    // To populate activeUser on sign in.
    handleGetAccount();
  }
}

I'd like to add, before i bump into this issue, obfuscating the build was crashing the app on the startup on physical device. I got over it by adding -keep class com.microsoft.identity.** { *; } in to my proguard-rules.pro file. Now app doesn't crash on start but this NoSuchMethodError is being thrown.

Am i missing something to add further into my proguard rules ? As like i said before, the app works on physical device if i create a fat .apk

pubspec.yaml

version: 1.0.0+1

environment:
  sdk: ">=2.1.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^0.1.3

  msal_mobile: ^0.1.4  

  # aad_oauth: ^0.1.9
  intl: ^0.16.1

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_launcher_icons: "^0.8.0"

flutter_icons:
  android: "launcher_icon"
  ios: true
  image_path: "assets/app-icon.png"

flutter:

  uses-material-design: true

  assets:
    - assets/auth_config.json
    - assets/stevens-logo.png
JediIzzyT commented 3 years ago

Hello @Faizan-sts ,

As @clragon mentioned in issue #11 , you may find your solution here

You mentioned adding a proguard rule above, which is half of the solution.

To save you the click, @clragon suggests having both of these rules, which solved my issue:

-keep class com.microsoft.** { *; }
-keep class com.gbwisx.msal_mobile.** { *; }

The first stopped the crashing, and the second stopped the NoSuchMethodErrors for me.