From d4718f65d36e5ee1d8c77e9f655b8a69f53d7057 Mon Sep 17 00:00:00 2001 From: Andrew Rosiclair Date: Wed, 7 Feb 2024 11:59:27 -0500 Subject: [PATCH 1/5] use lastUpdateID and previousUpdateID to apply updates --- .../PushNotification/NotificationType.ts | 2 ++ ...bscribeToReportCommentPushNotifications.ts | 32 ++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/libs/Notification/PushNotification/NotificationType.ts b/src/libs/Notification/PushNotification/NotificationType.ts index d6ec246eddf7..40778f38c0d4 100644 --- a/src/libs/Notification/PushNotification/NotificationType.ts +++ b/src/libs/Notification/PushNotification/NotificationType.ts @@ -18,6 +18,8 @@ type ReportCommentNotificationData = { shouldScrollToLastUnread?: boolean; roomName?: string; onyxData?: OnyxServerUpdate[]; + lastUpdateID?: number; + previousUpdateID?: number; }; /** diff --git a/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts b/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts index 070f83e19e0f..6ac7c31fdd2a 100644 --- a/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts +++ b/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts @@ -1,15 +1,18 @@ import Onyx from 'react-native-onyx'; +import * as OnyxUpdates from '@libs/actions/OnyxUpdates'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; +import * as SequentialQueue from '@libs/Network/SequentialQueue'; import getPolicyMemberAccountIDs from '@libs/PolicyMembersUtils'; import {extractPolicyIDFromPath} from '@libs/PolicyUtils'; import {doesReportBelongToWorkspace, getReport} from '@libs/ReportUtils'; import Visibility from '@libs/Visibility'; import * as Modal from '@userActions/Modal'; +import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import type {OnyxUpdatesFromServer} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import backgroundRefresh from './backgroundRefresh'; import PushNotification from './index'; let lastVisitedPath: string | undefined; @@ -27,10 +30,31 @@ Onyx.connect({ * Setup reportComment push notification callbacks. */ export default function subscribeToReportCommentPushNotifications() { - PushNotification.onReceived(PushNotification.TYPE.REPORT_COMMENT, ({reportID, reportActionID, onyxData}) => { + PushNotification.onReceived(PushNotification.TYPE.REPORT_COMMENT, ({reportID, reportActionID, onyxData, lastUpdateID, previousUpdateID}) => { Log.info(`[PushNotification] received report comment notification in the ${Visibility.isVisible() ? 'foreground' : 'background'}`, false, {reportID, reportActionID}); - Onyx.update(onyxData ?? []); - backgroundRefresh(); + + if (onyxData && lastUpdateID && previousUpdateID) { + const updates: OnyxUpdatesFromServer = { + type: CONST.ONYX_UPDATE_TYPES.PUSHER, + lastUpdateID, + previousUpdateID, + updates: [ + { + eventType: 'eventType', + data: onyxData, + }, + ], + }; + + if (!OnyxUpdates.doesClientNeedToBeUpdated(previousUpdateID)) { + OnyxUpdates.apply(updates); + return; + } + + // If we reached this point, we need to pause the queue while we prepare to fetch older OnyxUpdates. + SequentialQueue.pause(); + OnyxUpdates.saveUpdateInformation(updates); + } }); // Open correct report when push notification is clicked From 151b9ed364c9d27540412ddd43bb16f818f2d7fe Mon Sep 17 00:00:00 2001 From: Andrew Rosiclair Date: Wed, 7 Feb 2024 12:08:08 -0500 Subject: [PATCH 2/5] log when data is present or missing --- .../subscribeToReportCommentPushNotifications.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts b/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts index 6ac7c31fdd2a..4aca364d48c8 100644 --- a/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts +++ b/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts @@ -34,6 +34,8 @@ export default function subscribeToReportCommentPushNotifications() { Log.info(`[PushNotification] received report comment notification in the ${Visibility.isVisible() ? 'foreground' : 'background'}`, false, {reportID, reportActionID}); if (onyxData && lastUpdateID && previousUpdateID) { + Log.info('[PushNotification] reliable onyx update received', false, {lastUpdateID, previousUpdateID, onyxDataCount: onyxData?.length ?? 0}); + const updates: OnyxUpdatesFromServer = { type: CONST.ONYX_UPDATE_TYPES.PUSHER, lastUpdateID, @@ -54,6 +56,8 @@ export default function subscribeToReportCommentPushNotifications() { // If we reached this point, we need to pause the queue while we prepare to fetch older OnyxUpdates. SequentialQueue.pause(); OnyxUpdates.saveUpdateInformation(updates); + } else { + Log.hmmm("[PushNotification] Didn't apply onyx updates because some data is missing", {lastUpdateID, previousUpdateID, onyxDataCount: onyxData?.length ?? 0}); } }); From 9e7951afa5d4a588a357e2ade79e4113c165f58a Mon Sep 17 00:00:00 2001 From: Andrew Rosiclair Date: Wed, 7 Feb 2024 15:01:10 -0500 Subject: [PATCH 3/5] DRY up reliable update code --- .../subscribeToReportCommentPushNotifications.ts | 11 +---------- src/libs/actions/OnyxUpdates.ts | 15 ++++++++++++++- src/libs/actions/User.ts | 11 ++--------- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts b/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts index 4aca364d48c8..4586671d71ee 100644 --- a/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts +++ b/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts @@ -2,7 +2,6 @@ import Onyx from 'react-native-onyx'; import * as OnyxUpdates from '@libs/actions/OnyxUpdates'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; -import * as SequentialQueue from '@libs/Network/SequentialQueue'; import getPolicyMemberAccountIDs from '@libs/PolicyMembersUtils'; import {extractPolicyIDFromPath} from '@libs/PolicyUtils'; import {doesReportBelongToWorkspace, getReport} from '@libs/ReportUtils'; @@ -47,15 +46,7 @@ export default function subscribeToReportCommentPushNotifications() { }, ], }; - - if (!OnyxUpdates.doesClientNeedToBeUpdated(previousUpdateID)) { - OnyxUpdates.apply(updates); - return; - } - - // If we reached this point, we need to pause the queue while we prepare to fetch older OnyxUpdates. - SequentialQueue.pause(); - OnyxUpdates.saveUpdateInformation(updates); + OnyxUpdates.applyOnyxUpdatesReliably(updates); } else { Log.hmmm("[PushNotification] Didn't apply onyx updates because some data is missing", {lastUpdateID, previousUpdateID, onyxDataCount: onyxData?.length ?? 0}); } diff --git a/src/libs/actions/OnyxUpdates.ts b/src/libs/actions/OnyxUpdates.ts index cfb4735f0638..bcf7a9373ae0 100644 --- a/src/libs/actions/OnyxUpdates.ts +++ b/src/libs/actions/OnyxUpdates.ts @@ -2,6 +2,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {Merge} from 'type-fest'; import Log from '@libs/Log'; +import * as SequentialQueue from '@libs/Network/SequentialQueue'; import PusherUtils from '@libs/PusherUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -141,5 +142,17 @@ function doesClientNeedToBeUpdated(previousUpdateID = 0): boolean { return lastUpdateIDAppliedToClient < previousUpdateID; } +function applyOnyxUpdatesReliably(updates: OnyxUpdatesFromServer) { + const previousUpdateID = Number(updates.previousUpdateID) || 0; + if (!doesClientNeedToBeUpdated(previousUpdateID)) { + apply(updates); + return; + } + + // If we reached this point, we need to pause the queue while we prepare to fetch older OnyxUpdates. + SequentialQueue.pause(); + saveUpdateInformation(updates); +} + // eslint-disable-next-line import/prefer-default-export -export {saveUpdateInformation, doesClientNeedToBeUpdated, apply}; +export {saveUpdateInformation, doesClientNeedToBeUpdated, apply, applyOnyxUpdatesReliably}; diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index a8ef33a92e38..064453bca181 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -39,7 +39,7 @@ import type ReportAction from '@src/types/onyx/ReportAction'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import * as Link from './Link'; -import * as OnyxUpdates from './OnyxUpdates'; +import {applyOnyxUpdatesReliably} from './OnyxUpdates'; import * as PersonalDetails from './PersonalDetails'; import * as Report from './Report'; import * as Session from './Session'; @@ -503,14 +503,7 @@ function subscribeToUserEvents() { updates: pushJSON.updates ?? [], previousUpdateID: Number(pushJSON.previousUpdateID || 0), }; - if (!OnyxUpdates.doesClientNeedToBeUpdated(Number(pushJSON.previousUpdateID || 0))) { - OnyxUpdates.apply(updates); - return; - } - - // If we reached this point, we need to pause the queue while we prepare to fetch older OnyxUpdates. - SequentialQueue.pause(); - OnyxUpdates.saveUpdateInformation(updates); + applyOnyxUpdatesReliably(updates); }); // Handles Onyx updates coming from Pusher through the mega multipleEvents. From 02ad87af5c391b2fd81f53bb6272bcf840a56011 Mon Sep 17 00:00:00 2001 From: Andrew Rosiclair Date: Fri, 9 Feb 2024 18:21:15 -0500 Subject: [PATCH 4/5] re-add background refresh --- .../subscribeToReportCommentPushNotifications.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts b/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts index 8c31fddb0db8..8fcf281b1443 100644 --- a/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts +++ b/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts @@ -12,6 +12,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {OnyxUpdatesFromServer} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import backgroundRefresh from './backgroundRefresh'; import PushNotification from './index'; let lastVisitedPath: string | undefined; @@ -50,6 +51,8 @@ export default function subscribeToReportCommentPushNotifications() { } else { Log.hmmm("[PushNotification] Didn't apply onyx updates because some data is missing", {lastUpdateID, previousUpdateID, onyxDataCount: onyxData?.length ?? 0}); } + + backgroundRefresh(); }); // Open correct report when push notification is clicked From 33f9c411246dddc1720001fe099eaf3213535ba2 Mon Sep 17 00:00:00 2001 From: Andrew Rosiclair Date: Mon, 12 Feb 2024 16:46:10 -0500 Subject: [PATCH 5/5] use new airship update type --- src/CONST.ts | 1 + .../subscribeToReportCommentPushNotifications.ts | 2 +- src/libs/actions/OnyxUpdateManager.ts | 3 ++- src/libs/actions/OnyxUpdates.ts | 2 +- src/types/onyx/OnyxUpdatesFromServer.ts | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 79895d20aa57..4f93340de379 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -3025,6 +3025,7 @@ const CONST = { ONYX_UPDATE_TYPES: { HTTPS: 'https', PUSHER: 'pusher', + AIRSHIP: 'airship', }, EVENTS: { SCROLLING: 'scrolling', diff --git a/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts b/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts index 8fcf281b1443..7f86d3ddb9ac 100644 --- a/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts +++ b/src/libs/Notification/PushNotification/subscribeToReportCommentPushNotifications.ts @@ -37,7 +37,7 @@ export default function subscribeToReportCommentPushNotifications() { Log.info('[PushNotification] reliable onyx update received', false, {lastUpdateID, previousUpdateID, onyxDataCount: onyxData?.length ?? 0}); const updates: OnyxUpdatesFromServer = { - type: CONST.ONYX_UPDATE_TYPES.PUSHER, + type: CONST.ONYX_UPDATE_TYPES.AIRSHIP, lastUpdateID, previousUpdateID, updates: [ diff --git a/src/libs/actions/OnyxUpdateManager.ts b/src/libs/actions/OnyxUpdateManager.ts index ab0dea960b27..b4554f9461ce 100644 --- a/src/libs/actions/OnyxUpdateManager.ts +++ b/src/libs/actions/OnyxUpdateManager.ts @@ -41,7 +41,8 @@ export default () => { if ( !(typeof value === 'object' && !!value) || !('type' in value) || - (!(value.type === CONST.ONYX_UPDATE_TYPES.HTTPS && value.request && value.response) && !(value.type === CONST.ONYX_UPDATE_TYPES.PUSHER && value.updates)) + (!(value.type === CONST.ONYX_UPDATE_TYPES.HTTPS && value.request && value.response) && + !((value.type === CONST.ONYX_UPDATE_TYPES.PUSHER || value.type === CONST.ONYX_UPDATE_TYPES.AIRSHIP) && value.updates)) ) { console.debug('[OnyxUpdateManager] Invalid format found for updates, cleaning and unpausing the queue'); Onyx.set(ONYXKEYS.ONYX_UPDATES_FROM_SERVER, null); diff --git a/src/libs/actions/OnyxUpdates.ts b/src/libs/actions/OnyxUpdates.ts index bcf7a9373ae0..ab26ad330b6f 100644 --- a/src/libs/actions/OnyxUpdates.ts +++ b/src/libs/actions/OnyxUpdates.ts @@ -108,7 +108,7 @@ function apply({lastUpdateID, type, request, response, updates}: OnyxUpdatesFrom if (type === CONST.ONYX_UPDATE_TYPES.HTTPS && request && response) { return applyHTTPSOnyxUpdates(request, response); } - if (type === CONST.ONYX_UPDATE_TYPES.PUSHER && updates) { + if ((type === CONST.ONYX_UPDATE_TYPES.PUSHER || type === CONST.ONYX_UPDATE_TYPES.AIRSHIP) && updates) { return applyPusherOnyxUpdates(updates); } } diff --git a/src/types/onyx/OnyxUpdatesFromServer.ts b/src/types/onyx/OnyxUpdatesFromServer.ts index f6104ed470a0..3c6933da19ba 100644 --- a/src/types/onyx/OnyxUpdatesFromServer.ts +++ b/src/types/onyx/OnyxUpdatesFromServer.ts @@ -13,7 +13,7 @@ type OnyxUpdateEvent = { }; type OnyxUpdatesFromServer = { - type: 'https' | 'pusher'; + type: 'https' | 'pusher' | 'airship'; lastUpdateID: number | string; previousUpdateID: number | string; request?: Request;