react-native-encrypted-storage icon indicating copy to clipboard operation
react-native-encrypted-storage copied to clipboard

*CAREFUL* Your persisted values will be lost when running in the Background on iOS

Open wjeffersontpadua opened this issue 2 years ago • 9 comments

This is a great library for securily storing values, but it currently has a problem that might cause a lot of headaches to developers, specially if you already have an app running and add the Background Fetch capability into the app and start using it with libraries like react-native-background-fetch and react-native-background-timer both of which will execute operations in the background (e.g: when the phone is locked)

If your background processes interact with the Keychain, you'll completely loose those values if you try to update them when the app is running in the background. The reason for that is because the default keychain item accessibility is that items are only accessibible when the phone is unlocked, and this library currently uses the default accessibility when you pass your key/value pair to setItem. So when you call setItem in the background, the library will first delete the existing value as can be seen here and then it'll try to write the new value, but that'll fail since it's not using the proper accessibility level.

There's a PR already opened here which increases the functionality of the library by allowing us as developers to customize the accessibility level to whatever we want. I think the maintainers should consider accepting the PR and releasing a new official version, specially considering the popularity of this library and also the impact that this behavior can silently cause in apps, which is very tricky to reproduce when you consider how background fetches are executed by iOS.

If the PR isn't in the essense of how the maintainers believe the library should work, I think we should at least have a warning to this behavior added to the README section to prevent people from running into this issue in the future.

wjeffersontpadua avatar Jun 10 '22 18:06 wjeffersontpadua

This was extremely helpful. Thanks a lot my man! They should make this more clear in their doc.

Lyle-Rogers avatar Jul 04 '22 04:07 Lyle-Rogers

This happens to me also. Lot of months with this bug and it was extremely hard to reproduce (so hard to find a solution).

Thanks for sharing this information, I just reproduced it and it seems that this is breaking the app storage.

Agreed about having this issue as an advise in the home page. It can save a lot of time for us.

mateomarconi avatar Nov 17 '22 04:11 mateomarconi

This happens to me also. Lot of months with this bug and it was extremely hard to reproduce (so hard to find a solution).

Thanks for sharing this information, I just reproduced it and it seems that this is breaking the app storage.

Agreed about having this issue as an advise in the home page. It can save a lot of time for us.

@mateomarconi - How did you reproduce this issue? Seeing this logged but unable to reproduce the error to verify an issue.

jkelley79 avatar Dec 19 '22 16:12 jkelley79

@jkelley79 to reproduce the issue you can start the app and setup a timeout with a callback that changes something in the encrypted storage. Then, once the timeout is started, lock the phone and wait until the callback is called, then when you open the app again, you'll see that whatever property you tried to change when the phone was locked, will be gone from storage

wjeffersontpadua avatar Dec 20 '22 12:12 wjeffersontpadua

@wjeffersontpadua - I setup a timeout, locked the phone but the callback is not fired until I unlock the phone and/or relaunch the app. Seems like you would need a way to trigger the app to run in the background while the phone is locked to reproduce.

jkelley79 avatar Dec 20 '22 16:12 jkelley79

@jkelley79 I believe I've used react-native-background-timer to achieve that

wjeffersontpadua avatar Dec 20 '22 16:12 wjeffersontpadua

To help to index someone else with this bug. This is the error message:

RNEncryptedStorageError: An error occured while retrieving value

when calling:

await EncryptedStorage.getItem(key)

ericksprengel avatar Mar 08 '23 16:03 ericksprengel

Adding one more use case: receiving push notifications through firebase messaging (@react-native-firebase/messaging)

ericksprengel avatar Mar 08 '23 16:03 ericksprengel

@jkelley79 I'm using @react-native-firebase/messaging, MobX and Mobx state tree on top of react-native. When a firebase message comes in (at background), then the message is saved into EncryptedStorage.

mateomarconi avatar Aug 02 '23 18:08 mateomarconi