Skip to content

Commit

Permalink
Make iOS notifications compatible with background fetch (mattermost#5969
Browse files Browse the repository at this point in the history
)
  • Loading branch information
enahum authored Feb 17, 2022
1 parent f929bf9 commit b0b4e55
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 6 deletions.
14 changes: 8 additions & 6 deletions app/actions/views/root.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export function loadConfigAndLicense() {
};
}

export function loadFromPushNotification(notification, isInitialNotification) {
export function loadFromPushNotification(notification, isInitialNotification, skipChannelSwitch = false) {
return async (dispatch, getState) => {
const state = getState();
const {payload} = notification;
Expand Down Expand Up @@ -108,12 +108,14 @@ export function loadFromPushNotification(notification, isInitialNotification) {
await Promise.all(loading);
}

dispatch(handleSelectTeamAndChannel(teamId, channelId));
dispatch(selectPost(''));
if (!skipChannelSwitch) {
dispatch(handleSelectTeamAndChannel(teamId, channelId));
dispatch(selectPost(''));

const {root_id: rootId} = notification.payload || {};
if (isCollapsedThreadsEnabled(state) && rootId) {
dispatch(selectPost(rootId));
const {root_id: rootId} = notification.payload || {};
if (isCollapsedThreadsEnabled(state) && rootId) {
dispatch(selectPost(rootId));
}
}
return {data: true};
};
Expand Down
13 changes: 13 additions & 0 deletions app/init/push_notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,17 @@ class PushNotifications {
EphemeralStore.setStartFromNotification(true);
notification.userInteraction = true;

if (Platform.OS === 'ios') {
// when a notification is received on iOS, getInitialNotification, will return the notification
// as the app will initialized cause we are using background fetch,
// that does not necessarily mean that the app was opened cause of the notification was tapped.
// Here we are going to dettermine if the notification still exists in NotificationCenter to verify if
// the app was opened because of a tap or cause of the background fetch init
const delivered = await Notifications.ios.getDeliveredNotifications();
notification.userInteraction = delivered.find((d) => (d as unknown as NotificationWithAck).ack_id === notification?.payload?.ack_id) == null;
notification.foreground = false;
}

// getInitialNotification may run before the store is set
// that is why we run on an interval until the store is available
// once we handle the notification the interval is cleared.
Expand Down Expand Up @@ -221,6 +232,8 @@ class PushNotifications {
}
}
}
} else if (!userInteraction && Platform.OS === 'ios') {
dispatch(loadFromPushNotification(notification, isInitialNotification, true));
}
break;
case NOTIFICATION_TYPE.SESSION:
Expand Down
5 changes: 5 additions & 0 deletions app/types/push_notification.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ interface NotificationUserInfo {
test?: boolean;
}

interface NotificationWithAck extends Notification {
ack_id: string;
}

interface NotificationData {
ack_id: string;
body?: string;
channel_id: string;
channel_name?: string;
Expand Down

0 comments on commit b0b4e55

Please sign in to comment.