firebase / firebase-android-sdk

Firebase Android SDK
https://firebase.google.com
Apache License 2.0
2.24k stars 568 forks source link

159135253: Trigger FirebaseInAppMessagingClickListener. messageClicked when action is empty #1603

Open KonradSzewczuk opened 4 years ago

KonradSzewczuk commented 4 years ago

What feature would you like to see?

Invoke FirebaseInAppMessagingClickListener.messageClicked for use case when you don't want to trigger browser intent and you are interested only to handle other data (such as key-value map defined in the campaign)

As a user, I don't want to trigger any URL specific browser intent when i click my In App Message popup. I want to trigger below code without any side effects:

inAppMessaging.addClickListener { inAppMessage, action ->
      // invoke only code inside
          val data = inAppMessage.data // I am only interested in that data, don't want to trigger any browser intent
      }

Unfortunately, this listener is not being invoked when the defined action is empty. You must define the action with proper URL to be able to trigger this listener when popup is clicked.

Can we trigger such listener always when the popup is being clicked, even when the defined action for campaign is empty?

google-oss-bot commented 4 years ago

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

JasonAHeron commented 4 years ago

Hey @KonradSzewczuk, this is an interesting feature request. Right now when a user does not provide a valid click action we treat clicks as dismiss.

So what you're imagining is if an action is not set then when a FIAM is clicked we call the developer registered callback for click before dismissing it?

ashwinraghav commented 4 years ago

Thanks for the feature request. If you are looking for programmatic invocation of remote functions defined in your app, consider using FirebaseMessaging. You could send a message to your app from your app's backend or from the Notifications tab in the Firebase console. Upon receiving the message, your app can parse it and invoke any functions that you would like.

KonradSzewczuk commented 4 years ago

@JasonAHeron I can confirm that your description is something that I am looking for.

In addition, my use case is to trigger an InAppMessaging popup and after click on it change the Fragment in my activity without any current activity refresh. To achieve that I think I must not trigger any deeplink related browser intent. The easiest way would be to handle such scenario in the FirebaseInAppMessagingClickListener. messageClicked as I proposed (without any side effects) I don't see any possible reason to use FirebaseMessaging in that case as @ashwinraghav proposed.

@ashwinraghav @JasonAHeron Can we reopen this feature request?

ashwinraghav commented 4 years ago

Hey @KonradSzewczuk, Closed the ticket unintentionally. Sry bout that. Also, I may have misunderstood what you are reporting. Thanks for clarifying. @JasonAHeron seems like a change that is non breaking IMO. Seems safe to have this roll out just as a minor version ? Also worth checking what the behavior on iOS is.

PiotrPrus commented 4 years ago

The feature that we are talking about is a dismissal event. I have checked the documentation for iOS and in the CardActionFiamDisplay there is a messageDismissed listener: https://firebase.google.com/docs/in-app-messaging/modify-message-behavior?platform=ios#implement_a_displaydelegate_to_handle_card_interactions As far I as understand, the same functionality on android would resolve the issue. Why these two even do not share the same functionalities? :(

8kt8 commented 4 years ago

I am straggling with the same problem. I try to put my custom url like service://book and open proper book screen in my app after button click action. Now it is impossible, app crash: No Activity found to handle Intent { act=android.intent.action.VIEW dat=service://book (has extras) }
I my honest opinion is basic functionality to do something in the application after click button on In-AppMessage, without triggering any intent to the browser.
So +1 from my site for this feature request. Any suggestions for a workaround? I want dismiss the in-app message and change fragment(I need information in url which fragment should be open).

JasonAHeron commented 4 years ago

Hey folks, thanks for bringing this back to my attention. I'm going to prioritize this this week and hopefully have a fix in the next release.

JasonAHeron commented 4 years ago

Okay so after reading through this issue again it appears there are actually three different requests here all wrapped up in one issue.

  1. @KonradSzewczuk wants to know if it would be possible to trigger the clicked listener rather than just a dismiss if the action url is not provided

  2. @PiotrPrus is asking for a dismiss developer callback

  3. @8kt8 is asking about handling cases where the developer has specified a URL action but does not want it handled by the browser.

Do I have all these requests correct?

8kt8 commented 4 years ago

Hi @JasonAHeron thanks for the quick response. Firebase InAppMessaging should not send Intent with custom scheme of data. Now I am trying to set button action like myAppId://sceenA, myAppId://sceenB, myAppId://sceenC. After trigger action by the user, I want only to change a screen inside the app. Now my app crashing: No Activity found to handle Intent { act=android.intent.action.VIEW dat=myAppId://sceenA (has extras) } FirebaseInAppMessagingClickListener should provide the option to disable the sending of intent or give a possibility to override this default behavior. In my case sending Intent is not needed. The same problem is when I want to open the Uri inside my app in WebView instead of the external browser.

JasonAHeron commented 4 years ago

@8kt8 so my understanding is this could be supported if we call the click handler when a button is clicked with an empty action url. Then you could populate your custom data using the custom data bundles field in the campaign.

This would solve what both you and @KonradSzewczuk are asking for

8kt8 commented 4 years ago

@JasonAHeron Your proposal almost solves my problems. You mention about empty action url, what in case with opening url action in WebView in application instead of opening url in external browser?

KonradSzewczuk commented 4 years ago

Okay so after reading through this issue again it appears there are actually three different requests here all wrapped up in one issue.

  1. @KonradSzewczuk wants to know if it would be possible to trigger the clicked listener rather than just a dismiss if the action url is not provided
  2. @PiotrPrus is asking for a dismiss developer callback
  3. @8kt8 is asking about handling cases where the developer has specified a URL action but does not want it handled by the browser.

Do I have all these requests correct?

@JasonAHeron I think clickListener should always be invoked when we click on popup. The problem is it should not be somehow connected with specifying obligatory browser intent action in the console and handling it. This will cover the usecase when I am only interested in the key-value data defined in the console and for example I want to change Fragment in my app after the popup is being clicked. So I will not be forced to trigger the browser intent. Having a dismiss click listener is something different, I found it also useful but it is not connected with my story. So it would be great if both those features will be added

JasonAHeron commented 4 years ago

@KonradSzewczuk Yeah makes sense, I'm going to bring this request to the team and make sure we can be consistent with it across iOS and Android and our docs but it does make sense and I'm going to push to make it happen.

@8kt8 my understanding is if you want to handle a click in your app via your own mechanism then you can do that (assuming the click handler is always called) by just adding whatever data you want into the data bundle and then handling that however you want in your click handler. This would work for launching your own web view instead of the browser

To summarize I think we have two good feature requests here

  1. Always call the click listener even when there is no action url
  2. Add a dismiss listener to be consistent with iOS and better support developer interactivity
8kt8 commented 4 years ago

@JasonAHeron Yes, I can put my custom data to Bundle, but there is a difference between iOS and Android. On iOS is possible to add custom button action like appId://screenA, handle custom on click listener, iOS doesn't trigger an external browser. On Android in the same scenario system send an intent with url, which causes crashes for custom url scheme if the proper intent filter is not added to app manifest(Maybe you should catch NoActivityException and not crash the app). The best solution would be to have the same behavior on Android.

8kt8 commented 4 years ago

Please consider a case with more than one button on InAppMessaging Dialog. Now the only way to recognize which button was clicked is to compare action urls. In my opinion, when the developer define custom on click handler, default behavior with sending url intent should be overridden.

JasonAHeron commented 4 years ago

Okay so this is a request for something like "Prevent Default" on click listeners. Makes sense. I'll bundle it into the proposal for click behavior changes

JasonAHeron commented 4 years ago

The above change should improve a few things 1) Add a dismiss callback to be consistent with iOS 2) Graceful handling for launching a URI intent with the user has no browser installed 3) Now if a developer registers a click callback in the SDK then they will always get a chance to react to clicks even if that click does not have a URL.

shaozl commented 3 years ago

Hi @JasonAHeron @8kt8 , I have the same issue with @8kt8 , in my app , we receive dynamic URI through In-app messaging's FirebaseInAppMessagingClickListener. messageClicked() , we decided to analysis the URI scheme://hosts?querymaps, get the queryMaps then do some jobs. Unfortunately, our app crashed with 'No Activity found to handle Intent { act=android.intent.action.VIEW ', after reading the source of In-app messaging i found the Intent you guys 'hardcode' there, an intent was send with our customized URI, but no activites matches it, crashed! So from my site

  1. We passing data through the URI , maybe with dynamic scheme, could you guys help to remove that Hardcode Intent , just leave the ClickListener for the developers , many thx
  2. In our app we send in-app messaging to let our customer know ,if there is some big events, when the user clicks on the Message , they will navigate to a specific page. If you have any concerns or you prefer the keep the current solution of Android SDK, a better way is providing more types than Uri, that will improve developers experience, thx

Hope you guys can help to solve that issue(maybe not issue, lol), my boss told me if the issue still exists in next release , i gonna be fired!!! Looking forward to your reply ~~

tvietinghoff commented 3 years ago

Hi @JasonAHeron, thank you for the improved handling regarding calling click listeners with empty actionUrls. However, the Firebase console does not let me specify an empty actionUrl for the Modal message layout, so this work-around is not helping my case.

I think the more universal approach would be a "prevent default" option for all listeners. But if the console could be modified to allow the empty URL be handled as dismiss just like with the Card layout, it would be sufficient for these cases for now and would not require an API change.

image