react-native-app-auth: authorize() returns error 'Data intent is null' on Android

Issue

Every time I call authorize() method I get Error: Data intent is null, whenever running on an Android emulator with ‘R’ operating system. Any idea what could be causing this error and how to fix it?

const config = {
  warmAndPrefetchChrome: Platform.OS === 'android',
  issuer,
  clientId,
  redirectUrl: 'testSchema://oauth/redirect',
  scopes: ['openid', 'profile', 'api', 'offline_access'],
  usePKCE: true,
};

export const authenticate = async () => {
  try {
    const result = await authorize(config);
    console.log('authorized')  // Execution never makes it to this line
    return result
  } catch (e) {
    throw new Error(e);
  }
};

In android/app/builde.gradle


    defaultConfig {
        applicationId "com.testApp"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0.0"
        resValue "string", "build_config_package", "com.testApp"
        manifestPlaceholders = [
            appAuthRedirectScheme: 'testSchema'
        ]

    }

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.testApp">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:allowBackup="false"
      android:theme="@style/AppTheme">
      <activity
        android:name=".SplashActivity"
        android:theme="@style/SplashTheme"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
            <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
        </intent-filter>
      </activity>
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:screenOrientation="portrait"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustResize"
        android:exported="true">
      </activity>
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
      <provider
		    android:name="com.vinzscam.reactnativefileviewer.FileProvider"
		    android:authorities="${applicationId}.provider"
		    android:exported="false"
		    android:grantUriPermissions="true">
		    <meta-data
		    	android:name="android.support.FILE_PROVIDER_PATHS"
		    	android:resource="@xml/file_viewer_provider_paths"
		    />
	    </provider>
    </application>

</manifest>

Fails on all 3 of these, but works fine on ‘Q’ or ‘Pie’ operating systems: Screenshot 2020-04-02 at 15 23 22

Environment

  • Your Identity Provider: IdentityServer 4
  • Platform that you’re experiencing the issue on: Android (specific to version ‘R’)
  • Are you using Expo? No

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 8
  • Comments: 58 (9 by maintainers)

Most upvoted comments

It seems this ticket is diverging into different issues. The issue I’m referring to is the Error: Data intent is null error.

The problem I experienced was due to having deeplink integration already in place, using reactnavigation.

You won’t see this issue if you have not defined other intent-filters for the same auth scheme.

Based on the reactnavigation instructions, I have the following set in my AndroidManifest.xml:

<activity
  android:name=".MainActivity"
  android:label="@string/app_name"
  android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
  android:launchMode="singleTask"
  android:windowSoftInputMode="adjustResize">
  <intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
  <intent-filter>
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="com.myapp" />
  </intent-filter>
</activity>

And for react-native-app-auth, I have set the following in my build.gradle:

android {
    defaultConfig {
        manifestPlaceholders = [
            appAuthRedirectScheme: 'com.myapp'
        ]
    }
}

Note that adding the above effectively is the same as explicitly adding a new activity & intent filter like so:

<activity
        android:name="net.openid.appauth.RedirectUriReceiverActivity"
        tools:node="replace">
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="com.myapp"/>
    </intent-filter>
</activity>

So now we have two activities handling the same scheme.

The result of this is that after logging in, I’m presented with an “Open With” prompt that shows my app twice. I assume because there are now effectively two intent-filter’s for the same scheme.

If I select the app that’s handling the .MainActivity activity, I get the Error: Data intent is null error. If I select the other app, the authentication works.

To “fix” this, I followed @AlkanV’s advice and used a different scheme for the authentication redirect url, set in the build.gradle:

android {
    defaultConfig {
        manifestPlaceholders = [
            appAuthRedirectScheme: 'com.myapp.auth'
        ]
    }
}

I then updated my redirect url to reflect the auth redirect scheme. After logging in, everything works. I don’t get the “open with” prompt and I don’t get the auth error. I don’t like that the app handles two different deeplinking schemes, but I’m not sure if this is a problem or not.

I will create a new ticket asking the library authors to update the example to include reactnavigation. Issue here: https://github.com/FormidableLabs/react-native-app-auth/issues/611

@anisimov74 i can’t share my manifest file as it contains a bunch of other activities and it will just confuse others. I can say that instead of using appAuthRedirectScheme I ended up explicitly adding the RedirectUriReceiverActivity activity into my AndroidManifest.xml:

<activity
  android:name="net.openid.appauth.RedirectUriReceiverActivity"
  tools:node="replace">
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="com.example.app.auth"/>
    </intent-filter>
</activity>

I see you’ve tried the same, but your sheme looks wrong to me. Should com.myapp be com.myapp.oauth?

We have exactly the same issue in our project. @yberstad your reproduction steps are correct.

To trigger “Data intent is null” error, the user must:

  1. Open the app (the example app will do)
  2. Start the authentication process (web page)
  3. Press home button
  4. Open the app again (through Home screen icon)
  5. Then the webview is automatically closed and the user sees the error.

To avoid the issue, the user, during step 4, must use Recent apps/Overview button/gesture to navigate back to the app.

For some reason, there is a difference in app-auth behavior depending on the user opening the app through the Home screen or Recent apps. One case always fails, the other succeeds.

We suspect it is due to onResume() method triggering finish() in AuthorizationManagementActivity.java of AppAuth-Android. https://github.com/openid/AppAuth-Android/blob/907ebbd890738e47c0c0c5d04fc6dfa6c449891b/library/java/net/openid/appauth/AuthorizationManagementActivity.java#L211

The issue is quite critical since in our case we need to use third-party banking apps to authenticate, so the users have to switch between apps. At the moment we have to manually instruct the users to use “Recent apps” instead of the home button, but that is not a good solution.

Same issue. Any updates?

Any update on this ? I am still facing same issue. I have applied all above changes but still facing same issue can some one help

I figured out the cause of the problem. There is a In Manifest.xml android:taskAffinity="", which should prevent possible phishing via task hijacking. https://github.com/FormidableLabs/react-native-app-auth/issues/674

@AlkanV thank you so much for your very quick response, much appreciated!

This is our current config:

{
  issuer: https://identity-dev.sharpnet.no,
  clientId: "sharpnetapp",
  redirectUrl: "sharpnet://signin-oidc",
  scopes: ["openid", "appdevice", "applogin"],
  additionalParameters: {}
};

/app/build.gradle:

manifestPlaceholders = [
    appAuthRedirectScheme: 'sharpnet'
]

And here is our current intent-filter’s in AndroidManifest.xml:

<activity
    android:name=".MainActivity"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
    android:label="@string/app_name"
    android:theme="@style/SplashTheme"
    android:launchMode="singleInstance"
    android:windowSoftInputMode="adjustResize">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
    </intent-filter>
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
    </intent-filter>
</activity>

Should I change it to this?

<activity
    android:name=".MainActivity"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
    android:label="@string/app_name"
    android:theme="@style/SplashTheme"
    android:launchMode="singleInstance"
    android:windowSoftInputMode="adjustResize">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
    </intent-filter>
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="sharpnet" />
    </intent-filter>
</activity>
<activity android:name="net.openid.appauth.RedirectUriReceiverActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="sharpnet"  />
    </intent-filter>
</activity>

Just a clarification, we are only getting “Data intent is null” for some our Android users. It is working for the majority of our users.

I resolved this by adding the link prefix into the build.gradle file

manifestPlaceholders = [
            appAuthRedirectScheme: 'com.mobileubdiapp',
            appAuthRedirectScheme: 'ubdi'
        ]

e.g. If the redirect URL is ubdi://connect, then you need to have ubdi listed here

I tried all solutions but getting same issue “Data intent is null”. If anyone have more suggestion or solution then please describe ??

1 change package name in redirectUrl com.YOUR_APP => com.YOUR_APP.auth

const config = {
      issuer: 'https://accounts.google.com',
      clientId: 'YOUR_clientId',
      redirectUrl: 'com.YOUR_APP.auth:/oauth2callback', 
     scopes: ['email', 'profile'],
};

2 change the package name on the google website com.YOUR_APP => com.YOUR_APP.auth

3 in build.gradle

android {
    defaultConfig {
        manifestPlaceholders = [
            appAuthRedirectScheme: 'com.YOUR_APP.auth'
        ]
    }
}

I’m out of ideas. IMO it would be useful if this repo has a reactnavigation example that people can refer to.

This is still issue for me and problem is that its only happending on some android devices!

The fix seems to be to change android:launchMode to “singleTop” in AndroidManifest.xml @yberstad, @DanielSchwartz89 @netanelh