Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Push notification onyx updates not applied when notification is selected #42510

Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
5dce826
Merge branch 'main' into @chrispader/add-deferred-updates--queue-func…
chrispader May 23, 2024
65a43c1
apply notification updates once a push notification is selected
chrispader May 23, 2024
9f0a892
Update src/libs/Notification/PushNotification/subscribePushNotificati…
chrispader May 24, 2024
435cb59
Merge branch 'main' into @chrispader/fix/push-notifications-defer-ony…
chrispader May 24, 2024
56645b7
fix: pr comments
chrispader May 24, 2024
08bb933
fix: don't wait for notification updates being applied before navigat…
chrispader May 24, 2024
aec6383
fix: wrong import
chrispader May 24, 2024
427c4fa
fix: resolve gh comments
chrispader May 28, 2024
73ecced
rename function
chrispader May 28, 2024
dc2372f
fix: apply onyx updates in order
chrispader May 29, 2024
e2e7940
fix: missing spread operator
chrispader May 29, 2024
5098cef
Merge branch 'main' into @chrispader/fix/push-notifications-defer-ony…
chrispader May 31, 2024
62b38a5
Merge branch 'main' into @chrispader/fix/push-notifications-defer-ony…
chrispader May 31, 2024
c2361cb
Merge branch 'main' into @chrispader/fix/push-notifications-defer-ony…
chrispader Jun 3, 2024
a2a85b9
add logs to DeferredOnyxUpdates
chrispader Jun 3, 2024
f7895e2
fix: wait for notifications to be fetched before navigating to report
chrispader Jun 3, 2024
955247e
fix: other logs
chrispader Jun 3, 2024
6fb2993
don't enqueue updates when no notifications received
chrispader Jun 3, 2024
aa9503b
rename logs for consistency
chrispader Jun 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type {PushPayload} from '@ua/react-native-airship';
import type {PushNotificationData} from './NotificationType';

function getPushNotificationData(notification: PushPayload): PushNotificationData {
let payload = notification.extras.payload;

// On Android, some notification payloads are sent as a JSON string rather than an object
if (typeof payload === 'string') {
payload = JSON.parse(payload);
}

return payload as PushNotificationData;
}

export default getPushNotificationData;
10 changes: 2 additions & 8 deletions src/libs/Notification/PushNotification/index.native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Log from '@libs/Log';
import * as PushNotificationActions from '@userActions/PushNotification';
import ONYXKEYS from '@src/ONYXKEYS';
import ForegroundNotifications from './ForegroundNotifications';
import getPushNotificationData from './getPushNotificationData';
import type {PushNotificationData} from './NotificationType';
import NotificationType from './NotificationType';
import type {ClearNotifications, Deregister, Init, OnReceived, OnSelected, Register} from './types';
Expand All @@ -27,14 +28,7 @@ const notificationEventActionMap: NotificationEventActionMap = {};
*/
function pushNotificationEventCallback(eventType: EventType, notification: PushPayload) {
const actionMap = notificationEventActionMap[eventType] ?? {};
let payload = notification.extras.payload;

// On Android, some notification payloads are sent as a JSON string rather than an object
if (typeof payload === 'string') {
payload = JSON.parse(payload);
}

const data = payload as PushNotificationData;
const data = getPushNotificationData(notification);

Log.info(`[PushNotification] Callback triggered for ${eventType}`);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import Airship from '@ua/react-native-airship';
import Onyx from 'react-native-onyx';
import applyOnyxUpdatesReliably from '@libs/actions/applyOnyxUpdatesReliably';
import type {DeferredUpdatesDictionary} from '@libs/actions/OnyxUpdateManager/types';
import * as DeferredOnyxUpdates from '@libs/actions/OnyxUpdateManager/utils/DeferredOnyxUpdates';
import * as ActiveClientManager from '@libs/ActiveClientManager';
import Log from '@libs/Log';
import Navigation from '@libs/Navigation/Navigation';
import getPushNotificationData from '@libs/Notification/PushNotification/getPushNotificationData';
import type {ReportActionPushNotificationData} from '@libs/Notification/PushNotification/NotificationType';
import getPolicyEmployeeAccountIDs from '@libs/PolicyEmployeeListUtils';
import {extractPolicyIDFromPath} from '@libs/PolicyUtils';
Expand All @@ -13,6 +17,7 @@ import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {OnyxUpdatesFromServer} from '@src/types/onyx';
import type {OnyxServerUpdate} from '@src/types/onyx/OnyxUpdatesFromServer';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import PushNotification from '..';

Expand All @@ -27,6 +32,20 @@ Onyx.connect({
},
});

function buildOnyxUpdatesFromServer({onyxData, lastUpdateID, previousUpdateID}: {onyxData: OnyxServerUpdate[]; lastUpdateID: number; previousUpdateID: number}) {
chrispader marked this conversation as resolved.
Show resolved Hide resolved
return {
type: CONST.ONYX_UPDATE_TYPES.AIRSHIP,
lastUpdateID,
previousUpdateID,
updates: [
{
eventType: 'eventType',
data: onyxData,
},
],
} as OnyxUpdatesFromServer;
}

function getLastUpdateIDAppliedToClient(): Promise<number> {
return new Promise((resolve) => {
Onyx.connect({
Expand All @@ -50,17 +69,8 @@ function applyOnyxData({reportID, reportActionID, onyxData, lastUpdateID, previo
}

Log.info('[PushNotification] reliable onyx update received', false, {lastUpdateID, previousUpdateID, onyxDataCount: onyxData?.length ?? 0});
const updates: OnyxUpdatesFromServer = {
type: CONST.ONYX_UPDATE_TYPES.AIRSHIP,
lastUpdateID,
previousUpdateID,
updates: [
{
eventType: 'eventType',
data: onyxData,
},
],
};

const updates = buildOnyxUpdatesFromServer({onyxData, lastUpdateID, previousUpdateID});

/**
* When this callback runs in the background on Android (via Headless JS), no other Onyx.connect callbacks will run. This means that
Expand All @@ -71,6 +81,31 @@ function applyOnyxData({reportID, reportActionID, onyxData, lastUpdateID, previo
}

function navigateToReport({reportID, reportActionID}: ReportActionPushNotificationData): Promise<void> {
Log.info('[PushNotification] Adding push notification updates to deferred updates queue', false, {reportID, reportActionID});

// Onyx data from push notifications might not have been applied when they were received in the background
// due to OS limitations. So we'll also attempt to apply them here so they can display immediately. Reliable
// updates will prevent any old updates from being duplicated and any gaps in them will be handled
Airship.push.getActiveNotifications().then((notifications) => {
const onyxUpdates = notifications.reduce<DeferredUpdatesDictionary>((updates, notification) => {
const pushNotificationData = getPushNotificationData(notification);
const lastUpdateID = pushNotificationData.lastUpdateID;
const previousUpdateID = pushNotificationData.previousUpdateID;

if (pushNotificationData.onyxData == null || lastUpdateID == null || previousUpdateID == null) {
return updates;
}

const newUpdates = buildOnyxUpdatesFromServer({onyxData: pushNotificationData.onyxData, lastUpdateID, previousUpdateID});

// eslint-disable-next-line no-param-reassign
updates[lastUpdateID] = newUpdates;
return updates;
}, {});

return DeferredOnyxUpdates.enqueueAndProcess(onyxUpdates);
});

Log.info('[PushNotification] Navigating to report', false, {reportID, reportActionID});

const policyID = lastVisitedPath && extractPolicyIDFromPath(lastVisitedPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ function process() {
}

missingOnyxUpdatesQueryPromise = OnyxUpdateManagerUtils.validateAndApplyDeferredUpdates();

return missingOnyxUpdatesQueryPromise;
}

type EnqueueDeferredOnyxUpdatesOptions = {
Expand Down Expand Up @@ -105,7 +107,7 @@ function enqueue(updates: OnyxUpdatesFromServer | DeferredUpdatesDictionary, opt
*/
function enqueueAndProcess(updates: OnyxUpdatesFromServer | DeferredUpdatesDictionary, options?: EnqueueDeferredOnyxUpdatesOptions) {
enqueue(updates, options);
process();
return process();
}

type ClearDeferredOnyxUpdatesOptions = {
Expand Down
Loading