Closed sin2 closed 5 years ago
Hey @sin2,
Good digging. That setContentIntentIfPresent
routes an intent back to our BroadcastReceiver
, allowing it to log analytics before opening the deep link in the intent.
When we open deep links, we use a standard ACTION_VIEW
, however, it lives inside a stackbuilder that places the main activity on the background before navigating to the deep link URI. The code lives here: https://github.com/Appboy/android-sdk/blob/develop/android-sdk-ui/src/main/java/com/appboy/ui/actions/UriAction.java#L142
That's probably what's triggering your splash activity. You can use our back stack configurations settings added in 2.1.4 to change or disable our default stackbuilder behavior - https://github.com/Appboy/appboy-android-sdk/blob/master/CHANGELOG.md#214
Setting <bool name="com_appboy_push_deep_link_back_stack_activity_enabled">false</bool>
does not seem to work. Also looks like it is opening the correct activity.
Here is a partial log:
02-19 10:26:55.911 21720-21720/com.app.app D/Appboy v2.7.0 .com.appboy.AppboyFcmReceiver: Received broadcast message. Message: Intent { act=com.appboy.action.APPBOY_PUSH_CLICKED flg=0x10 cmp=com.app.app/com.appboy.AppboyFcmReceiver bqHint=4 VirtualScreenParam=Params{mDisplayId=-1, null, mFlags=0x00000000)} (has extras) }
02-19 10:26:55.911 21720-21720/com.app.app D/Appboy v2.7.0 .com.appboy.push.AppboyNotificationUtils: Sending notification opened broadcast
02-19 10:26:55.911 21720-22163/com.app.app D/Appboy v2.7.0 .com.appboy.Appboy: No campaign Id associated with this notification. Not logging push click to Appboy.
02-19 10:26:55.931 21720-21720/com.app.app D/Appboy v2.7.0 .com.appboy.configuration.CachedConfigurationProvider: Defaulting to using xml value for key: com_appboy_handle_push_deep_links_automatically and value: true
02-19 10:26:55.931 21720-21720/com.app.app D/Appboy v2.7.0 .com.appboy.push.AppboyNotificationUtils: Found a deep link app://friends
Use webview set to: false
02-19 10:26:55.941 21720-21720/com.app.app D/Appboy v2.7.0 .com.appboy.ui.actions.UriAction: Executing Uri action from channel PUSH: app://friends. UseWebView: false. Extras: Bundle[{source=Appboy, ab_use_webview=false, cid=null, uri=app://friends}]
02-19 10:26:55.941 21720-21720/com.app.app D/Appboy v2.7.0 .com.appboy.configuration.CachedConfigurationProvider: Defaulting to using xml value for key: com_appboy_push_deep_link_back_stack_activity_enabled and value: false
02-19 10:26:55.941 21720-21720/com.app.app D/Appboy v2.7.0 .com.appboy.ui.actions.UriAction: Not adding back stack activity while opening uri from push due to disabled configuration setting.
02-19 10:26:56.341 21720-22163/com.app.app D/Appboy v2.7.0 .bo.app.dr: No stored open session in storage.
02-19 10:26:56.341 21720-22163/com.app.app D/Appboy v2.7.0 .bo.app.ac: bo.app.ao fired: bo.app.ao@b8e680b
02-19 10:26:56.341 21720-22163/com.app.app D/Appboy v2.7.0 .bo.app.ac: Triggering bo.app.ao on 1 subscribers.
02-19 10:26:56.341 21720-22163/com.app.app D/Appboy v2.7.0 .bo.app.bn: New session created with ID: 39754c1a-3bb1-4b26-8922-516804548798
02-19 10:26:56.341 21720-21720/com.app.app D/Appboy v2.7.0 .com.appboy.ui.inappmessage.AppboyInAppMessageManager: registerInAppMessageManager called
02-19 10:26:56.341 21720-22163/com.app.app D/Appboy v2.7.0 .bo.app.ac: bo.app.aq fired: bo.app.aq@3c77994
Triggering bo.app.aq on 1 subscribers.
02-19 10:26:56.341 21720-22163/com.app.app D/Appboy v2.7.0 .bo.app.bl: Completed the openSession call. Starting or continuing session 39754c1a-3bb1-4b26-8922-516804548798
02-19 10:26:56.341 21720-22163/com.app.app D/Appboy v2.7.0 .bo.app.bm: Messaging session timeout: 21600, current diff: 26
Messaging session not started.
02-19 10:26:56.341 21720-22163/com.app.app V/Appboy v2.7.0 .bo.app.bl: Opened session with activity: host.exp.exponent.MainActivity
The activity is setup in the manifest like so:
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:theme="@style/Theme.Exponent.Splash"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<data android:scheme="app" />
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
@sin2 thanks for sharing - the logs show expected behavior and this manifest entry look good so the issue is likely on the React side. Could you share your getInitialUrl
/componentDidMount
implementation?
I have a listener in componentDidMount:
Linking.addEventListener('url', this.handleOpenURL);
handleOpenURL(event) {
openDeepLink(event.url);
}
Then in my splash component I handle the deep link after data is loaded:
const url = await Linking.getInitialURL();
if (url) {
openDeepLink(url);
}
ReactAppboy.getInitialURL(pushNotificationURL => {
if (pushNotificationURL) {
openDeepLink(pushNotificationURL);
}
});
Also I can successfully deep link using adb shell am start -W -a android.intent.action.VIEW -d "app://friends"
Which leads me to believe it is implemented correctly.
Hey @sin2, we were still not able to repro the behavior on our end. Our sample app's getInitialUrl
implementation worked whether the app was in the background or killed (see https://github.com/Appboy/appboy-react-sdk/blob/master/AppboyProject/AppboyProject.js#L66). Note that our sample calls getInitialURL
from directly within componentDidMount
- and that we don't use a splash activity. You might also see what behavior you get if you temporarily remove your splash activity.
Separately, could you provide us with either a sample app that reproduces the behavior or a minimum set of changes to our sample app that we can implement to repro the behavior? Short of that, a set of logs for each case with relevant lifecycle events in react (e.g. componentDidMount
, getInitialURL
+its url, _handleOpenUrl
) and Braze's verbose SDK logs would be helpful to understand what's going on.
@Bucimis I have created a sample expo detached project to reproduce the issue. https://github.com/sin2/expo-braze-test
@sin2 thanks for sending over the sample app, we were able to repro on our end as well. We've narrowed the issue to an interaction between the FLAG_ACTIVITY_NEW_TASK
and Linking.getInitialURL
on singleTask
apps - in short, our push intent doesn't have the flag (and doesn't work) and the adb
flag includes the flag (and works). The following is code you can add to MainActivity
's onCreate()
method to force Appboy to use FLAG_ACTIVITY_NEW_TASK
for push intents. We'll also explore adding FLAG_ACTIVITY_NEW_TASK
to our base SDK and let you know if that happens.
After adding the following we were able to get deep linking working in all situations:
// imports
import com.appboy.enums.Channel;
import com.appboy.IAppboyNavigator;
import com.appboy.ui.AppboyNavigator;
import com.appboy.ui.actions.NewsfeedAction;
import com.appboy.ui.actions.UriAction;
AppboyNavigator.setAppboyNavigator(new IAppboyNavigator() {
@Override
public void gotoNewsFeed(Context context, NewsfeedAction newsfeedAction) {
new AppboyNavigator().gotoNewsFeed(context, newsfeedAction);
}
@Override
public void gotoUri(Context context, UriAction uriAction) {
if (uriAction.getChannel().equals(Channel.PUSH)) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uriAction.getUri());
if (uriAction.getExtras() != null) {
intent.putExtras(uriAction.getExtras());
}
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
if (intent.resolveActivity(context.getPackageManager()) != null) {
context.startActivity(intent);
}
} else {
new AppboyNavigator().gotoUri(context, uriAction);
}
}
});
Let us know how this goes on your end. Thanks!
@Bucimis it's working great! Thanks your time and work, and we will keep an eye out for changes to the base SDK.
hey @Bucimis I had deep link not working when app was in foreground and when app was killed. The code you shared fixes the foreground case but when app is killed and I tap on a notification, deep link is not working. Any idea or hint where to look at?
@comanzanares i know the original ticket is android, but just want to sanity check - are you seeing this on android, ios or both?
Android
Hi @comanzanares thanks for following up.
Do you see the same behaviors when using the following adb
command to test your deep link in the closed state:
adb shell am start -W -a android.intent.action.VIEW -d "THE_DEEP_LINK" THE_PACKAGE_NAME
Our deep link code essentially runs the above command in code, so if the adb
command doesn't work, deep links will also not work.
Hey @Bucimis thanks for reaching out so fast, I get the exact same behaviour with adb :/
@comanzanares are you calling Linking.getInitialURL()
in your componentDidMount()
per https://github.com/Appboy/appboy-react-sdk/blob/5887ece50db2099bc4c54ff6a0d55e0a6f8842c2/AppboyProject/AppboyProject.js#L58? Also, make sure deep links are properly configured on the native side per https://developer.android.com/training/app-links/deep-linking.
yup @Bucimis the code was skipping the getInitialUrl for some conditions. thanks!
AppboyNavigator is now deprecated and the following should be used:
BrazeDeeplinkHandler.setBrazeDeeplinkHandler(object : IBrazeDeeplinkHandler {
override fun gotoNewsFeed(context: Context?, newsfeedAction: NewsfeedAction?) {
}
override fun gotoUri(context: Context?, uriAction: UriAction?) {
}
override fun getIntentFlags(intentFlagPurpose: IBrazeDeeplinkHandler.IntentFlagPurpose?): Int {
}
override fun createUriActionFromUrlString(
url: String?,
extras: Bundle?,
openInWebView: Boolean,
channel: Channel?
): UriAction {
}
override fun createUriActionFromUri(
uri: Uri?,
extras: Bundle?,
openInWebView: Boolean,
channel: Channel?
): UriAction {
}
})
I have a detached expo project set up with this SDK. I am having issues where opening an Android app from tapping a push notification with a deep link causes the android app to restart/open from the splash screen. This leads to the listener from not firing, and getInitialUrl() just returns the base deep link.
This only occurs when the application was backgrounded. From a killed state, when a push notification is opened the application starts and uses getInitialUrl(). It deep links appropriately in this case.
The project was configured according to the Braze docs and mainActivity launchmode is set to singleTask.
Seems like the issue is specifically caused by the intent set for the notification when there is a deep link.
AppboyNotificationUtils.setContentIntentIfPresent(context, notificationBuilder, notificationExtras);
I was able to simply deep link using:
Intent pushActionIntent = (new Intent(Intent.ACTION_VIEW, Uri.parse("app://friends"))).setClass(context, MainActivity.class);
However, this would bypass the default AppboyFcmReceiver and the logic contained there.