androidgoogle-oauthmaui

Android App Link defaults to disabled when app is deployed (but works otherwise)


I'm migrating a .NET MAUI Android authorization flow from one that handles redirect using the now-deprecated custom URL scheme to one that employs an Android App Link verified via a Digital Asset Links file hosted on Firebase. The Android App Link is configured correctly and works perfectly once enabled on the Android device.

The issue is that when the app is installed—either via the Google Play Internal Test Track or sideloaded—the Android App Link is disabled by default. Users must manually:

  1. Navigate to (Phone) Settings > Apps > Set as Default > Supported Web Addresses,
  2. Toggle the switch for the link (e.g. myfirebasedomain.com) that is already present.

manual flow to enable link


My question: How can I ensure the Android App Link is enabled by default when the app is installed from Google Play? Is there a configuration or known workaround to avoid requiring users to enable the link manually?


UPDATE What I've Tried:

I followed the link referenced in the comments and went through it with a fine-tooth comb. Here are things that I not only tried, but went through time and again looking for anything I could have possibly overlooked.


  1. Compiled in Release Mode:

    • Built the APK in Release mode to ensure it is signed with the correct keystore and suitable for domain verification.
  2. Verified APK Signature:

    • Used the keytool -printcert -jarfile command to extract the SHA-256 fingerprint of the APK's signing certificate.
    • Confirmed that the extracted SHA-256 fingerprint matches the one listed in the assetlinks.json file.
  3. Checked assetlinks.json Accessibility:

    • Verified that the assetlinks.json file is hosted at https://echoessyncproxy.com/.well-known/assetlinks.json.
    • Confirmed accessibility by entering the URL directly in a browser.
  4. Validated App Link Behavior:

    • Tested the app link with adb shell am start -a android.intent.action.VIEW -d "https://echoessyncproxy.com/auth".
    • Confirmed that the WebAuthenticatorCallbackActivity is invoked, indicating the IntentFilter is working as expected.
  5. Tested Domain Verification:

    • Ran the adb shell pm get-app-links com.ivsoftware.echoessyncproxy.maui command to check the domain verification state.
    • Observed that the domain status is 1024, indicating verification failure. But why? This seems to be "the thing" but what's the reason for it?

Intent Filter

Here's the web authenticator callback activity (which, again, does work!) with the AutoVerify=True shown.

using Android.App;
using Android.Content;
using Android.OS;

namespace GoogleDriveLocalSyncProxy.Maui.TestProject.Platforms.Android
{

    [Activity(Label = "FirebaseCallback", Exported = true)]
    [IntentFilter(new[] { Intent.ActionView },
        Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
        DataScheme = "https",
        DataHost = "echoessyncproxy.com",
        DataPath ="/auth", 
        DataPathPrefix = "/auth",
        AutoVerify = true)]

    public class FirebaseCallback : WebAuthenticatorCallbackActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            System.Diagnostics.Debug.WriteLine($"{nameof(WebAuthenticatorCallbackActivity)}: code = {Intent?.Data?.GetQueryParameter("code")}");
        }
    }
}


JSON

https://echoessyncproxy.com/.well-known/assetlinks.json

{
  "relation": [ "delegate_permission/common.handle_all_urls" ],
  "target": {
    "namespace": "android_app",
    "package_name": "com.ivsoftware.echoessyncproxy.maui",
    "sha256_cert_fingerprints": [
      "A8:F5:14:1E:38:A7:1E:83:56:DC:63:9B:94:DF:06:B5:A1:54:06:BB:45:E7:02:E8:F0:2A:61:CC:55:58:C5:CA",
      "BB:D1:A0:90:5E:E9:F6:71:23:CB:99:A6:84:18:7A:E2:CD:BF:4B:AE:F8:C0:C6:46:6E:65:5C:8B:A8:3D:2C:34"
    ]
  }
}

ADB

>keytool -printcert -jarfile ...

Signer #1:

Certificate #1:
Owner: CN={my name}, OU={my org unit}, O={my company}, L={my city}, ST={my state}, C={my country}
Issuer: CN={my name}, OU={my org unit}, O={my company}, L={my city}, ST={my state}, C={my country}
Serial number: 1047269e
Valid from: Tue Dec 03 14:31:15 MST 2024 until: Sat Apr 20 15:31:15 MDT 2052
Certificate fingerprints:
         SHA1: A6:4F:C9:B3:A5:55:27:87:C5:DF:6F:2A:3B:BA:16:5A:4E:C0:7E:90
         SHA256: BB:D1:A0:90:5E:E9:F6:71:23:CB:99:A6:84:18:7A:E2:CD:BF:4B:AE:F8:C0:C6:46:6E:65:5C:8B:A8:3D:2C:34
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key


>adb shell pm get-app-links com.ivsoftware.echoessyncproxy.maui
  com.ivsoftware.echoessyncproxy.maui:
    ID: 926983c3-9969-42f4-9e39-e408c79dcc14
    Signatures: [BB:D1:A0:90:5E:E9:F6:71:23:CB:99:A6:84:18:7A:E2:CD:BF:4B:AE:F8:C0:C6:46:6E:65:5C:8B:A8:3D:2C:34]
    Domain verification state:
      echoessyncproxy.com: 1024

Code 0x0400 (1024) signifies "not verified".


Solution

  • ANSWER:

    Use Google's Statement List Generator and Tester to diagnose and correct the issue.

    AFAIK this has never been posted as an actual answer.


    Failure Analysis:

    This question is similar to Android Deep link- Supported web addresses and Digital Asset Link verified by Android Studio, but not pass in Google Play Console, and it would be fair to say that this question should close because it was caused by a typo, because in the end what was wrong is that my assetlinks.json file was this:

    {
      "relation": [ "delegate_permission/common.handle_all_urls" ],
      "target": {
        "namespace": "android_app",
        "package_name": "com.ivsoftware.echoessyncproxy.maui",
        "sha256_cert_fingerprints": [
          "A8:F5:14:1E:38:A7:1E:83:56:DC:63:9B:94:DF:06:B5:A1:54:06:BB:45:E7:02:E8:F0:2A:61:CC:55:58:C5:CA",
          "BB:D1:A0:90:5E:E9:F6:71:23:CB:99:A6:84:18:7A:E2:CD:BF:4B:AE:F8:C0:C6:46:6E:65:5C:8B:A8:3D:2C:34"
        ]
      }
    }
    

    ... when it should have been this:

    [{
      "relation": [ "delegate_permission/common.handle_all_urls" ],
      "target": {
        "namespace": "android_app",
        "package_name": "com.ivsoftware.echoessyncproxy.maui",
        "sha256_cert_fingerprints": [
          "A8:F5:14:1E:38:A7:1E:83:56:DC:63:9B:94:DF:06:B5:A1:54:06:BB:45:E7:02:E8:F0:2A:61:CC:55:58:C5:CA",
          "BB:D1:A0:90:5E:E9:F6:71:23:CB:99:A6:84:18:7A:E2:CD:BF:4B:AE:F8:C0:C6:46:6E:65:5C:8B:A8:3D:2C:34"
        ]
      }
    }]
    

    The point I'd like to make here is that I WOULD HAVE STARED AT THAT FOREVER!! if not for seeing a comment on the second question.

    @TWL comment


    The adb command ("what I've tried...") reported the verification failure without saying why. This tool, however, identified the cause and also generated the correct block. Being my first attempt at doing this, I was simply unaware of the existence of this tool.

    Before

    error message verbose

    After

    fixed