Storing Data with Ionic Storage
Let’s say you’ve created an Ionic application where users can create shopping lists. A user downloads your application, spends 5 minutes adding their list and then closes the application… and all their data is gone.
Quite often when creating mobile applications you will want to store data that the user can retrieve later. A lot of the time this is done by storing the data somewhere that can be accessed through a remote server (think Facebook, Twitter, etc.) which would require an Internet connection and fetching the data remotely (which we will discuss in the next lesson). In many cases though, we may also want to store some data locally on the device itself.
There are a few reasons we might want to store some data locally:
- The application is completely self-contained and there is no interaction with other users, so all data can be stored locally
- We need to store data locally for some specific functionality like remembering logged in users
- We could skip unnecessary calls to a server by storing preference settings locally
- We could skip unnecessary calls to a server by caching other data locally
- We want to sync online and offline data so that the user can continue using the application even when they are offline (Evernote is a good example of this)
Ionic applications run in a browser, so we don’t have access to the storage options that native applications do. We do still have access to the usual browser storage options that websites have access to though like Local Storage and IndexedDB. These options might not always be ideal (for reasons I will cover shortly), but we can also access native data storage by using Capacitor which can overcome the shortfalls of browser-based data storage. However, native storage options are only available when your app is built natively for iOS and Android, if you are building a PWA then you will only be able to rely on browser storage.
There are plenty of different options out there for storing data locally, but we are going to focus on the main ones when it comes to Ionic applications.
Local Storage
This is the most basic storage option available, which allows you to store up to 5MB worth of data in the user’s browser. Remember, Ionic applications technically run inside of an embedded browser even when they are built as iOS or Android applications.
Local storage gets a bit of a bad rap and is generally considered to be unreliable. I think the browser’s local storage can be a viable option and it is reasonably stable and reliable, but, it is possible for the data to be wiped, which means for a lot of applications it’s not going to be a great option. Even if it worked 99% of the time, that’s still not good enough for storing most types of data.
In general, you should only use it where data loss would not be an issue, and it shouldn’t ever be used to store sensitive data (like a password). This doesn’t mean that local storage is insecure - you could for example store an authentication token like a JWT (JSON Web Token) in local storage which is a common practice. It is not easy for an attacker to steal data from local storage, but, if your application did become vulnerable to something like an XSS attack data store in local storage could potentially be stolen, so this needs to be taken into consideration. My general stance is that nobody except experts should be handling authentication/security issues like this anyway - if you need authentication/authorisation in your application you should use some kind of authentication service that handles it for you.
A JWT is a good example of the type of thing that suits being stored in local storage. This would allow you to tell if a user was already logged in or not, but if the data is lost it’s not really a big deal because the user will just need to enter in their username and password again to re-authenticate.
If you are just using local storage to cache data from a server it would also not be a big issue if the data is lost since it can just be fetched from the server again. Local storage is also great to use when we are just learning and building practice applications or prototypes because we don’t really care if the data gets wiped.
If you were storing all of a user’s notes in local storage and local storage gets wiped… not so good.
Local Storage is a simple key-value system, and can be accessed through the globally available localStorage
object:
localStorage.setItem('someSetting', 'off');
const someSetting = localStorage.getItem('someSetting');
This is the native (as in native to web browsers, not iOS or Android native) way to set and retrieve local storage data. We won’t be accessing local storage this way in Ionic applications.
SQLite
SQLite is basically an embedded SQL database that can run on a mobile device. Unlike a normal SQL database, it does not need to run on a server and does not require any configuration. SQLite can be utilised by both iOS and Android applications (as well as others), but the SQLite database can only be accessed natively, so it is not accessible by default to browser based mobile apps.
We can, however, use Capacitor to easily gain access to this functionality. You would just need to add the SQLite plugin and driver to your project:
npm install cordova-sqlite-storage
npm install localforage-cordovasqlitedriver
The IonicStorageModule
also needs to be configured to use this driver:
import { Drivers } from '@ionic/storage';
import { IonicStorageModule } from '@ionic/storage-angular';
import * as CordovaSQLiteDriver from 'localforage-cordovasqlitedriver';
@NgModule({
imports: [
// ...,
IonicStorageModule.forRoot({
driverOrder: [CordovaSQLiteDriver._driver, Drivers.IndexedDB, Drivers.LocalStorage]
})
],
// ...
})
export class AppModule { }
and then when we use the storage instance, we need to call the defineDriver
method:
import * as CordovaSQLiteDriver from 'localforage-cordovasqlitedriver'
await this.storage.defineDriver(CordovaSQLiteDriver);
We will implement this step-by-step in an application later, so don’t worry if it all looks a bit confusing right now.
The main benefits of using SQLite are that it: