Storage Options
When evaluating storage options for React Native, you will want to consider a few things first:
- Size of data you need to store.
- What type of data are you storing?
- PII data? That should be securely stored.
- Passwords, tokens? That too.
- Sensitive user info like health? Credit cards? Ditto.
- Do you need to account for rooted (Android) or jailbroken (iOS) devices?
- Does this data need to persist on device?
- Do you also want to sync this to the cloud?
- Do you need to be able to export this data?
So you’ve answered those questions (and possibly a few more) and are now looking for the right modules to fill your needs. I’ve done quite a bit of reading and these are the best summaries I’ve seen of existing solutions:
You’ll read through those and see that it’s not very comprehensive. In fact, many of those questions are let unanswered. However, you’ll find places to start digging and will have to evaluate everything to see what fits best. The choices are many which is great; you’ll eventually find the perfect fit. But this is also one of the downsides to the React Native ecosystem: The Paradox of Choice
Taking the time to familiarize yourself with the abundance of choices out there will suck up a lot of time that soloprenuers simply don’t have to spare (ultimately, this is what killed my own 1 year venture into the startup world). So to help with that, I’ll be trying my best to keep this wiki page up to date with the available options for each overarching category of modules you may need when developing a mobile app in React Native. I’ll add more in-depth pages for any modules I use in a project, but for others, the best I can promise is to source the bits of information I run into. First up, Storage.
Options
Component State
Redux
Async Storage
Considerations
- Space limitations are:
- React Native recommends using an abstraction layer on top of this for anything other than light usage since it operates globally.
- Backend implementation:
- iOS: Native code that stores small values in a serialized dictionary and larger values in separate files.
- Android: Uses RocksDB or SQLite underneath depending on what is available according to the source code comments.
- This is secure for non-rooted / non-jailbroken devices as:
- For Android: Just like files that you save on the device’s internal storage, Android stores your database in private disk space that’s associated application. Your data is secure, because by default this area is not accessible to other applications.
- For iOS: Every App Is an Island An iOS app’s interactions with the file system are limited mostly to the directories inside the app’s sandbox. During installation of a new app, the installer creates a number of containers for the app. Each container has a specific role. The bundle container holds the app’s bundle, whereas the data container holds data for both the application and the user. The data container is further divided into a number of directories that the app can use to sort and organize its data. The app may also request access to additional containers—for example, the iCloud container—at runtime.
- However, if the device cannot properly safeguard app data, then it is not secure.
SQLite
- On how to accomplish this on React Native:
react-native-sqlite-storage
This is the current most recommended module.
Considerations
Troubleshooting
Sharing storage connection between components?
https://stackoverflow.com/questions/37342528/reactnative-best-approach-to-share-a-sqlite-instance-across-all-components-and
react-native-sqlite-2
react-native-sqlite
Firebase
Realm
iCloud
Couchbase
MongoDB
GraphQL
redux-persist
Key Features
- Allows you to persist redux state data in a storage engine of your choice.
- Since v5, allows you to persist to nested storage engines. This means you can do neat things like persist to Async Storage but also blacklist keys with sensitive data and have them persist instead to a more secure storage.
Considerations
- It is only as secure as the storage engine you use.
- It’s ability to handle large datasets is very dependent on how you organize your state and your choice of storage.
redux-persist-filesystem-storage
Key Features
redux-persist-sensitive-storage
This is a plugin for redux-persist that lets you use react-native-sensitive-info for storage.
This is a plugin for redux-persist that automatically encrypts the data in your redux store that is being persisted using the given secret key (from the code).
Note: This is good but not perfect. A better solution would be to use a secret key from KeyChain (iOS) / KeyStore (Android), so it’s not stored in the JS bundle on device. An implementation is being worked on but it’s not released yet.
redux-offline
This uses redux-persist for it’s storage so everything that applies to that, applies here.
react-native-keychain
Key Features
- Keychain Access for React Native. Currently functionality is limited to just storing internet and generic passwords.
- From v2.0.0 and on: The KeychainModule will now automatically use the appropriate CipherStorage implementation based on API level.
- Encrypted data is stored in SharedPreferences.
react-native-sensitive-info
Key Features
- Manages all data stored in Android Shared Preferences and iOS Keychain. You can set and get all key/value using simple methods.
- Since v5.0.0 on the keystore branch, the module has support for Android Keystore security.
Considerations
react-native-shared-preferences
https://github.com/sriraman/react-native-shared-preferences
Fork for: https://github.com/rt2zz/redux-persist/issues/185#issuecomment-277128378
https://github.com/nhayfield/react-native-shared-preferences
react-native-fetch-blob
Key Features
- A project committed to making file access and data transfer easier and more efficient for React Native developers.
react-native-fs
react-native-get-shared-prefs
This has been replaced by react-native-sensitive-info.
react-native-redux-secure-storage
Unreleased project that should be an improvement on redux-persist-transform-encrypt.
rxdb
Expo
Native linking is required more many of the different storage options, but Expo does not allow that. So instead, many storage options are built-in. These are some of the options available.
SecureStore
Debugging Tips
Example Use Cases
redux-persist + redux-persist-sensitive-storage + react-native-sensitive-info (keystore) + react-native-sqlite-storage + SQLCipher fork
- Size of data you need to store.
- Automatic and manually entered log entries so this can potentially grow to be very large.
- What type of data are you storing?
- PII type data so it needs to be securely stored.
- Do you need to account for rooted (Android) or jailbroken (iOS) devices?
- No, we’ll warn the user about this but this would be outside the scope of the project.
- Does this data need to persist on device?
- Yes, as this is intended to be offline usable in many cases.
- Do you also want to sync this to the cloud?
- Possibly, but if we do, then it would be a self-hosted option first, so technical expertise would be required. That means we don’t need anything seamless or automatic.
- Do you need to be able to export this data?
The why for each module:
- redux-persist will allow me to persist data from redux easily.
- redux-persist-sensitive-storage + react-native-sensitive-info (keystore) will allow me to store sensitive app data securely.
- react-native-sqlite-storage + SQLCipher fork will allow me to securely store the large amount of PII log data that I plan to allow users to export and cloud sync.
Copyright © 2011-2020
Ho Yin Cheng