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
176 stars 68 forks source link

Android missing query parameters of app link #136

Closed appcapsergen closed 4 days ago

appcapsergen commented 5 days 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 5 days ago

Are you testing from ADB?

appcapsergen commented 5 days ago

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

llfbandit commented 5 days ago

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

appcapsergen commented 5 days 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 5 days 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 5 days 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 5 days 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 5 days 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 5 days 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 5 days 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 5 days 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 days 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 days 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 days 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 21 hours 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