What Are My Options for Storing Data When Using React Native? (iOS and Android)

What are my options for storing data when using React Native? (iOS and Android)

Here's what I've learned as I determine the best way to move forward with a couple of my current app projects.

Async Storage (formerly "built-in" to React Native, now moved on its own)

I use AsyncStorage for an in-production app. Storage stays local to the device, is unencrypted (as mentioned in another answer), goes away if you delete the app, but should be saved as part of your device's backups and persists during upgrades (both native upgrades ala TestFlight and code upgrades via CodePush).

Conclusion: Local storage; you provide your own sync/backup solution.

SQLite

Other projects I have worked on have used sqlite3 for app storage. This gives you an SQL-like experience, with compressible databases that can also be transmitted to and from the device. I have not had any experience with syncing them to a back end, but I imagine various libraries exist. There are RN libraries for connecting to SQLite.

Data is stored in your traditional database format with databases, tables, keys, indices, etc. all saved to disk in a binary format. Direct access to the data is available via command line or apps that have SQLite drivers.

Conclusion: Local storage; you supply the sync and backup.

Firebase

Firebase offers, among other things, a real time noSQL database along with a JSON document store (like MongoDB) meant for keeping from 1 to n number of clients synchronized. The docs talk about offline persistence, but only for native code (Swift/Obj-C, Java). Google's own JavaScript option ("Web") which is used by React Native does not provide a cached storage option (see 2/18 update below). The library is written with the assumption that a web browser is going to be connecting, and so there will be a semi-persistent connection. You could probably write a local caching mechanism to supplement the Firebase storage calls, or you could write a bridge between the native libraries and React Native.

Update 2/2018
I have since found React Native Firebase which provides a compatible JavaScript interface to the native iOS and Android libraries (doing what Google probably could/should have done), giving you all the goodies of the native libraries with the bonus of React Native support. With Google's introduction of a JSON document store beside the real-time database, I'm giving Firebase a good second look for some real-time apps I plan to build.

The real-time database is stored as a JSON-like tree that you can edit on the website and import/export pretty simply.

Conclusion: With react-native-firebase, RN gets same benefits as Swift and Java. [/update] Scales well for network-connected devices. Low cost for low utilization. Combines nicely with other Google cloud offerings. Data readily visible and editable from their interface.

Realm

Update 4/2020
MongoDB has acquired Realm and is planning to combine it with MongoDB Stitch (discussed below). This looks very exciting.

Update 9/2020
Having used Realm vs. Stitch:
Stitch API's essentially allowed a JS app (React Native or web) to talk directly to the Mongo database instead of going through an API server you build yourself.

Realm was meant to synchronize portions of the database whenever changes were made.

The combination of the two gets a little confusing. The formerly-known-as-Stitch API's still work like your traditional Mongo query and update calls, whereas the newer Realm stuff attaches to objects in code and handles synchronization all by itself... mostly. I'm still working through the right way to do things in one project, which is using SwiftUI, so it's a bit off-topic. But promising and neat nonetheless.


Also a real time object store with automagic network synchronization. They tout themselves as "device first" and the demo video shows how the devices handle sporadic or lossy network connectivity.

They offer a free version of the object store that you host on your own servers or in a cloud solution like AWS or Azure. You can also create in-memory stores that do not persist with the device, device-only stores that do not sync up with the server, read-only server stores, and the full read-write option for synchronization across one or more devices. They have professional and enterprise options that cost more up front per month than Firebase.

Unlike Firebase, all Realm capabilities are supported in React Native and Xamarin, just as they are in Swift/ObjC/Java (native) apps.

Your data is tied to objects in your code. Because they are defined objects, you do have a schema, and version control is a must for code sanity. Direct access is available via GUI tools Realm provides. On-device data files are cross-platform compatible.

Conclusion: Device first, optional synchronization with free and paid plans. All features supported in React Native. Horizontal scaling more expensive than Firebase.

iCloud

I honestly haven't done a lot of playing with this one, but will be doing so in the near future.

If you have a native app that uses CloudKit, you can use CloudKit JS to connect to your app's containers from a web app (or, in our case, React Native). In this scenario, you would probably have a native iOS app and a React Native Android app.

Like Realm, this stores data locally and syncs it to iCloud when possible. There are public stores for your app and private stores for each customer. Customers can even chose to share some of their stores or objects with other users.

I do not know how easy it is to access the raw data; the schemas can be set up on Apple's site.

Conclusion: Great for Apple-targeted apps.

Couchbase

Big name, lots of big companies behind it. There's a Community Edition and Enterprise Edition with the standard support costs.

They've got a tutorial on their site for hooking things up to React Native. I also haven't spent much time on this one, but it looks to be a viable alternative to Realm in terms of functionality. I don't know how easy it is to get to your data outside of your app or any APIs you build.

[Edit: Found an older link that talks about Couchbase and CouchDB, and CouchDB may be yet another option to consider. The two are historically related but presently completely different products. See this comparison.]

Conclusion: Looks to have similar capabilities as Realm. Can be device-only or synced. I need to try it out.

MongoDB

Update 4/2020

Mongo acquired Realm and plans to combine MongoDB Stitch (discussed below) with Realm (discussed above).


I'm using this server side for a piece of the app that uses AsyncStorage locally. I like that everything is stored as JSON objects, making transmission to the client devices very straightforward. In my use case, it's used as a cache between an upstream provider of TV guide data and my client devices.

There is no hard structure to the data, like a schema, so every object is stored as a "document" that is easily searchable, filterable, etc. Similar JSON objects could have additional (but different) attributes or child objects, allowing for a lot of flexibility in how you structure your objects/data.

I have not tried any client to server synchronization features, nor have I used it embedded. React Native code for MongoDB does exist.

Conclusion: Local only NoSQL solution, no obvious sync option like Realm or Firebase.

Update 2/2019

MongoDB has a "product" (or service) called Stitch. Since clients (in the sense of web browsers and phones) shouldn't be talking to MongoDB directly (that's done by code on your server), they created a serverless front-end that your apps can interface with, should you choose to use their hosted solution (Atlas). Their documentation makes it appear that there is a possible sync option.

This writeup from Dec 2018 discusses using React Native, Stitch, and MongoDB in a sample app, with other samples linked in the document (https://www.mongodb.com/blog/post/building-ios-and-android-apps-with-the-mongodb-stitch-react-native-sdk).

Twilio Sync

Another NoSQL option for synchronization is Twilio's Sync. From their site:
"Sync lets you manage state across any number of devices in real time at scale without having to handle any backend infrastructure."

I looked at this as an alternative to Firebase for one of the aforementioned projects, especially after talking to both teams. I also like their other communications tools, and have used them for texting updates from a simple web app.


[Edit] I've spent some time with Realm since I originally wrote this. I like how I don't have to write an API to sync the data between the app and the server, similar to Firebase. Serverless functions also look to be really helpful with these two, limiting the amount of backend code I have to write.

I love the flexibility of the MongoDB data store, so that is becoming my choice for the server side of web-based and other connection-required apps.

I found RESTHeart, which creates a very simple, scalable RESTful API to MongoDB. It shouldn't be too hard to build a React (Native) component that reads and writes JSON objects to RESTHeart, which in turn passes them to/from MongoDB.


[Edit] I added info about how the data is stored. Sometimes it's important to know how much work you might be in for during development and testing if you've got to tweak and test the data.


Edits 2/2019 I experimented with several of these options when designing a high-concurrency project this past year (2018). Some of them mention hard and soft concurrency limits in their documentation (Firebase had a hard one at 10,000 connections, I believe, while Twilio's was a soft limit that could be bumped, according to discussions with both teams at AltConf).

If you are designing an app for tens to hundreds of thousands of users, be prepared to scale the data backend accordingly.

Storing big data on a mobile device, iOS and Android, with react native and expo SQLite


1) Storing large data on a react native app

Redux-persist and SQLite are not ideal ways to store large data on mobile devices. You can store your data on the application storage managed by the relevant OS. You can use Documents or /Library/Caches or tmp directories on iOS and external storage or external sd card on Android. You will need read-write permissions on Android, you can use react-native-permissions to handle it. react-native-fs is a good library to save, read or delete files.

2) Deleting data

If you store a binary or text in your database when you delete that record, it will reduce your database size. But if you store your file in the documents folder and add a reference to your database, deleting this reference won't remove the actual file from the device. You need to do this yourself.

3) SQLite limitations

I assume you are storing binaries. Regardless of the data type, there is a limit for SQLite Text type which is 2 GB. You can see more info here

4) Suggestions

I would prefer storing data in local storage as explained above and keep the references in Async Storage managed by redux-persist or a local SQLite database.

Where to store data locally to be persistent and safe using React Native without using cloud services?

You have tried realm which is a very good option for storing encrypted data. But if you want storage like async-storage with encryption you can use:-
https://www.npmjs.com/package/react-native-sensitive-info (this is what I used for my project)
It is supportable for both the platforms and if you are using expo then by default expo provide SecureStore (https://docs.expo.io/versions/latest/sdk/securestore/).

You can also check Encrypting sensivite data in React Native and Expo

data persistence: see react-native-sensitive-info will store data in Android Shared Preferences, iOS Keychain and Windows Credentials and it will be available even if you close/restart the app. It will get removed when you clear the storage of your app.

Security: For sure it will store data securely as they have mentioned on npm website and we used this package for that purpose only instead of async-storage to get clearance from the security team of my company.

How to store local private user data with React Native app?

I had a similar case and i went for realm.js .

React Native ToDo app: Storing ToDo items locally on Android

Check out React Native Async Storage

How to store data in local storage with react native?

Async Storage can only store string data, so in order to store object data you need to serialize it first. For data that can be serialized to JSON you can use JSON.stringify() when saving the data and JSON.parse() when loading the data.

import AsyncStorage from '@react-native-community/async-storage';

Storing string value

const storeData = async (value) => {
try {
await AsyncStorage.setItem('@storage_Key', value)
} catch (e) {
// saving error
}
}

Sorting Object Value

const storeData = async (value) => {
try {
const jsonValue = JSON.stringify(value)
await AsyncStorage.setItem('@storage_Key', jsonValue)
} catch (e) {
// saving error
}
}

Reading String Value

const getData = async () => {
try {
const value = await AsyncStorage.getItem('@storage_Key')
if(value !== null) {
// value previously stored
}
} catch(e) {
// error reading value
}
}

Reading Object Value

const getData = async () => {
try {
const jsonValue = await AsyncStorage.getItem('@storage_Key')
return jsonValue != null ? JSON.parse(jsonValue) : null;
} catch(e) {
// error reading value
}
}


Related Topics



Leave a reply



Submit