Deferred deep links in flutter, not working in sandbox/production from debug build.
I have tried building to actual device on iOS and Android and can't get the call back to fire.
I have followed the steps: https://dev.adjust.com/en/sdk/ios/features/deep-links/testing/#test-deferred-deep-linking
I have also tried toggling on Enable probabilistic modeling reattribution
Is there something I am missing? Is there a way to test this with debug builds ? Or does this need to be on a production release build to actually work.
Unfortunately, i think adjust doesn't handled this in flutter, I had the same issue in both (android - ios), the issue is solved when I use a channel from the native code to flutter code, the issue is solved like that:
- add flutter sdk.
- add android and IOS SDKs. android in app/build.gradle, IOS in pod file.
- create channel between native code and flutter code.
Deep Linking Integration with Adjust SDK (Android & iOS)
This integration allows deep links to be received on both Android and iOS, processed by the Adjust SDK, and passed to Flutter via a MethodChannel.
Android
Channel & Engine
private static final String CHANNEL = "Any";
private static FlutterEngine globalFlutterEngine; // Assign this engine somewhere accessible
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
Uri data = intent.getData();
if (data != null) {
Adjust.processDeeplink(new AdjustDeeplink(data), this);
sendDeeplinkToFlutter(data.toString());
}
}
@Override
protected void onNewIntent(@NonNull Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
// TO BACK TO VIEW
if (intent.getScheme() != null && intent.getScheme().equals(ShopperResultUrl)) {
success("success");
}
Uri data = intent.getData();
if (data != null) {
Adjust.processDeeplink(new AdjustDeeplink(data), this);
sendDeeplinkToFlutter(data.toString());
}
}
private void sendDeeplinkToFlutter(String uri) {
if (globalFlutterEngine != null) {
new MethodChannel(globalFlutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.invokeMethod("onDeepLinkReceived", uri);
}
}
### IOS
var batteryChannel: FlutterMethodChannel?// assign this
var pendingDeepLinkURL: String?// assign this
// MARK: - Universal Links
override func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL {
handleIncomingDeepLink(url)
}
return true
}
override func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
handler = true
handleIncomingDeepLink(url)
return handler
}
// MARK: - Deep Link Handling Helper
private func handleIncomingDeepLink(_ url: URL) {
if let deeplink = ADJDeeplink(deeplink: url) {
Adjust.processDeeplink(deeplink)
}
if let channel = batteryChannel {
channel.invokeMethod("onDeepLinkReceived", arguments: url.absoluteString)
} else {
pendingDeepLinkURL = url.absoluteString
}
print("[DeepLink] Received: \(url.absoluteString)")
}
@amrel7afy I tried your way, it gives me error:
Failed to build iOS app
Could not build the precompiled application for the device.
Swift Compiler Error (Xcode): Cannot find 'handler' in scope
/Users/eqrakhattak/carbee/carbee-flutter-user/ios/Runner/AppDelegate.swift:84:16
Swift Compiler Error (Xcode): Cannot find 'handler' in scope
/Users/eqrakhattak/carbee/carbee-flutter-user/ios/Runner/AppDelegate.swift:86:15
Removing handler and returning true didn't work too.
I'm also experiencing this issue. The deep link callback isn't triggered, even though the Adjust SDK logs indicate that the link is received. The deferredDeeplinkCallback is set, but the callback doesn't fire consistently. Any updates or workarounds would be appreciated.
try setting
adjustConfig.isDeferredDeeplinkOpeningEnabled = false;
for me now the callback is working. tested with release build on both android and ios. on ios callback called after user allow the AppTrackingAuthorization permission after receiving the popup
adjust version:
adjust_sdk: ^5.1.1
@amrel7afy @eqrakhattak @jayadevpanthaplavil did you get any solution. please update here
@Gagan5278 Ours was working in our release build, we ended up testing using Sentry (for logging). Then you can follow the process opening the deferred deeplink (opens app store), close the app store. Then going to testflight and downloading from there, and check logs to see where it is failing.
@Gagan5278 No, I didn’t get a proper solution. Even after adding adjustConfig.isDeferredDeeplinkOpeningEnabled = false;, the callback from the SDK didn’t work for me.
Instead, I integrated app_links along with the adjust sdk to extract the params — that’s the approach that worked.
@jayadevpanthaplavil thanks, could you please explain in detail with steps you followed for testing as well.
Hey guys, sorry for the delay on this one from our end.
@ToddZeil Your original question was about the deferred deep linking and testing to see whether that mechanism works. Did you manage to get that to work?
@amrel7afy I am not sure whether your answer is directly tied to what @ToddZeil asked initially, but it might be (depends). From what I can see in your code snippets, you're hooking into native activity / app delegate in order to send deep link that has opened an app from native layer to Flutter.
When app is already installed and when you tap on a deep link, then the app will be opened and these places are the places where the deep links can be found. In this case (direct deep linking - opening an already existing app), our SDK will not handle this what your code snippets are doing for you. We didn't bake this mechanism into our SDK because there are already Flutter plugins / instructions out there that the community is using and which are handling this for you (https://docs.flutter.dev/ui/navigation/deep-linking, https://pub.dev/packages/app_links, etc). So yes, in this case, Adjust SDK will not provide you with a deep link that has opened your already installed app - you'll need to capture it on your own and pass it later to processDeeplink / processAndResolveDeeplink method.
However, historically this path can also be triggered in case of deferred deep linking. When the Adjust SDK receives the deferred deep link from our backend, by default we will try to "open" the deep link, if not stated otherwise. Opening the deep link pretty much means that natively we'll try to launch the intent that will open a native activity that's handling the scheme from the deeplink / trigger on our own the openURL method from the app delegate. In case you would not like the Adjust SDK to "open" the deep link by default, you need to set this filed to false when configuring the SDK.
But when it comes to deferred deep linking, in case you are interested in the content of the deep link itself, that's what the deferred deep link callback is for and, once the SDK receives deferred deep link, it will send the content of that deep link directly to that callback so that you can obtain it in your Dart code.
If the callback is not getting triggered, that's because for some reason, the install that you have just made was not attributed to the click on some Adjust link that you have made prior to making that install.
What @ToddZeil said:
I have also tried toggling on Enable probabilistic modeling reattribution
Is what should be done for the specific link you're running this test with in the dashboard (still makes me wonder does it work for you at the end or not).
Other than that, one needs to follow the steps from the link that Todd posted. tl;dr:
- Make sure to have probabilistic modeling enabled for the link you're gonna be running this test with.
- Uninstall the app from your test device.
- Forget your device from the testing console.
- Tap on the properly formatted and set up link from somewhere (some app, from some web page, etc - don't paste the link in the browser URL bar, that won't work).
- After tapping, you'll be redirected to App / Play Store, ignore that.
- Run the debug build of your app on your test device to track an install and hopefully see that install attributed to that click on the Adjust link you just made.
Deferred deep link should arrive to the SDK and, in case you have implemented deferred deep link callback, the callback should get triggered. In case it's not, there's probably some issue down this testing road. If you are still facing the issues, it would be helpful if you could run this test as described above, have SDK set to sandbox mode + verbose log level, pick up all the Adjust SDK native (not Dart) logs from this run (in Android, LogCat tag is Adjust, in iOS all the logs are prefixed with [Adjust]) and send them over so that we can see what's up during that run. It would also be helpful to know what is the test link you're using. In case you think some of the parameters from the logs are sensitive, feel free to omit them. If you're still not comfortable with sending those logs here, you can send them to my email (you'll find it on my profile page).
- Open https://suite.adjust.com/apps
- Enter the
Testing consoleof the corresponding App - Search your device
- Uninstall app from device
- Click deep link
- Install the app manually
deferredDeeplinkCallbackcalls back a url
I resolved this issue by performing the above steps.