Skip to content

multiMerge will *overwrite* key on iOS for '{}' #1046

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

Closed
1 of 5 tasks
irisjae opened this issue Dec 8, 2023 · 5 comments · Fixed by #1064
Closed
1 of 5 tasks

multiMerge will *overwrite* key on iOS for '{}' #1046

irisjae opened this issue Dec 8, 2023 · 5 comments · Fixed by #1064
Assignees
Labels
bug Something isn't working released

Comments

@irisjae
Copy link

irisjae commented Dec 8, 2023

What happened?

According to documentation, the function of multiMerge is Multiple merging of existing and new values in a batch. Assumes that values are stringified JSON. Once completed, invokes callback with errors (if any).

One expects that the empty object {} is the identity of the operation of merging objects, and that merging the JSON-ified object "{}" into any value that is already an object will produce no effect.

This is the case on Android and not the case on iOS (tested with 1.19.3). The following snippet reproduces this, producing '{ "x": 1 }' for key "a" on Android, and producing '{}' on iOS.

let { default: { multiMerge, getAllKeys, multiGet } } = require ('@react-native-async-storage/async-storage')

Promise .resolve ()
.then (_ => multiMerge ([ [ 'a', '{ "x": 1 }' ] ] ))
.then (_ => multiMerge ([ [ 'a', '{}' ] ] ))
.then (_ => getAllKeys ())
.then (keys => multiGet (keys))
.then (entries => Object .fromEntries (entries))
.then (result => console .log (result))

The bug is caused by this line

if (RCTMergeRecursive(mergedVal, RCTJSONParse(entry[1], &jsonError))) {
Presumably, the line is intended to overwrite the previous value if the provided input is not an object (i.e. not mergeable). What is actually specified is overwriting of the previous value if the provided input has no keys, which unfortunately produces this bug. The corresponding implementation in Android properly (it seems) merges the values instead, and handles the case correctly.

Version

1.19.3

What platforms are you seeing this issue on?

  • Android
  • iOS
  • macOS
  • Windows
  • web

System Information

.

Steps to Reproduce

Provided above

@irisjae irisjae added the bug Something isn't working label Dec 8, 2023
Copy link

github-actions bot commented Feb 7, 2024

This issue has been marked as stale due to inactivity. Please respond or otherwise resolve the issue within 7 days or it will be closed.

@github-actions github-actions bot added the Stale label Feb 7, 2024
@irisjae
Copy link
Author

irisjae commented Feb 8, 2024

I've worked around this, but this is not stale; I've attached a test case and the relevant code that appears to cause the issue.

This issue potentially causes data loss.

@github-actions github-actions bot removed the Stale label Feb 9, 2024
@irisjae
Copy link
Author

irisjae commented Feb 17, 2024

I don't know about the maintainers of this project, but to me, unexpected data loss issues are not very encouraging signs. I'm happy to provide a PR if maintainers show interest.

@krizzu
Copy link
Member

krizzu commented Feb 17, 2024

@irisjae Thanks for the details explanation, I'll try to find some time later next week to look into that 🙏

@AsyncStorageBot
Copy link
Collaborator

🎉 This issue has been resolved in version 1.22.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working released
Projects
None yet
3 participants