diff --git a/src/libs/actions/OnyxUpdates.ts b/src/libs/actions/OnyxUpdates.ts index 436c28ba42b6..e60ba962d436 100644 --- a/src/libs/actions/OnyxUpdates.ts +++ b/src/libs/actions/OnyxUpdates.ts @@ -1,7 +1,7 @@ import type {OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {Merge} from 'type-fest'; -import {WRITE_COMMANDS} from '@libs/API/types'; +import {SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import Log from '@libs/Log'; import Performance from '@libs/Performance'; import PusherUtils from '@libs/PusherUtils'; @@ -114,7 +114,11 @@ function apply({lastUpdateID, type, request, response, updates}: OnyxUpdatesFrom function apply({lastUpdateID, type, request, response, updates}: OnyxUpdatesFromServer): Promise | undefined { Log.info(`[OnyxUpdateManager] Applying update type: ${type} with lastUpdateID: ${lastUpdateID}`, false, {command: request?.command}); - if (lastUpdateID && lastUpdateIDAppliedToClient && Number(lastUpdateID) <= lastUpdateIDAppliedToClient && request?.command !== WRITE_COMMANDS.OPEN_APP) { + const isUpdateOld = lastUpdateID && lastUpdateIDAppliedToClient && Number(lastUpdateID) <= lastUpdateIDAppliedToClient; + const isOpenAppRequest = request?.command === WRITE_COMMANDS.OPEN_APP; + const isFullReconnectRequest = request?.command === SIDE_EFFECT_REQUEST_COMMANDS.RECONNECT_APP && !request?.data?.updateIDFrom; + + if (isUpdateOld && !isOpenAppRequest && !isFullReconnectRequest) { Log.info('[OnyxUpdateManager] Update received was older than or the same as current state, returning without applying the updates other than successData and failureData', false, { lastUpdateID, lastUpdateIDAppliedToClient, diff --git a/tests/unit/OnyxUpdatesTest.ts b/tests/unit/OnyxUpdatesTest.ts index 708a75fb7c67..563acb6ee909 100644 --- a/tests/unit/OnyxUpdatesTest.ts +++ b/tests/unit/OnyxUpdatesTest.ts @@ -1,5 +1,6 @@ import type {OnyxKey} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; +import {SIDE_EFFECT_REQUEST_COMMANDS} from '@libs/API/types'; import CONST from '@src/CONST'; import * as OnyxUpdates from '@src/libs/actions/OnyxUpdates'; import DateUtils from '@src/libs/DateUtils'; @@ -64,6 +65,41 @@ describe('OnyxUpdatesTest', () => { expect(reportAction).toStrictEqual(reportActionValue); }); }); + + it('applies full ReconnectApp Onyx updates even if they appear old', async () => { + // Given the current lastUpdateIDAppliedToClient is merged + const currentUpdateID = 100; + await Onyx.merge(ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT, currentUpdateID); + + // And we received onyx updates from a full ReconnectApp request with the same lastUpdateID + const reportID = NumberUtils.rand64(); + const reportValue = {reportID}; + const fullReconnectUpdates: OnyxUpdatesFromServer = { + type: CONST.ONYX_UPDATE_TYPES.HTTPS, + request: { + command: SIDE_EFFECT_REQUEST_COMMANDS.RECONNECT_APP, + data: { + updateIDFrom: null, + }, + }, + response: { + onyxData: [ + { + onyxMethod: 'merge', + key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, + value: reportValue, + }, + ], + }, + previousUpdateID: currentUpdateID - 2, + lastUpdateID: currentUpdateID - 1, + }; + + // When we apply the updates, then they are still applied even if the lastUpdateID is old + await OnyxUpdates.apply(fullReconnectUpdates); + const report = await getOnyxValue(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`); + expect(report).toStrictEqual(reportValue); + }); }); function getOnyxValues(...keys: TKey[]) {