> ## Documentation Index
> Fetch the complete documentation index at: https://help.airbridge.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting - Flutter SDK

## iOS

<AccordionGroup>
  <Accordion title="The domain of saved passwords appears as airbridge.io or abr.ge">
    #### Problem

    Users may see the domain of passwords stored with the [Password AutoFill](https://developer.apple.com/documentation/security/password-autofill) feature as airbridge.io or abr.ge.

    #### Cause

    After setting up deep links for the Airbridge SDK, if you utilize the Password AutoFill feature, the domain is saved as the applinks domain of the Airbridge deep link, which is airbridge.io or abr.ge.

    #### Solution

    The problem can be solved by setting up the webcredentials domain used in the Password AutoFill.

    1. Prepare the domain that will store the password.

    2. Host the JSON below at `https://YOUR_DOMAIN/.well-known/apple-app-site-association` with `Content-Type: application/json`. Your prepared domain should be entered instead of `YOUR_DOMAIN`.

    You can find the App ID Prefix and Bundle ID in the **\[Identifiers]>\[YOUR\_APP]** menu of the [Apple Developer Portal](https://developer.apple.com/account/resources).

    ```json lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    {
        "webcredentials": {
            "apps": ["YOUR_APP_ID_PREFIX.YOUR_BUNDLE_ID"]
        }
    }
    ```

    3. Navigate to **\[YOUR\_PROJECT]>\[Signing & Capabilities]** in Xcode.

    4. Click **+ Capability** to add Associated Domains. Enter `webcredentials:YOUR_DOMAIN` in Associated Domains.
  </Accordion>

  <Accordion title="Upload Symbol Failed on Xcode">
    #### Problem

    Upon uploading the app to the App Store, Xcode displays a warning message that a dSYM for the Airbridge framework was not included.

    #### Cause

    The Airbridge iOS SDK does not support dSYM.

    #### Solution

    The dSYM will be supported in the coming update. You may ignore this warning.
  </Accordion>

  <Accordion title="Tracking links open the app but don't navigate to the intended page, or the deeplink isn't delivered.">
    #### **Problem**

    When the app is launched via an Airbridge tracking link (Universal Link / URI scheme), the following may occur:

    * The app does not navigate to the destination (scheme deeplink) set on the tracking link.
    * The scheme deeplink is not delivered to the deeplink listener, and the Deeplink Open event or the destination delivery for a deferred deeplink does not work.

    #### Cause

    Starting from v3.7, Flutter improved its ability to handle deeplinks directly through the framework's Router API without an external plugin. On iOS, when the `FlutterDeepLinkingEnabled` key in `Info.plist` is `true` or the default handler is active, the Flutter engine intercepts the incoming Universal Link / scheme and routes it through the app's Router.

    The Airbridge SDK receives the Airbridge deeplink in `AppDelegate` (`application(_:open:options:)`, `application(_:continue:restorationHandler:)`) via `AirbridgeFlutter.trackDeeplink`, converts it into the scheme deeplink, and then delivers it to the app. When Flutter's default deeplink handler conflicts with this flow, the converted scheme deeplink is not delivered to the app properly.

    #### Solution

    Set the `FlutterDeepLinkingEnabled` key in `Info.plist` to the Boolean value `false`. (Xcode's property list editor displays this `Boolean` value as `NO`.)

    ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    <key>FlutterDeepLinkingEnabled</key>
    <false/>
    ```

    After applying this setting, also verify that the Airbridge SDK's native deeplink integration (`AirbridgeFlutter.trackDeeplink(url:)`, `AirbridgeFlutter.trackDeeplink(userActivity:)`) in `AppDelegate` has not been omitted.
  </Accordion>

  <Accordion title="[Xcode 27] SceneDelegate Migration Required — Additional Setup Needed for Airbridge Deep Links">
    <Note>
      **Attention**

      This troubleshooting guide is for customers who need to migrate an existing AppDelegate-based app to UIScene(SceneDelegate) lifecycle.
    </Note>

    #### **Problem**

    * When you run an app built with Xcode 27, an EXC\_BAD\_ACCESS (code=1, address=0x0) crash occurs near GeneratedPluginRegistrant.register(with:) and the app terminates immediately.
    * Airbridge deep link events are not collected even when the app is opened through a scheme deep link or Universal Link.
    * The app does not work even though the code was added to `AppDelegate` as shown in the [Initialize SDK](/en/developers/flutter-sdk-v4#initialize-sdk) and [Collect deep link events in your app](/en/developers/flutter-sdk-v4#enable-airbridge-deep-link-event-collection) developer guide examples.

    #### **Cause**

    Apple is moving the app lifecycle from the `UIApplicationDelegate`-only AppDelegate model to the `UIScene`-based SceneDelegate model, and adopting the Scene lifecycle has effectively become required in the latest Xcode and iOS environments.

    When an app adopts the Scene lifecycle through `UIApplicationSceneManifest`, the following `AppDelegate` callbacks are **no longer called.**

    | Existing AppDelegate callback                                     | Replacement callback in the Scene lifecycle (`SceneDelegate`) |
    | ----------------------------------------------------------------- | ------------------------------------------------------------- |
    | `window` creation in `application:didFinishLaunchingWithOptions:` | `scene:willConnectToSession:options:`                         |
    | Deep link at app cold start                                       | `connectionOptions` of `scene:willConnectToSession:options:`  |
    | `application:openURL:options:`                                    | `scene:openURLContexts:`                                      |
    | `application:continueUserActivity:restorationHandler:`            | `scene:continueUserActivity:`                                 |

    #### **Solution**

    <Tabs>
      <Tab title="Airbridge Flutter SDK 4.10.0 or later">
        | Deep link when the app is terminated | In `scene:willConnectToSession:options:`, call `trackDeeplink(connectionOptions:)` with `connectionOptions` |
        | ------------------------------------ | ----------------------------------------------------------------------------------------------------------- |
        | Scheme deep link (background)        | In `scene:openURLContexts:`, call `trackDeeplink(openURLContexts:)` with `URLContexts`                      |
        | Universal Link (background)          | In `scene:continueUserActivity:`, call `trackDeeplink(userActivity:)` with `NSUserActivity`                 |
      </Tab>

      <Tab title="Airbridge Flutter SDK earlier than 4.10.0">
        | Deep link when the app is terminated | In `scene:willConnectToSession:options:`, from `connectionOptions`<br />- extract `URL` from `URLContexts` and call `trackDeeplinkWithUrl:`<br />- extract `NSUserActivity` from `userActivities` and call `trackDeeplinkWithUserActivity:` |
        | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
        | Scheme deep link (background)        | Extract `URL` from `URLContexts` and call `trackDeeplinkWithUrl:`                                                                                                                                                                           |
        | Universal Link (background)          | Extract `NSUserActivity` from `userActivities` and call `trackDeeplinkWithUserActivity:`                                                                                                                                                    |
      </Tab>
    </Tabs>

    ##### 1. Add Scene Manifest to Info.plist

    Add the following UIApplicationSceneManifest to Info.plist. Set UISceneDelegateClassName to match the module you use, and **be sure to set** **UISceneStoryboardFile** **to** **Main**. (Without this value, FlutterViewController is not created as the scene's rootViewController, so plugin registration fails.)

    ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    <key>UIApplicationSceneManifest</key>
    <dict>
        <key>UIApplicationSupportsMultipleScenes</key>
        <false/>
        <key>UISceneConfigurations</key>
        <dict>
            <key>UIWindowSceneSessionRoleApplication</key>
            <array>
                <dict>
                    <key>UISceneConfigurationName</key>
                    <string>Default Configuration</string>
                    <key>UISceneDelegateClassName</key>
                    <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
                    <key>UISceneStoryboardFile</key>
                    <string>Main</string>
                </dict>
            </array>
        </dict>
    </dict>
    ```

    ##### 2. Create SceneDelegate and move the deep link collection code to SceneDelegate

    <Tabs>
      <Tab title="Swift SDK 4.10.0 or later">
        ```swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        import UIKit
        import Flutter
        import airbridge_flutter_sdk

        class SceneDelegate: UIResponder, UIWindowSceneDelegate {
            var window: UIWindow?

            // when terminated app is opened with scheme deeplink or universal links
            func scene(_ scene: UIScene,
                       willConnectTo session: UISceneSession,
                       options connectionOptions: UIScene.ConnectionOptions) {
                guard let windowScene = scene as? UIWindowScene else { return }

                // In the Scene lifecycle, the window is owned by the SceneDelegate,
                // so plugins must be registered against the FlutterViewController, not the AppDelegate.
                if let controller = window?.rootViewController as? FlutterViewController {
                    GeneratedPluginRegistrant.register(with: controller)
                }

                // track deeplink
                AirbridgeFlutter.trackDeeplink(connectionOptions: connectionOptions)
            }

            // when backgrounded app is opened with scheme deeplink
            func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
                // track deeplink
                AirbridgeFlutter.trackDeeplink(openURLContexts: URLContexts)
            }

            // when backgrounded app is opened with universal links
            func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
                // track deeplink
                AirbridgeFlutter.trackDeeplink(userActivity: userActivity)
            }
        }
        ```
      </Tab>

      <Tab title="Objective-C SDK 4.10.0 or later">
        ```objective-c lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        // SceneDelegate.h
        #import <UIKit/UIKit.h>

        API_AVAILABLE(ios(13.0))
        @interface SceneDelegate : UIResponder <UIWindowSceneDelegate>

        @property (strong, nonatomic) UIWindow *window;

        @end

        // SceneDelegate.m
        #import "SceneDelegate.h"
        #import "AppDelegate.h"
        #import <Flutter/Flutter.h>
        #import "GeneratedPluginRegistrant.h"
        #import <airbridge_flutter_sdk/AirbridgeFlutter.h>

        @implementation SceneDelegate

        // when terminated app is opened with scheme deeplink or universal links
        - (void)scene:(UIScene *)scene
            willConnectToSession:(UISceneSession *)session
                         options:(UISceneConnectionOptions *)connectionOptions
        {
          // In the Scene lifecycle, the window is owned by the SceneDelegate,
          // so plugins must be registered against the FlutterViewController, not the AppDelegate.
          if ([self.window.rootViewController isKindOfClass:[FlutterViewController class]]) {
            FlutterViewController *controller = (FlutterViewController *)self.window.rootViewController;
            [GeneratedPluginRegistrant registerWithRegistry:controller];
          }

          // track deeplink
          [AirbridgeFlutter trackDeeplinkWithConnectionOptions:connectionOptions];
        }

        // when backgrounded app is opened with scheme deeplink
        - (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts
        {
          // track deeplink
          [AirbridgeFlutter trackDeeplinkWithOpenURLContexts:URLContexts];
        }

        // when backgrounded app is opened with universal links
        - (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity
        {
          // track deeplink
          [AirbridgeFlutter trackDeeplinkWithUserActivity:userActivity];
        }

        @end
        ```
      </Tab>

      <Tab title="Swift SDK earlier than 4.10.0">
        ```swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        import UIKit
        import Flutter
        import airbridge_flutter_sdk

        class SceneDelegate: UIResponder, UIWindowSceneDelegate {
            var window: UIWindow?

            // when terminated app is opened with scheme deeplink or universal links
            func scene(_ scene: UIScene,
                       willConnectTo session: UISceneSession,
                       options connectionOptions: UIScene.ConnectionOptions) {
                guard let windowScene = scene as? UIWindowScene else { return }

                // In the Scene lifecycle, the window is owned by the SceneDelegate,
                // so plugins must be registered against the FlutterViewController, not the AppDelegate.
                if let controller = window?.rootViewController as? FlutterViewController {
                    GeneratedPluginRegistrant.register(with: controller)
                }

                // track deeplink
                if let context = connectionOptions.urlContexts.first {
                    AirbridgeFlutter.trackDeeplink(url: context.url)
                }
                if let userActivity = connectionOptions.userActivities.first {
                    AirbridgeFlutter.trackDeeplink(userActivity: userActivity)
                }
            }

            // when backgrounded app is opened with scheme deeplink
            func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
                // track deeplink
                if let context = URLContexts.first {
                    AirbridgeFlutter.trackDeeplink(url: context.url)
                }
            }

            // when backgrounded app is opened with universal links
            func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
                // track deeplink
                AirbridgeFlutter.trackDeeplink(userActivity: userActivity)
            }
        }
        ```
      </Tab>

      <Tab title="Objective-C SDK eariler than 4.10.0">
        ```objective-c lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
        // SceneDelegate.h
        #import <UIKit/UIKit.h>

        API_AVAILABLE(ios(13.0))
        @interface SceneDelegate : UIResponder <UIWindowSceneDelegate>

        @property (strong, nonatomic) UIWindow *window;

        @end

        // SceneDelegate.m
        #import "SceneDelegate.h"
        #import "AppDelegate.h"
        #import <Flutter/Flutter.h>
        #import "GeneratedPluginRegistrant.h"
        #import <airbridge_flutter_sdk/AirbridgeFlutter.h>

        @implementation SceneDelegate

        // when terminated app is opened with scheme deeplink or universal links
        - (void)scene:(UIScene *)scene
            willConnectToSession:(UISceneSession *)session
                         options:(UISceneConnectionOptions *)connectionOptions
        {
          // In the Scene lifecycle, the window is owned by the SceneDelegate,
          // so plugins must be registered against the FlutterViewController, not the AppDelegate.
          if ([self.window.rootViewController isKindOfClass:[FlutterViewController class]]) {
            FlutterViewController *controller = (FlutterViewController *)self.window.rootViewController;
            [GeneratedPluginRegistrant registerWithRegistry:controller];
          }

          // track deeplink
          UIOpenURLContext *context = connectionOptions.URLContexts.allObjects.firstObject;
          if (context != nil) {
            [AirbridgeFlutter trackDeeplinkWithUrl:context.URL];
          }
          NSUserActivity *userActivity = connectionOptions.userActivities.allObjects.firstObject;
          if (userActivity != nil) {
            [AirbridgeFlutter trackDeeplinkWithUserActivity:userActivity];
          }
        }

        // when backgrounded app is opened with scheme deeplink
        - (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts
        {
          // track deeplink
          UIOpenURLContext *context = URLContexts.allObjects.firstObject;
          if (context != nil) {
            [AirbridgeFlutter trackDeeplinkWithUrl:context.URL];
          }
        }

        // when backgrounded app is opened with universal links
        - (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity
        {
          // track deeplink
          [AirbridgeFlutter trackDeeplinkWithUserActivity:userActivity];
        }

        @end
        ```
      </Tab>
    </Tabs>

    ##### 3. Clean up AppDelegate

    * Leave the SDK initialization code (`initializeSDK`) in `application:didFinishLaunchingWithOptions:` **as is.**
    * The `application:openURL:options:` and `application:continueUserActivity:restorationHandler:`methods you wrote to collect deep links are not called in the Scene lifecycle, so after moving them to `SceneDelegate`, delete them from `AppDelegate`.
    * `GeneratedPluginRegistrant.register(with: self)` relies on `FlutterAppDelegate` building the plugin registrar through `self.window.rootViewController` (FlutterViewController). In the Scene lifecycle the `window` is owned by the `SceneDelegate`, so `AppDelegate`'s `self.window` becomes `nil`. As a result the registrar is returned as `nil`, and a plugin that dereferences this `nil` triggers an `EXC_BAD_ACCESS (address=0x0)` crash. Therefore plugin registration (`GeneratedPluginRegistrant.register`) **must be moved to the** **`SceneDelegate`**, **where** **`FlutterViewController`** **exists.**

    ```swift lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    import UIKit
    import Flutter
    import airbridge_flutter_sdk

    @main
    @objc class AppDelegate: FlutterAppDelegate {
        override func application(
            _ application: UIApplication,
            didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
        ) -> Bool {
            AirbridgeFlutter.initializeSDK(name: "YOUR_APP_NAME", token: "YOUR_APP_TOKEN")

    				// Moved to SceneDelegate (Deleted)
            // GeneratedPluginRegistrant.register(with: self)

            return super.application(application, didFinishLaunchingWithOptions: launchOptions)
        }
    }
    ```
  </Accordion>
</AccordionGroup>

## Android

<AccordionGroup>
  <Accordion title="A coroutine dependency error occurs during the build process">
    #### Issue

    A coroutine dependency error occurs during the build process with the following message.

    ```html Text lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    java.lang.NoClassDefFoundError: kotlin/coroutines/AbstractCoroutineContextKey
        at java.base/java.lang.ClassLoader.defineClass1(Native Method)
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
      ...
    ```

    #### Cause

    If the kotlinx-coroutines-core library version is 1.3.5 or later, [the kotlin-stdlib library version must be at a certain level or later](https://github.com/Kotlin/kotlinx.coroutines/issues/1879).

    #### Solution

    Check whether the kotlin-stdlib library version is v.1.3.70 or later with the `gradlew dependencies` command. If the version is earlier than v.1.3.70, you need to update it.
  </Accordion>

  <Accordion title="Deeplink Opens generated by push notifications using the Braze SDK are not collected">
    #### Issue

    Deep link execution (Deeplink Open) events are not collected when using the Braze SDK for push notifications. Instead, the open event is collected.

    #### Cause

    The Airbridge Android SDK distinguishes the deep link execution event and the open event based on the dataString found in the activity's action and intent. When the app is launched through a push notification using the Braze SDK, `NotificationTrampolineActivity`is used. When an app is launched through a push notification using the Braze SDK, dataString cannot be verified from the action and intent of the `NotificationTrampolineActivity`. As a result, it is impossible to distinguish between the deep link execution event and the open event.

    #### Solution

    <CodeGroup>
      ```kotlin Kotlin lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import co.ab180.airbridge.flutter.AirbridgeFlutter
      ...
      AirbridgeFlutter.setLifecycleIntegration { activity ->
          return@setLifecycleIntegration activity
              .takeIf { it.javaClass.name == "com.braze.push.NotificationTrampolineActivity" }
              ?.run { intent?.extras?.getString("uri") }
      }
      ```

      ```java Java lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      import co.ab180.airbridge.flutter.AirbridgeFlutter;
      import co.ab180.airbridge.flutter.common.AirbridgeLifecycleIntegration;
      ...
      AirbridgeFlutter.setLifecycleIntegration(new AirbridgeLifecycleIntegration() {
          @Nullable
          @Override
          public String getDataString(@NonNull Activity activity) {
              if (
                  activity.getClass().getName().equals("com.braze.push.NotificationTrampolineActivity")
                  && activity.getIntent() != null
                  && activity.getIntent().getExtras() != null
              ) {
                  return activity.getIntent().getExtras().getString("uri");
              }
              return null;
          }
      });
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="The &#x22;Manifest merger failed&#x22; error occurs during the build process">
    #### Issue

    The "Manifest merger failed" error occurs during the build process.

    #### Cause

    The Airbridge SDK's `AndroidManifest.xml` includes rules to opt out of backing up the Shared Preferences data. The purpose of this rule is to avoid retaining the same Airbridge settings during the reinstallation of the app so that new installs or reinstalls can be detected accurately.

    Merging Airbridge SDK backup rules with your app backup rules can cause conflicts.

    #### Solution

    Below are the opt-out rules defined in the Airbridge SDK.

    <CodeGroup>
      ```xml Backup on Android 12 or later lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      <?xml version="1.0" encoding="utf-8"?>
      <data-extraction-rules>
          <cloud-backup>
              <exclude domain="sharedpref" path="airbridge-internal" />
              <exclude domain="sharedpref" path="airbridge-install" />
              <exclude domain="sharedpref" path="airbridge-user-info" />
              <exclude domain="sharedpref" path="airbridge-user-alias" />
              <exclude domain="sharedpref" path="airbridge-user-attributes" />
              <exclude domain="sharedpref" path="airbridge-device-alias" />
              <exclude domain="database" path="airbridge.db" />
          </cloud-backup>
          <device-transfer>
              <exclude domain="sharedpref" path="airbridge-internal" />
              <exclude domain="sharedpref" path="airbridge-install" />
              <exclude domain="sharedpref" path="airbridge-user-info" />
              <exclude domain="sharedpref" path="airbridge-user-alias" />
              <exclude domain="sharedpref" path="airbridge-user-attributes" />
              <exclude domain="sharedpref" path="airbridge-device-alias" />
              <exclude domain="database" path="airbridge.db" />
          </device-transfer>
      </data-extraction-rules>
      ```

      ```xml Backup on Android 11 and earlier lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      <?xml version="1.0" encoding="utf-8"?>
      <full-backup-content>
          <exclude domain="sharedpref" path="airbridge-internal" />
          <exclude domain="sharedpref" path="airbridge-install" />
          <exclude domain="sharedpref" path="airbridge-user-info" />
          <exclude domain="sharedpref" path="airbridge-user-alias" />
          <exclude domain="sharedpref" path="airbridge-user-attributes" />
          <exclude domain="sharedpref" path="airbridge-device-alias" />
          <exclude domain="database" path="airbridge.db" />
      </full-backup-content>
      ```
    </CodeGroup>

    ##### Fix conflict with fullBackupContent="string"

    Adding `android:fullBackupContent="string"` to the `AndroidManifest.xml` file may cause an error like the following.

    ```html Build Output lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    Manifest merger failed : Attribute application@fullBackupContent value=(string) from AndroidManifest.xml
    ```

    To fix this error,

    * add `xmlns:tools="http://schemas.android.com/tools"` to the `<manifest>` tag
    * add `tools:replace="android:fullBackupContent"` to the `<application>` tag

    in the `AndroidManifest.xml` file.

    ##### Fix conflict with dataExtractionRules="string resource"

    Adding `android:dataExtractionRules="string resource"` to the `AndroidManifest.xml` file may cause an error like the following.

    ```html Build Output lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    Manifest merger failed : Attribute application@dataExtractionRules value=(string resource) from AndroidManifest.xml

    ```

    To fix this error,

    * add `xmlns:tools="http://schemas.android.com/tools"` to the `<manifest>` tag
    * add `tools:replace="android:dataExtractionRules"` to the `<application>` tag

    in the `AndroidManifest.xml` file.

    ##### Fix conflict with allowBackup="false"

    Adding `android:allowBackup="false"` to the `AndroidManifest.xml` file may cause an error like the following.

    ```html Build Output lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    Manifest merger failed : Attribute application@allowBackup value=(false) from AndroidManifest.xml:32:9-36
    	is also present at [:airbridge] AndroidManifest.xml:27:9-35 value=(true).
    	Suggestion: add 'tools:replace="android:allowBackup"' to <application> element at AndroidManifest.xml:30:5-250:19 to override.
    ```

    To fix this error,

    * add `xmlns:tools="http://schemas.android.com/tools"` to the `<manifest>` tag
    * add `tools:replace="android:allowBackup"` to the `<application>` tag

    in the `AndroidManifest.xml` file.

    ##### If compileSdkVersion is lower than 31

    The `android:dataExtractionRules` has been added in API Level 31. Therefore, if the compileSdkVersion is lower than 31,  an error like the following may occur.

    ```html Build Output lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    AndroidManifest.xml: AAPT: error: attribute android:dataExtractionRules not found.
    ```

    To fix this error,

    * add `xmlns:tools="http://schemas.android.com/tools"` to the `<manifest>` tag
    * add `tools:remove="android:dataExtractionRules"` to the `<application>` tag

    in the `AndroidManifest.xml` file.

    For more guidance, refer to the articles below.

    * [Android Developers Guide](https://developer.android.com/identity/data/autobackup)
    * [Airbridge Developer Guide](https://airbridge.readme.io/page/auto-backup-%EC%A4%91%EB%B3%B5-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0-%EA%B0%80%EC%9D%B4%EB%93%9C)
  </Accordion>

  <Accordion title="Resolve Airbridge SDK backup rules merge conflict issue">
    #### Issue

    If an Airbridge SDK backup rule and a backup rule for a different third-party SDK (e.g., AppsFlyer SDK) overlap, you will see the build error below.

    ```html lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    Attribute application@fullBackupContent value=(@xml/appsflyer_backup_rules) from [com.appsflyer:af-android-sdk:6.6.1] AndroidManifest.xml:14:18-73
    is also present at [io.airbridge:sdk-android:2.14.0] AndroidManifest.xml:27:18-78 value=(@xml/airbridge_auto_backup_rules).
    Suggestion: add 'tools:replace="android:fullBackupContent"' to <application> element at AndroidManifest.xml:7:5-13:19 to override.
    ```

    #### Cause

    Overlapping of the Airbridge SDK backup rules and third-party SDK backup rules can cause build errors.

    #### Solution

    ##### `backup_rules.xml` setup

    1. Create a `android/app/src/main/res/xml` folder.
    2. Within the new xml folder, create a file (e.g. `custom_backup_rules.xml`).
    3. Add the data backup rules defined in the Airbridge SDK as follows.

    ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    <?xml version="1.0" encoding="utf-8"?>
    <full-backup-content>
        <!-- Airbridge Backup Rules -->
        <exclude domain="sharedpref" path="airbridge-internal" />
        <exclude domain="sharedpref" path="airbridge-install" />
        <exclude domain="sharedpref" path="airbridge-user-info" />
        <exclude domain="sharedpref" path="airbridge-user-alias" />
        <exclude domain="sharedpref" path="airbridge-user-attributes" />
        <exclude domain="sharedpref" path="airbridge-device-alias" />
        <exclude domain="database" path="airbridge.db" />
      
        <!-- Appsflyer Backup Rules -->
        <exclude domain="sharedpref" path="appsflyer-data"/>
    	
    	<!-- Your Custom Backup Rules -->
    </full-backup-content>
    ```

    ##### `data_extraction_rules.xml` setup

    <Info>
      **Note**

      The data\_extraction\_rules.xml setting is required for Airbridge Flutter SDK v4.1.5 and above.
    </Info>

    1. Within the new xml folder, create a file (e.g. `custom_data_extraction_rules.xml`).
    2. Add the data backup rules defined in the Airbridge SDK as follows.

    ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    <?xml version="1.0" encoding="utf-8"?>
    <data-extraction-rules>
        <cloud-backup>
            <!-- Airbridge Backup Rules -->
            <exclude domain="sharedpref" path="airbridge-internal" />
            <exclude domain="sharedpref" path="airbridge-install" />
            <exclude domain="sharedpref" path="airbridge-user-info" />
            <exclude domain="sharedpref" path="airbridge-user-alias" />
            <exclude domain="sharedpref" path="airbridge-user-attributes" />
            <exclude domain="sharedpref" path="airbridge-device-alias" />
            <exclude domain="database" path="airbridge.db" />

            <!-- Appsflyer Backup Rules -->
            <exclude domain="sharedpref" path="appsflyer-data"/>

    	    <!-- Your Custom Backup Rules -->
        </cloud-backup>
        <device-transfer>
            <!-- Airbridge Backup Rules -->
            <exclude domain="sharedpref" path="airbridge-internal" />
            <exclude domain="sharedpref" path="airbridge-install" />
            <exclude domain="sharedpref" path="airbridge-user-info" />
            <exclude domain="sharedpref" path="airbridge-user-alias" />
            <exclude domain="sharedpref" path="airbridge-user-attributes" />
            <exclude domain="sharedpref" path="airbridge-device-alias" />
            <exclude domain="database" path="airbridge.db" />

            <!-- Appsflyer Backup Rules -->
            <exclude domain="sharedpref" path="appsflyer-data"/>

    	    <!-- Your Custom Backup Rules -->
        </device-transfer>
    </data-extraction-rules>
    ```

    ##### `AndroidManifest.xml` setup

    ###### Airbridge Flutter SDK v4.1.5 or above

    ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    <manifest
        ...
        xmlns:tools="http://schemas.android.com/tools">

        <application
            ...
    		android:allowBackup="true"
    		android:fullBackupContent="@xml/custom_backup_rules"
            android:dataExtractionRules="@xml/custom_data_extraction_rules"
    		tools:replace="android:fullBackupContent,android:dataExtractionRules">
    ```

    ###### Airbridge Flutter SDK version earlier than v4.1.5

    ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    <manifest
        ...
        xmlns:tools="http://schemas.android.com/tools">

        <application
            ...
    		android:allowBackup="true"
    		android:fullBackupContent="@xml/custom_backup_rules"
    		tools:replace="android:fullBackupContent">
    ```
  </Accordion>

  <Accordion title="GAID is collected as 00000000-0000-0000-0000-000000000000">
    #### Issue

    GAID is being collected as 00000000-0000-0000-0000-000000000000 even though LAT (Limited Ad Tracking) is deactivated.

    #### Cause

    The AD\_ID permission has been excluded due to other third-party libraries.

    #### Solution

    Add AD\_ID permission.

    ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    <manifest ...>
      ...
      <uses-permission android:name="com.google.android.gms.permission.AD_ID" />
      ...
    </manifest>
    ```
  </Accordion>

  <Accordion title="Warnings or rejections related to 16KB page size occur when uploading to Google Play">
    ### **Issue**

    When uploading your app to Google Play Console, you may receive the following warning or rejection messages:

    * "Your app doesn't support 16 KB page size"
    * "16 KB page size compatibility required"
    * App upload is rejected or displayed in a warning state

    This is due to Google Play policy requirements that apps targeting Android 15 (API level 35) or higher must support 16KB page size.

    ### Cause

    To support 16 KB page sizes, the entire app (APK/AAB) must be packaged with 16 KB zipalign to pass Google Play policy.

    If the APK/AAB is not built with 16 KB zipalign:

    * You will receive warning or rejection messages when uploading to Google Play Console
    * Uploads will be completely blocked after November 1, 2025
    * The app may not work properly on 16KB page size devices in the future

    **Known Issue in the Airbridge SDK: PT\_GNU\_RELRO Alignment**

    The Airbridge SDK has supported 16 KB page sizes since v4.6. However, in versions built with NDK r21, the LOAD segments of the native libraries (`.so`) are aligned to the 16 KB boundary, but the `PT_GNU_RELRO` segment is not.

    * **App behavior is not affected.** The app runs normally on 16 KB page size devices.
    * However, Google Play Console may display a 16 KB page size warning when you upload your app.
    * Alignment check tools such as Android Studio lint, APK Analyzer, and `check_elf_alignment.sh` may also report this as a warning.

    This issue was resolved by upgrading the SDK build toolchain to NDK r27, and 16 KB page size support has been verified after the fix. Refer to the table below for the minimum version with 16 KB support and the recommended version for each platform.

    | Platform      | Minimum Version with 16 KB Support | Recommended Version (PT\_GNU\_RELRO issue fixed) |
    | ------------- | ---------------------------------- | ------------------------------------------------ |
    | Android       | v4.6                               | v4.9.4                                           |
    | React Native  | v4.6                               | v4.9.0                                           |
    | Cordova Ionic | v4.4.1                             | x (support planned)                              |
    | Flutter       | v4.6                               | v4.9.0                                           |
    | Expo          | v4.6                               | v4.9.0                                           |
    | Unity         | v4.6                               | v4.9.2                                           |
    | Unreal        | v4.6                               | v4.9.0                                           |

    ### **Solution**

    **Step 1: Check Airbridge SDK Version**

    Compare the Airbridge SDK version you are using against the table above.

    * **If you are using a version lower than the** **`Minimum Version with 16 KB Support`:**

      16 KB page sizes are not supported. Be sure to update.
    * **If you are using a version at or above the** **`Minimum Version with 16 KB Support`** **but below the** **`Recommended Version`:**

      The `PT_GNU_RELRO` alignment issue described above may cause Google Play Console to keep showing the warning. App behavior is not affected, but to resolve the warning, update to the `Recommended Version` or later.

    **Step 2: Check and Configure Android Gradle Plugin (AGP) Version**

    Check your project's current AGP version.

    If using AGP 8.5.1 or higher:

    * 16KB zipalign is automatically applied without any additional configuration.
    * Proceed directly to Step 3.

    If using AGP 8.5.0 or lower:

    * Option A: Upgrade AGP to 8.5.1 or higher
    * Option B: Keep current AGP version + Add configuration

      ```groovy lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
      android {
          ...
          packagingOptions {
              jniLibs {
                  useLegacyPackaging true
              }
          }
      }
      ```

    **Step 3: Rebuild and Verify the App**

    After changing the configuration, perform a clean build of your app.

    **Step 4: Verify 16KB zipalign Application**

    Verify that the built APK/AAB is properly 16KB zipaligned.
  </Accordion>

  <Accordion title="Tracking links open the app but don't navigate to the intended page, or the deeplink isn't delivered">
    **Problem**

    When the app is launched via an Airbridge tracking link (App Link / URI scheme), the following may occur:

    * The app opens to the home screen or a blank screen instead of the destination (scheme deeplink) set on the tracking link.
    * The scheme deeplink is not delivered to the deeplink listener (

      `Airbridge.setOnDeeplinkReceived`

      ).
    * The Deeplink Open event, or the destination delivery for a deferred deeplink, does not work.

    ##### Cause

    Starting from v3.7, Flutter improved its ability to handle deeplinks directly through the framework's Router API without an external plugin, and from Flutter v3.27 onward this default deeplink handler is enabled by default.

    The Airbridge SDK intercepts the incoming Airbridge deeplink at the native level (`AirbridgeFlutter.trackDeeplink(intent)`, called in `MainActivity`'s `onResume`/`onNewIntent`), converts it into the scheme deeplink set on the tracking link (`YOUR_SCHEME://...`), and then delivers it to the app.

    If Flutter's default deeplink handler is enabled, the Flutter engine intercepts the same URI first and routes it through the app's Router. Because the value delivered to the app is the original Airbridge deeplink (such as an HTTP App Link) rather than the scheme deeplink converted by the Airbridge SDK, the app's router cannot match the path, and the conflict also disrupts the Airbridge SDK's conversion and delivery flow.

    ##### Solution

    In `AndroidManifest.xml`, set the `flutter_deeplinking_enabled` metadata to `false` on the `<activity>` that handles deeplinks (typically `MainActivity`) to disable Flutter's default deeplink handler.

    ```xml lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    <activity
        android:name=".MainActivity"
        ...>
        <meta-data
            android:name="flutter_deeplinking_enabled"
            android:value="false" />
        ...
    </activity>
    ```

    After applying this setting, also verify that the Airbridge SDK's native deeplink integration (the `AirbridgeFlutter.trackDeeplink(intent)` call in `MainActivity`) has not been omitted.
  </Accordion>
</AccordionGroup>

<link rel="alternate" hrefLang="en" href="https://help.airbridge.io/en/developers/troubleshooting-flutter-sdk-v4" />

<link rel="alternate" hrefLang="ko" href="https://help.airbridge.io/ko/developers/troubleshooting-flutter-sdk-v4" />
