RodrigoSMarques / flutter_branch_sdk

Flutter Plugin for create deep link using Branch Metrics SDK. This plugin provides a cross-platform (iOS, Android, Web).
https://branch.io
MIT License
101 stars 91 forks source link

Android cannot get the opening link (onInitFinished called after clicking on deep link two times) #325

Closed vasa137 closed 6 months ago

vasa137 commented 6 months ago

Describe the bug Using new version 8.0.0, onInitFinished is not called when application is opened. It doesn't make any difference if it's opened by clicking on deep link or opened via launcher icon.

To Reproduce Steps to reproduce the behavior:

  1. Open the app using deep link
  2. listSession will not return clicked link, there will be no events
  3. On the native Android side "onInitFinished" log is not printed, just "onListen"

Expected behavior ListSession should return opening deep link or "null" if app is opened using launcher icon.

Smartphone (Please complete the following information. remove session if not platform):

Additional context When I click on deep link again, onInitFinished is called and deep link is received in listSession stream - so just the first link is always missed :(

RodrigoSMarques commented 6 months ago

@vasa137

Create a file called branch.json, with the following content:

{
   "deferInitForPluginRuntime": true
}

Place this file in the path:

android/src/main/assets/branch.json

Retake the test.

RodrigoSMarques commented 6 months ago

Are You calling: await FlutterBranchSdk.init(); ?

vasa137 commented 6 months ago

Thanks for the fast reply - I cannot see this "deferInitForPluginRuntime" int Readme, should I still call - await FlutterBranchSdk.init(); or not after creating this file?

RodrigoSMarques commented 6 months ago

You shouldn't create this file as it is included in the SDK. That's why there are no instructions about it in README.MD

I did several tests, but it may be that in your project for some reason at build time, this file was deleted, that's why I asked you to create it.

Yes. You must still call the await function FlutterBranchSdk.init(); at main.

If not called, onInitFinished will never be executed.

RodrigoSMarques commented 6 months ago

Only useTestKey has been deprecated

vasa137 commented 6 months ago

I understand, I added it manually now - and I await FlutterBranchSdk.init(); in main - but I have still the same issue - do you have any idea how to check is this file loaded properly. All other things are working well - just first link is missed.

vasa137 commented 6 months ago

Logs:

D/FlutterBranchSDK( 8234): triggered onActivityPaused: rs.operi.app.MainActivity D/FlutterBranchSDK( 8234): triggered onActivityStopped: rs.operi.app.MainActivity D/FlutterBranchSDK( 8456): triggered onAttachedToEngine D/FlutterBranchSDK( 8456): triggered setupChannels
D/FlutterBranchSDK( 8456): SDK Init
D/FlutterBranchSDK( 8456): triggered onAttachedToActivity D/FlutterBranchSDK( 8456): triggered setActivity
D/FlutterBranchSDK( 8456): triggered onActivityResumed: rs.operi.app.MainActivity D/FlutterBranchSDK( 8456): triggered setupBranch D/FlutterBranchSDK( 8456): notifyNativeToInit() D/FlutterBranchSDK( 8456): triggered onListen

vasa137 commented 6 months ago

Also, after tapping deep link a lot of times - I get this thing logged again Branch SDK logged this

D/FlutterBranchSDK( 3719): BranchReferralInitListener - params: {"+non_branch_link":"dev-operi-app://open?link_click_id=1304070486333205728","+clicked_branch_link":false,"+is_first_session":false}

It's from this issue #308

So looks like I have serious problems with the library on my phone/project

RodrigoSMarques commented 6 months ago

@vasa137

It's very weird. Looking at your log, the behavior is correct. I shouldn't be missing the link.

I made a change to the code.

Update pubspec.yaml, as in the example below:

#flutter_branch_sdk:
flutter_branch_sdk:
     git:
       url: https://github.com/RodrigoSMarques/flutter_branch_sdk.git
       ref: dev
vasa137 commented 6 months ago

Still the same - I tried now on different device - Google Pixel - so nothing changes.

On previous versions of your lib I forked your repo and fixed this issue - but I am not so good in Java - so I made everything dirty (you can disregard part for "intercom"), can you please take a look at this commit and see what can be the problem - since with this commit it was capturing the initial link - https://github.com/operi-rs/flutter_branch_sdk/commit/68de901c63d17b698ba25c42b9521ac4a8615c1a

But I think startActivity was the solution there in setup method. Anyways I dont want to use my fork since I made it by guess, making everything confusing..

vasa137 commented 6 months ago

The only difference in ny project is that besides MainActivity, I have one more FlutterFragmentActivity defined for support chat (intercom_flutter) plugin, but it should not make any sense, because your plugin attached to MainActivity (see logs)

RodrigoSMarques commented 6 months ago

The only difference in ny project is that besides MainActivity, I have one more FlutterFragmentActivity defined for support chat (intercom_flutter) plugin, but it should not make any sense, because your plugin attached to MainActivity (see logs)

Does your MainActivity inherit from FlutterActivity or FlutterFragmentActivity?

RodrigoSMarques commented 6 months ago

If it's FlutterFragmentActivity, maybe I forgot to adjust something.

vasa137 commented 6 months ago

FlutterFragmentActivity - I needed to do that brcause of the intercom_flutter plugin

Sorry for the previous message - I mixed up something in my mind, so this is the only activity class I have, and intercom_flutter is creating another activity when I launch live chat support - but all these tests I've performed were unrelated to this (I was not opening support chat).

So you have full context now. The fork commit I provided in the last message I did for 2 different reasons:

  1. Initial link cannot be captured
  2. When other activity is opened (live chat) app was restarting infinitely, so I just tried to add some random lines with intent flags to stop this thing..

I would be very grateful if you can provide an official fix

package rs.operi.app;

import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant

class MainActivity: FlutterFragmentActivity () {
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine);

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "flavor").setMethodCallHandler {
            call, result -> result.success(BuildConfig.FLAVOR)
        }
    }
}
RodrigoSMarques commented 6 months ago

FlutterFragmentActivity - I needed to do that brcause of the intercom_flutter plugin

Sorry for the previous message - I mixed up something in my mind, so this is the only activity class I have, and intercom_flutter is creating another activity when I launch live chat support - but all these tests I've performed were unrelated to this (I was not opening support chat).

So you have full context now. The fork commit I provided in the last message I did for 2 different reasons:

  1. Initial link cannot be captured
  2. When other activity is opened (live chat) app was restarting infinitely, so I just tried to add some random lines with intent flags to stop this thing..

I would be very grateful if you can provide an official fix

package rs.operi.app;

import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant

class MainActivity: FlutterFragmentActivity () {
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine);

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "flavor").setMethodCallHandler {
            call, result -> result.success(BuildConfig.FLAVOR)
        }
    }
}

I already know what the problem is. I will release a new version later.

RodrigoSMarques commented 6 months ago

The infinite loop will also be fixed in this version

vasa137 commented 6 months ago

Amazing! You are the man!

RodrigoSMarques commented 6 months ago

@vasa137

Version 8.0.1 available

vasa137 commented 6 months ago

Hey, thanks for releasing. Looks like onInitFinished is called now, but since I've disabled tracking, I've got this log:

BranchReferralInitListener - error: Trouble initializing Branch. Tracking is disabled. Requested operation cannot be completed when tracking is disabled

I just want to use deep linking feature from Branch, without tracking.

Additionally, when I wanted to test with tracking enabled by calling this method without disableTracking parameter set (default value is "false")

await FlutterBranchSdk.init();

I got the same message - BranchReferralInitListener - error: Trouble initializing Branch. Tracking is disabled. Requested operation cannot be completed when tracking is disabled

So two things:

When I deleted the app - and cleaned the project - I was able to set trackingDisabled = false again - and deep links are working perfect!

vasa137 commented 6 months ago

Also reporting here some minor thing - which is not breaking anything basically - but it is in the console output when using "Hot Restart" Flutter feature:

W/System.err(24038): java.lang.IllegalStateException: Reply already submitted W/System.err(24038): at io.flutter.embedding.engine.dart.DartMessenger$Reply.reply(DartMessenger.java:431) W/System.err(24038): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.success(MethodChannel.java:272) W/System.err(24038): at br.com.rsmarques.flutter_branch_sdk.MethodResultWrapper$1.run(MethodResultWrapper.java:25) W/System.err(24038): at android.os.Handler.handleCallback(Handler.java:958) W/System.err(24038): at android.os.Handler.dispatchMessage(Handler.java:99) W/System.err(24038): at android.os.Looper.loopOnce(Looper.java:230) W/System.err(24038): at android.os.Looper.loop(Looper.java:319) W/System.err(24038): at android.app.ActivityThread.main(ActivityThread.java:8893) W/System.err(24038): at java.lang.reflect.Method.invoke(Native Method) W/System.err(24038): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608) W/System.err(24038): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)

This is not important at all - but you should be informed

RodrigoSMarques commented 6 months ago

Hey, thanks for releasing. Looks like onInitFinished is called now, but since I've disabled tracking, I've got this log:

BranchReferralInitListener - error: Trouble initializing Branch. Tracking is disabled. Requested operation cannot be completed when tracking is disabled

I just want to use deep linking feature from Branch, without tracking.

Additionally, when I wanted to test with tracking enabled by calling this method without disableTracking parameter set (default value is "false")

await FlutterBranchSdk.init();

I got the same message - BranchReferralInitListener - error: Trouble initializing Branch. Tracking is disabled. Requested operation cannot be completed when tracking is disabled

So two things:

  • Deep link handling should be available without tracking enabled
  • When I disabled tracking by calling await FlutterBranchSdk.init(disableTracking: true); - I couldn't re-enable it with await FlutterBranchSdk.init(); - I always get the same log "Trouble to..". I am not using "Hot restart" or something like that.

When I deleted the app - and cleaned the project - I was able to set trackingDisabled = false again - and deep links are working perfect!

In the plugin I only treated the case of disableTracking being equal to true, as I imagined that this would be per session.

But everything indicates that the native SDK stores some preference to know whether the app should be launched with tracking or not.

Once you have disabled tracking, you need to explicitly enable it with FlutterBranchSdk.disableTracking(false);

I will evaluate, so that in init I can change it to true or I do it at each startup.

RodrigoSMarques commented 6 months ago

Also reporting here some minor thing - which is not breaking anything basically - but it is in the console output when using "Hot Restart" Flutter feature:

W/System.err(24038): java.lang.IllegalStateException: Reply already submitted W/System.err(24038): at io.flutter.embedding.engine.dart.DartMessenger$Reply.reply(DartMessenger.java:431) W/System.err(24038): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.success(MethodChannel.java:272) W/System.err(24038): at br.com.rsmarques.flutter_branch_sdk.MethodResultWrapper$1.run(MethodResultWrapper.java:25) W/System.err(24038): at android.os.Handler.handleCallback(Handler.java:958) W/System.err(24038): at android.os.Handler.dispatchMessage(Handler.java:99) W/System.err(24038): at android.os.Looper.loopOnce(Looper.java:230) W/System.err(24038): at android.os.Looper.loop(Looper.java:319) W/System.err(24038): at android.app.ActivityThread.main(ActivityThread.java:8893) W/System.err(24038): at java.lang.reflect.Method.invoke(Native Method) W/System.err(24038): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608) W/System.err(24038): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)

This is not important at all - but you should be informed

Hot Restart

Hot Restart should not kill the native code that is running, initializing it again.

Unfortunately, in Hot Restart, this cannot be resolved.

vasa137 commented 6 months ago

Hey, thanks for releasing. Looks like onInitFinished is called now, but since I've disabled tracking, I've got this log: BranchReferralInitListener - error: Trouble initializing Branch. Tracking is disabled. Requested operation cannot be completed when tracking is disabled I just want to use deep linking feature from Branch, without tracking. Additionally, when I wanted to test with tracking enabled by calling this method without disableTracking parameter set (default value is "false") await FlutterBranchSdk.init(); I got the same message - BranchReferralInitListener - error: Trouble initializing Branch. Tracking is disabled. Requested operation cannot be completed when tracking is disabled So two things:

  • Deep link handling should be available without tracking enabled
  • When I disabled tracking by calling await FlutterBranchSdk.init(disableTracking: true); - I couldn't re-enable it with await FlutterBranchSdk.init(); - I always get the same log "Trouble to..". I am not using "Hot restart" or something like that.

When I deleted the app - and cleaned the project - I was able to set trackingDisabled = false again - and deep links are working perfect!

In the plugin I only treated the case of disableTracking being equal to true, as I imagined that this would be per session.

But everything indicates that the native SDK stores some preference to know whether the app should be launched with tracking or not.

Once you have disabled tracking, you need to explicitly enable it with FlutterBranchSdk.disableTracking(false);

I will evaluate, so that in init I can change it to true or I do it at each startup.

Yeah, but you cannot use plugin when Tracking is disabled. So plugin crashes always with error - "BranchReferralInitListener - error: Trouble initializing Branch. Tracking is disabled. Requested operation cannot be completed when tracking is disabled"

I don't want to use tracking at all - but it shouldn't prevent me to have this plugin for deep link purposes - this is the main problem. I have just one initialization line - await FlutterBranchSdk.init(disableTracking: true); - and plugin is crashing.

Regarding trackingDisabled: false - I just mentioned that as an example - but I don't plan to use the plugin for Tracking - just for deep linking.

RodrigoSMarques commented 6 months ago

This message is returned by the native SDK.

I have no control over the plugin code in relation to this.

In this case, I suggest opening an issue in the Branch SDK Android repository.

RodrigoSMarques commented 6 months ago

Check the links:

https://github.com/BranchMetrics/ios-branch-deep-linking-attribution/issues/1029

https://help.branch.io/developers-hub/docs/honoring-opt-out-of-processing-requests

https://help.branch.io/developers-hub/docs/android-full-reference

public void disableTracking(boolean disableTracking)

Method to change the tracking state. If disabled, the Branch Android SDK will not track any user data or state. The SDK will not send any network calls, except for deep linking, when tracking is disabled.

vasa137 commented 6 months ago

I saw a lot of similar issues reported - but they've never took any action.

So looks like, I need to initialize the plugin with tracking enabled and then to explicitly disable it in the next line of code.

Because otherwise initialization will fail.

vasa137 commented 6 months ago

Thanks a lot for the update - we can close this issue!

RodrigoSMarques commented 6 months ago

I identified that the plugin in the init method will call disableTracking(true) if the value is true.

if the value is false the plugin does not call disableTracking(false).

I will adjust this in a new version.