llfbandit / app_links

Android App Links, Deep Links, iOs Universal Links and Custom URL schemes handler for Flutter.
https://pub.dev/packages/app_links
Apache License 2.0
220 stars 81 forks source link

Android missing query parameters of app link #136

Closed appcapsergen closed 4 months ago

appcapsergen commented 4 months ago

Describe the bug

When setting an app link for my app, when such an app link is opened in the app, it leaves out all the query parameters. So: https://my.host/pathPart1/pathPart2?queryParam1=something&queryParam2=something becomes https://my.host/pathPart1/pathPart2.

Does it related to

Does the example project work?

Did you fully read the instructions for the targeted platform before submitting this issue?

llfbandit commented 4 months ago

Are you testing from ADB?

appcapsergen commented 4 months ago

@llfbandit no, this also happens with a released version of the app.

llfbandit commented 4 months ago

Can you provide your setup? manifest and stream subscription callback? URI are not touched in any way.

appcapsergen commented 4 months ago

@llfbandit

app/src/main/AndroidManifest.xml

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

    <queries>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="https" />
        </intent>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="market" />
        </intent>

        <provider
            android:authorities="com.facebook.katana.provider.PlatformProvider"
            android:exported="false" /> <!-- allows app to access Facebook app features -->
        <provider
            android:authorities="com.facebook.orca.provider.PlatformProvider"
            android:exported="false" /> <!-- allows sharing to Messenger app -->
    </queries>

    <application
        android:name="${applicationName}"
        android:hardwareAccelerated="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:networkSecurityConfig="@xml/network_security_config"
        android:requestLegacyExternalStorage="true"
        android:usesCleartextTraffic="true"
        tools:targetApi="n">
        <activity
            android:name=".MainActivity"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:exported="true"
            android:hardwareAccelerated="true"
            android:launchMode="singleTop"
            android:supportsPictureInPicture="true"
            android:theme="@style/LaunchTheme"
            android:windowSoftInputMode="adjustResize">
            <!-- Theme to apply as soon as Flutter begins rendering frames -->
            <meta-data
                android:name="io.flutter.embedding.android.NormalTheme"
                android:resource="@style/NormalTheme" />

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="FLUTTER_NOTIFICATION_CLICK" />
                <category android:name="android.intent.category.DEFAULT" />
            </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:host="@string/universal_link_host"
                    android:scheme="https" />
            </intent-filter>
        </activity>
    </application>
</manifest>

build.gradle

android {
    namespace 'com.webuildapps.huddle'

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

    defaultConfig {
        minSdkVersion 23
        compileSdk 34
        targetSdkVersion 34
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName

        multiDexEnabled true
    }

    flavorDimensions "app"
    productFlavors {
        huddle {
            dimension "app"
            resValue "string", "app_name", "Huddle"
            resValue "string", "universal_link_host", "link.thehuddle.nl"
            applicationId "xxx"
        }
        imu {
            dimension "app"
            resValue "string", "app_name", "IMU+"
            resValue "string", "universal_link_host", "link.imu.nl"
            applicationId "xxx"
        }
    }
    lint {
        disable 'InvalidPackage'
    }
}

Stream subscription

  Future<void> configureUniversalLinks() async {
    try {
      _pendingUniversalLink = await _appLinks.getInitialLink();

      _appLinks.uriLinkStream.listen(
        _handleIncomingUniversalLink,
        onError: (dynamic error) => print('Exception: App links stream error - $error'),
      );
    } on PlatformException {
      print('Unable to configure universal links');
    }
  }

  Future<void> _handleIncomingUniversalLink(Uri link) async {
    final bool authRequired = _isAuthorizationRequiredForLink(link);

    if (authRequired && isOnUnauthorizedRoute) {
      _pendingUniversalLink = link;
    } else {
      await openUniversalLink(link);
    }
  }

  /// The `openUniversalLink` method then parses the universal/app link that came in and opens the right screen,
  /// but this is not relevant, as the link is already coming in wrong here (without query parameters).
appcapsergen commented 4 months ago

Also maybe good to note, before switching to app_links, I used uni_links package, which did the exact same thing but handled it with a String instead of a Uri. The same issue was present there, where then the string would also miss the query parameters. Maybe this is just an issue with Android or with Android universal/app links, but I can't find anything online about anybody having the same issue...

llfbandit commented 4 months ago

There's a missing piece here. Your setup is OK as far as I can tell.

Are you sure about your input? Can you test this with ADB and the following command?

adb shell am start -a android.intent.action.VIEW -d "https://link.thehuddle.nl/path1/path2?param1=a&param2=b"

Not sure if it works with app links. If not, you can put this URL in an email or whatever and launch it. Just don't use a browser.

appcapsergen commented 4 months ago

@llfbandit I have tried that yes, and when I do the query parameters are left out. Whether I do it from an email, from notes or with that adb shell command, it makes no difference.

llfbandit commented 4 months ago

Ok, you should get some log in debug mode from native part with the tag "com.llfbandit.app_links" in logcat. I guess the URL is also "truncated" at this time, right? Can you share it?

appcapsergen commented 4 months ago

@llfbandit This is all I see:

2024-06-26 16:16:01.237 27746-27746 com.llfbandit.app_links com.webuildapps.huddle               D  Intent { act=android.intent.action.VIEW cat=[android.intent.category.BROWSABLE] dat=https://link.thehuddle.nl/... flg=0x14400000 cmp=com.webuildapps.huddle/.MainActivity (has extras) }
2024-06-26 16:16:01.237 27746-27746 com.llfbandit.app_links com.webuildapps.huddle               D  Handled intent: action: android.intent.action.VIEW / data: https://link.thehuddle.nl/1/auth/v4/link-login/c7734e60bd9a8aa820871b5c24aa55eaa756f26eaea3a1c98f7c3a2ccca3dfde
llfbandit commented 4 months ago

So if query params are missing from this URL https://link.thehuddle.nl/1/auth/v4/link-login/c7734... I can't do anything unfortunately. This URL comes directly from the system... It must be something else because I use myself the package with many query parameters without any issue.

appcapsergen commented 4 months ago

@llfbandit could it be a device specific issue? Otherwise it doesn't make much sense to me how this would go wrong honestly...

christofkost commented 4 months ago

I have a very similar problem. I have this URL:app://com.example.test/dashboard/fairground/hall-plan?hallId=11.0&highlightedBoothId=110_foy02&navigationOriginIsHallPlan=false

The parameter after question mark is taken into account, the query params after & are ignored. So my example URL results in app://com.example.test/dashboard/fairground/hall-plan?hallId=11.0

Here a screenshot from debugger:

Screenshot 2024-06-27 at 16 49 07

When I replace & with ?, it looks like that:

Screenshot 2024-06-27 at 16 51 48
llfbandit commented 4 months ago

@christofkost it feels like a typical issue ADB testing. If so, you must escape '&' with backslash or wrap the URL with double quotes.

appcapsergen commented 4 months ago

Thank you to both of you for attempting to help. Fortunately, I've found the issue, and it did not have anything to do with the device, the package or anything. The issue was very specific and had to do with our website, luckily it's been found and fixed!

christofkost commented 4 months ago

@christofkost it feels like a typical issue ADB testing. If so, you must escape '&' with backslash or wrap the URL with double quotes.

Using both double quotes and backslashes solved the issue. Thank you very much for your help! More info: https://stackoverflow.com/questions/35645414/android-deep-linking-with-multiple-query-parameters

jrwhit commented 1 month ago

Obrigado a ambos por tentarem ajudar. Felizmente, encontrei o problema, e não tinha nada a ver com o dispositivo, o pacote ou qualquer coisa. O problema era muito específico e tinha a ver com nosso site, felizmente foi encontrado e corrigido!

How did you find out it was the website and how did you resolve it?

appcapsergen commented 1 month ago

How did you find out it was the website and how did you resolve it?

I found out the links that were being opened were links starting with http, while my app only supported https. I now fixed the links and also support opening links starting with http to fix the issue!

jrwhit commented 1 month ago

Como você descobriu que era o site e como resolveu o problema?

Descobri que os links que estavam sendo abertos eram links que começavam com http, enquanto meu aplicativo só suportava https. Agora, consertei os links e também suportei a abertura de links que começam com httppara corrigir o problema!

I'm having a similar problem and I can't find the cause.

appcapsergen commented 1 month ago

@jrwhit look for /universal_link_host in app/src/main/AndroidManifest.xml. If you only support https but also need to support links starting with http, add it.