If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!
Action Performed:
This bug comes from discussion in #26592
TL;DR: Onyx processes the successData and API response in the wrong order on iOS and Android.
Dive deeper:
|
API.write('AddMembersToWorkspace', params, {optimisticData, successData, failureData}); |
When adding a member to workspace here, we send the following data:
"optimisticData": {
"onyxMethod": "set",
"key": "report_3008335418540078",
"value": {
"type": "chat",
"chatType": "policyExpenseChat",
"ownerAccountID": 899964195,
"participantAccountIDs": [
15664021,
899964195
],
"policyID": "41A8E180FAEB43DF",
"reportID": "3008335418540078",
"reportName": "Chat Report",
"pendingFields": {
"createChat": "add"
},
"isOptimisticReport": true
...
}
},
"successData": {
"onyxMethod": "merge",
"key": "report_3008335418540078",
"value": {
"pendingFields": {
"createChat": null
},
"errorFields": {
"createChat": null
},
"isOptimisticReport": false
}
}
And the API call returns the following onyx merge_collection action:
{
"jsonCode": 200,
"requestID": "806fecea0afd3512-WAW",
"onyxData": [
{
"onyxMethod": "mergecollection",
"key": "report_",
"value": {
...
"report_3008335418540078": {
"reportID": "3008335418540078",
"reportName": "",
"type": "chat",
"chatType": "policyExpenseChat",
"ownerEmail": "[pasha@test.co](mailto:pasha@test.co)",
"ownerAccountID": 15671904,
"policyID": "41A8E180FAEB43DF",
"participants": [
"[pasha@test.co](mailto:pasha@test.co)",
"[paultsimura+3@gmail.com](mailto:paultsimura+3@gmail.com)"
],
"participantAccountIDs": [
15664021,
15671904
],
"lastActorAccountID": 15671904,
},
}
},
]
}
It should replace the temporary accountID of the report.ownerAccountID with the real one, which comes from the server.
On the web, the onyx actions are executed in the following order:
- persist optimisticData;
- persist successData;
- persist API response;
The issue is that on iOS, the onyx actions are executed in the following order:
- persist optimisticData;
- persist API response;
- persist successData;
The successData holds merge operation of only several certain fields, which shouldn't affect the report much.
However, here's the tricky part:
This piece of code, which creates a promise for future merge operation, is executed before Onyx persists the API response:
https://github.com/Expensify/react-native-onyx/blob/616c4c5286b7a7fadac18d477cd75edd60865b12/lib/Onyx.js#L1136-L1147
Meaning the following execution chain:
- persist optimisticData;
- create
persistSuccessData promise;
- persist API response;
- execute
persistSuccessData promise;
This means, at the moment persistSuccessData is created, the existingValue is still not updated, so even though it should update only a couple of fields, the modifiedData here is saved in a state of pre-API-response.
Then the report is updated by the "persist API response" operation, but gets overwritten by the persistSuccessData operation with the outdated data.
If we debug step-by-step, you'll notice that the chat name is displayed correctly between the steps 3 and 4 from above.
As an outcome of this complete operation, the state of Onyx is the following:
- personalDetailsList contains the new permanent ownerAccountID;
- report has the temporary ownerAccountID, which is already removed from Onyx.
Expected Result:
Onyx updates are executed in correct order without data being overwritten
Actual Result:
Onyx updates face a race condition and some data is overwritten
Workaround:
Unknown
Platforms:
Which of our officially supported platforms is this issue occurring on?
Version Number: 1.3.76.0
Reproducible in staging?: n/a
Reproducible in production?: n/a
If this was caught during regression testing, add the test name, ID and link from TestRail:
Email or phone of affected tester (no customers):
Logs: https://stackoverflow.com/c/expensify/questions/4856
Notes/Photos/Videos: Any additional supporting documentation
n/a
Expensify/Expensify Issue URL:
Issue reported by: @@paultsimura
Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1696287156456449
View all open jobs on GitHub
Upwork Automation - Do Not Edit
- Upwork Job URL: https://www.upwork.com/jobs/~013373cff08a2575e9
- Upwork Job ID: 1709846441891180544
- Last Price Increase: 2023-10-05
If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!
Action Performed:
This bug comes from discussion in #26592
TL;DR: Onyx processes the
successDataand API response in the wrong order on iOS and Android.Dive deeper:
App/src/libs/actions/Policy.js
Line 408 in 3352cc8
When adding a member to workspace here, we send the following data:
And the API call returns the following onyx
merge_collectionaction:It should replace the temporary
accountIDof thereport.ownerAccountIDwith the real one, which comes from the server.On the web, the onyx actions are executed in the following order:
The issue is that on iOS, the onyx actions are executed in the following order:
The
successDataholds merge operation of only several certain fields, which shouldn't affect the report much.However, here's the tricky part:
This piece of code, which creates a promise for future merge operation, is executed before Onyx persists the API response:
https://github.com/Expensify/react-native-onyx/blob/616c4c5286b7a7fadac18d477cd75edd60865b12/lib/Onyx.js#L1136-L1147
Meaning the following execution chain:
persistSuccessDatapromise;persistSuccessDatapromise;This means, at the moment
persistSuccessDatais created, the existingValue is still not updated, so even though it should update only a couple of fields, themodifiedDatahere is saved in a state of pre-API-response.Then the report is updated by the "persist API response" operation, but gets overwritten by the
persistSuccessDataoperation with the outdated data.If we debug step-by-step, you'll notice that the chat name is displayed correctly between the steps 3 and 4 from above.
As an outcome of this complete operation, the state of Onyx is the following:
Expected Result:
Onyx updates are executed in correct order without data being overwritten
Actual Result:
Onyx updates face a race condition and some data is overwritten
Workaround:
Unknown
Platforms:
Which of our officially supported platforms is this issue occurring on?
Version Number: 1.3.76.0
Reproducible in staging?: n/a
Reproducible in production?: n/a
If this was caught during regression testing, add the test name, ID and link from TestRail:
Email or phone of affected tester (no customers):
Logs: https://stackoverflow.com/c/expensify/questions/4856
Notes/Photos/Videos: Any additional supporting documentation
n/a
Expensify/Expensify Issue URL:
Issue reported by: @@paultsimura
Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1696287156456449
View all open jobs on GitHub
Upwork Automation - Do Not Edit