Skip to content

Cordova - Storage

Cordova applications can leverage various client-side storage mechanisms to store data locally on the device. This enables offline functionality, improves performance by caching data, and allows for saving user preferences. This tutorial focuses on localStorage, a simple key-value store, and briefly mentions other options.

localStorage is part of the Web Storage API, available in all modern web views. It allows you to store data as key-value pairs, where both keys and values are strings.

In www/index.html, create buttons to interact with localStorage and a div to display stored data or messages.

<body>
<h1>localStorage Demo</h1>
<input type="text" id="dataKey" placeholder="Enter Key (e.g., userTheme)">
<input type="text" id="dataValue" placeholder="Enter Value (e.g., dark)">
<br><br>
<button id="setItemBtn">SET Item</button>
<button id="getItemBtn">GET Item by Key</button>
<button id="removeItemBtn">REMOVE Item by Key</button>
<button id="listAllBtn">LIST All Items</button>
<button id="clearAllBtn">CLEAR All Storage</button>
<div id="storageOutput" style="margin-top: 20px; border: 1px solid #ccc; padding: 10px;">
Storage data will appear here...
</div>
<script src="cordova.js"></script>
<script src="js/index.js"></script>
</body>

In www/js/index.js, access localStorage directly. It’s available immediately and doesn’t require deviceready (though your app logic might).

// No 'deviceready' needed for localStorage itself, but good practice for app structure.
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
console.log('Device is ready. localStorage is available.');
const keyInput = document.getElementById('dataKey');
const valueInput = document.getElementById('dataValue');
const outputDiv = document.getElementById('storageOutput');
document.getElementById('setItemBtn').addEventListener('click', () => {
const key = keyInput.value.trim();
const value = valueInput.value.trim();
if (key && value) {
// For non-string data, serialize to JSON
// For this example, we assume simple strings or let users manage JSON manually.
localStorage.setItem(key, value);
outputDiv.textContent = `Item set: ${key} = ${value}`;
console.log(`localStorage.setItem: ${key} = ${value}`);
} else {
outputDiv.textContent = 'Please provide both key and value.';
}
});
document.getElementById('getItemBtn').addEventListener('click', () => {
const key = keyInput.value.trim();
if (key) {
const value = localStorage.getItem(key);
if (value !== null) {
outputDiv.textContent = `Item found: ${key} = ${value}`;
console.log(`localStorage.getItem(${key}): ${value}`);
} else {
outputDiv.textContent = `Item with key '${key}' not found.`;
console.log(`localStorage.getItem(${key}): null`);
}
} else {
outputDiv.textContent = 'Please provide a key to retrieve.';
}
});
document.getElementById('removeItemBtn').addEventListener('click', () => {
const key = keyInput.value.trim();
if (key) {
localStorage.removeItem(key);
outputDiv.textContent = `Item with key '${key}' removed (if it existed).`;
console.log(`localStorage.removeItem: ${key}`);
} else {
outputDiv.textContent = 'Please provide a key to remove.';
}
});
document.getElementById('listAllBtn').addEventListener('click', () => {
outputDiv.innerHTML = '<h3>All localStorage Items:</h3>';
if (localStorage.length === 0) {
outputDiv.innerHTML += '<p>localStorage is empty.</p>';
return;
}
const ul = document.createElement('ul');
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const value = localStorage.getItem(key);
const li = document.createElement('li');
li.textContent = `${key}: ${value}`;
ul.appendChild(li);
}
outputDiv.appendChild(ul);
console.log('localStorage contents:', localStorage);
});
document.getElementById('clearAllBtn').addEventListener('click', () => {
localStorage.clear();
outputDiv.textContent = 'All items cleared from localStorage.';
console.log('localStorage.clear() executed.');
});
}
MethodDescription
setItem(key, value)Adds or updates a key-value pair. Both key and value are converted to strings.
getItem(key)Retrieves the value associated with the key. Returns null if the key doesn’t exist.
removeItem(key)Removes the key-value pair associated with the key.
key(index)Returns the name of the key at the given integer index. The order of keys is not guaranteed and can vary between browser engines. Do not rely on this order.
length (property)Returns the number of key-value pairs stored.
clear()Removes all key-value pairs.
  • String Data Only: localStorage stores all data as strings. If you need to store objects or arrays, you must serialize them to JSON strings (e.g., using JSON.stringify()) before saving and parse them (using JSON.parse()) after retrieving.
  • Synchronous: localStorage operations are synchronous, meaning they block the main thread. For complex data or frequent operations, this can impact performance. Consider asynchronous alternatives for more demanding scenarios.
  • Storage Limits: localStorage has a storage limit, typically around 5-10MB per origin, though this can vary by browser/WebView.
  • Security: Data in localStorage is not encrypted and can be accessed by any script running on the same origin. Do not store sensitive information like passwords or tokens directly.
  • Persistence: Data in localStorage persists until explicitly cleared by the app or the user (e.g., by clearing browser data). It is not cleared if the app is updated.
  • Order of Keys: As mentioned, localStorage.key(index) does not guarantee a specific order. If order is important, manage it yourself (e.g., store an array of keys).

While localStorage is convenient for simple data, Cordova apps can also use more advanced storage solutions:

  • sessionStorage: Similar to localStorage but data is cleared when the session ends (e.g., app is closed). Not typically used for persistent data in mobile apps.
  • IndexedDB: A more powerful, asynchronous, transactional NoSQL database built into modern browsers/WebViews. Suitable for storing larger amounts of structured data. Can be complex to use directly; libraries like PouchDB or Dexie.js can simplify its usage.
  • WebSQL (Deprecated): An older API providing SQL database access. It’s deprecated and not recommended for new projects. Support is inconsistent.
  • Cordova Plugins for Storage:
    • cordova-sqlite-storage: Provides access to a native SQLite database. Excellent for relational data, large datasets, and complex queries. Operations are asynchronous.
    • cordova-plugin-nativestorage: Offers a native, asynchronous key-value store, potentially more performant or robust than localStorage for some use cases, especially on certain platforms. Useful for preferences and small data.
    • cordova-plugin-file: For storing data as files in the device’s file system. Suitable for binary data, large blobs, or user-generated files.

The best storage choice depends on your app’s needs:

  • Simple key-value pairs, small data, non-sensitive user preferences: localStorage can be sufficient.
  • Larger structured data, offline capabilities, complex queries: IndexedDB (with a helper library) or cordova-sqlite-storage.
  • Storing files (images, documents, etc.): cordova-plugin-file.
  • Improved asynchronous key-value storage: cordova-plugin-nativestorage.

For more advanced storage needs, explore the plugins mentioned and their documentation. Understanding the trade-offs between simplicity, performance, storage capacity, and data structure capabilities is key.