Closed hanniedong closed 2 years ago
Have you tried following the manual setup instructions here: https://developers.intercom.com/installing-intercom/docs/ios-push-notifications
Namely setting the IntercomAutoIntegratePushNotifications
to NO
in Info.plist
and then seeing if the didReceiveRemoteNotification
is triggered when you tap on the message?
If that is called you should be able to grab the url from userInfo
object parameter of that function.
After that you can either call openUrl
with that url to pass your deep link to that function:
NSString *deepLink = "extracted from userInfo";
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:deepLink]] options:nil completionHandler:nil]
or just pass it to your deep link handler directly
Also having the same issue on iOS, I have deep links working everywhere else just not from Intercom Notifications, feels like library issue when it works on android but not on iOS.
@johnryan you might be on to something but could you detail it a little more? 🤔 How would you extract the deep link URL from userInfo and pass it to for example RCTLinkingManager
?
@du5rte You probably need to be on the latest Intercom version - but what I was suggesting was to just get the value you want out of the userInfo dictionary - you'd have to take a look at that object and grab whatever key you want
For anyone having this issue here's my fix, basically intercepts the notification, checks for a uri
key value and opens it. I'm not an Objective-C developer so maybe someone else can give suggestions on how to optimise this.
Edit: Still doesn't solve opening deeplinks from notifications when the app is closed 🤔
// Required for localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
// Required for Intercom disabled automatic handling of Intercom push notifications:
NSDictionary *userInfo = response.notification.request.content.userInfo;
if ([Intercom isIntercomPushNotification:userInfo]) {
[Intercom handleIntercomPushNotification:userInfo];
if (userInfo[@"uri"]) {
// Get the uri from the userInfo
NSString *uri = userInfo[@"uri"];
// Bring application into scope
UIApplication *application = [UIApplication sharedApplication];
// Convert the uri string to a NSURL Type
NSURL *URL = [NSURL URLWithString:uri];
// Open a URL with iOS 10
// @see https://useyourloaf.com/blog/openurl-deprecated-in-ios10/
[application openURL:URL options:@{}
completionHandler:^(BOOL success) {
NSLog(@"Open %@: %d",uri,success);
}];
}
}
[RNCPushNotificationIOS didReceiveNotificationResponse:response];
}
Edit 2: Check new solution bellow 👇
Update! Found a more elegant solution and that works when the app is closed.
Checklist, make sure you've done these steps before:
The core issue of Intercom not handling deep links for me was that react-native-intercom
does not pass an initial URL to an application through didFinishLaunchingWithOptions
if it's opened from the background.
Instead react-native-intercom
calls the openURL
method immediately after the application is launched and the react-native part of the application misses this event. Read more.
Handle intercom notifications manually, intercept notifications with deep links inside it and store it to open later when the app is ready. Read more on the original solution
IntercomAutoIntegratePushNotifications
to NO
in Info.plist
like it says on IntercomInfo.plist
<key>IntercomAutoIntegratePushNotifications</key>
<string>NO</string>
didReceiveNotificationResponse
in you setup on Update AppDelegate.m
AppDelegate.m
// Required for localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
// Required for handleIntercomPushNotification function bellow
NSDictionary *userInfo = response.notification.request.content.userInfo;
// Required to handle Intercom push notifications manually
if ([Intercom isIntercomPushNotification:userInfo]) {
[Intercom handleIntercomPushNotification:userInfo];
}
[RNCPushNotificationIOS didReceiveNotificationResponse:response];
}
onNotification
( see react-native-push-notification
usage). Setup up a condition that when the app is not initialized, store the deep link for later else just open the link.I know using
global
is considered "dirty" but I tried many variations usingAppStatus
,React.Context
,Async.Storage
, this one worked the best).
index.ts
// Must be outside of any component LifeCycle (such as `componentDidMount`).
PushNotification.configure({
// ...
// (required) Called when a remote is received or opened, or local notification is opened
onNotification: function (notification) {
console.log('[Notification]', notification)
// If notification is interactive
if (notification.userInteraction) {
const url = (notification.data as any)?.uri
if (url) {
/**
* When handling a notification with a deep link
*
* if the app is initialized just open url
* else save it to AsyncStorage and handle it later
*/
if (global.initialized === true) {
Linking.openURL(url)
} else {
AsyncStorage.setItem('initialURL', url)
.then(() => {
console.log('[Notification/AsyncStorage] initial url', url)
})
.catch(console.error)
}
}
}
// (required) Called when a remote is received or opened, or local notification is opened
notification.finish(PushNotificationIOS.FetchResult.NoData)
},
// ...
})
initialURL
from the AsyncStorage
otherwise every time your app starts up it will continue to open that url
, and set global.initialized
to true, so when the app is active new notifications deep links don't keep getting stored.await authenticate()
// set initialized, important to
global.initialized = true
// check if there was a initialURL stored
const initialURL = await AsyncStorage.getItem('initialURL')
// open and delete it
if (initialURL) {
await Linking.openURL(initialURL)
await AsyncStorage.removeItem('initialURL')
}
App.tsx
(mockup)
const linking = {
// ...
// Custom function to get the URL which was used to open the app
async getInitialURL() {
console.log('[Navigation/Linking] Getting initial url')
// Check if app was opened from a deep link
const url = await Linking.getInitialURL()
if (url != null) {
console.log('[Navigation/Linking] Has initial url', url)
return url
}
// Check for additional initial deep link in AsyncStorage stored by notifications
const initialURL = await AsyncStorage.getItem('initialURL')
if (initialURL != null) {
console.log('[Navigation/AsyncStorage] Has initial url', initialURL)
await AsyncStorage.removeItem('initialURL')
return initialURL
}
},
// ...
}
function App() {
return (
<Auth>
<NavigationContainer linking={linking} />
...
</NavigationContainer>
</Auth>
)
}
Important to do the authentication before the routing
Auth.tsx
(mockup)
function Auth(props) {
async function init() {
try {
await authenticate()
global.initialized = true
} catch (error) {
console.error(error)
}
}
return loading ? (
<LoadingIndicator />
) : (
props.children
)}
}
For TypeScript users here's how you fix the property does not exist on type 'Global & typeof globalThis'.ts(2339)
. On the root of the app project
global.d.ts
declare module '*.png'
declare global {
namespace NodeJS {
interface ProcessEnv {
NODE_ENV?: 'development' | 'test' | 'production'
}
interface Global {
initialized: boolean
}
}
}
// If this file has no import/export statements (i.e. is a script)
// convert it into a module by adding an empty export statement.
export {}
@du5rte @hanniedong Are your links Universal Links of Custom Scheme URLs? We now have support for deep linking a universal link in version 9.3.0
I'm using branch.io to handle deep linking and have it working with another push notification platform (One Signal).
I'm able to receive push notifications (using intercom and this library) on both iOS and Android. The only difference is the handling of the deep link. Deep links work in Android, so when I tap on the push notification, it takes me to the correct screen in the app. For iOS, tapping the push notification only opens the app and doesn't carry over the deep link.
Has anyone figured out how to handle deep links coming from Intercom push notifications?