Intermediate · Networking, storage and Firebase · topic 33 of 50 · 30 min
Local storage
Explanation
Why store data on the device?
Apps should remember things: the user's language, whether they finished onboarding, a draft message, a cached product list for offline use, the login token. Storing them locally makes apps faster (no waiting for the network), usable offline, and friendlier. Different kinds of data need different tools.
| Data | Tool | Notes |
|---|---|---|
| Small settings and flags | shared_preferences | Simple key-value; not encrypted |
| Tokens, PINs, secrets | flutter_secure_storage | Uses iOS Keychain / Android secure storage |
| Lists of records with queries | sqflite (SQLite) or drift | Tables, SQL queries, transactions |
| Files: images, PDFs, exports | path_provider + dart:io | App documents or cache directories |
shared_preferences
import 'package:shared_preferences/shared_preferences.dart';
Future<void> saveLanguage(String code) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('language', code);
}
Future<String> loadLanguage() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString('language') ?? 'en'; // default when nothing is saved
}All these storage calls are asynchronous because disk access is slow compared to memory. Load settings early (for example before runApp, or in a splash screen) and keep them in your state management layer, so widgets do not wait for disk reads every time they build.
Secure storage for tokens
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
const storage = FlutterSecureStorage();
Future<void> saveToken(String token) => storage.write(key: 'auth_token', value: token);
Future<String?> readToken() => storage.read(key: 'auth_token');
Future<void> logout() => storage.delete(key: 'auth_token');SQLite for structured data
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
Future<Database> openNotesDb() async {
return openDatabase(
join(await getDatabasesPath(), 'notes.db'),
version: 1,
onCreate: (db, version) => db.execute(
'CREATE TABLE notes(id INTEGER PRIMARY KEY AUTOINCREMENT, text TEXT NOT NULL, created INTEGER NOT NULL)',
),
);
}
Future<void> addNote(Database db, String text) =>
db.insert('notes', {'text': text, 'created': DateTime.now().millisecondsSinceEpoch});
Future<List<Map<String, Object?>>> latestNotes(Database db) =>
db.query('notes', orderBy: 'created DESC', limit: 20);drift is a popular alternative built on SQLite that generates type-safe Dart code from your tables and queries, supports streams that update when data changes, and works on more platforms. It needs build_runner. For small apps sqflite is fine; for larger data layers many teams prefer drift.
On the web, sqflite is not available; drift or IndexedDB-based packages are options there.
Files with path_provider
path_provider gives platform-correct folders: getApplicationDocumentsDirectory() for files the user expects to keep, and getTemporaryDirectory() for caches the system may delete. Combine it with dart:io File to read and write (not available on the web).
Common mistakes
- Storing a login token in shared_preferences.
- Building SQL with string concatenation from user input: SQL injection risk. Use whereArgs.
- Opening the database again on every query. Open it once and reuse it.
- Forgetting that data must be migrated when the table structure changes (increase version and use onUpgrade).
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Local storage · 1/6
Choose storage by the kind of data.
Prefer a video by a teacher? Find free videos on “flutter local storage shared_preferences sqflite secure storage drift” on YouTube ↗
In real life: A notes app that works offline
A student notes app stores notes in SQLite, the chosen theme and font size in shared_preferences, and the cloud-sync login token in secure storage. Notes open instantly in a metro tunnel; the theme is applied before the first frame; and if the phone is lost, the token is not readable from plain files.
Practice (0/3 done)
Where should a login token be stored?
Which is the safe way to query a note by id in sqflite?
Build a tiny expense app: save expenses (title, amount, date) in SQLite with sqflite, show them newest first in a ListView, remember the chosen currency symbol in shared_preferences, and show the monthly total with a SQL SUM query.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Firebase in FlutterNetworking, storage and Firebase · same module
- HTTP requests and FutureBuilderNetworking, storage and Firebase · same module
- The shared responsibility modelCyber Security: from zero to SOC analyst · Cloud security basics
- Offline-first apps and DataStoreKotlin and Android App Development · Saving data and calling APIs
- The shared responsibility modelCloud Computing (AWS, Azure, Google Cloud) · What cloud computing is
- Block and file storage: EBS, instance store and EFSCloud Computing (AWS, Azure, Google Cloud) · Compute and storage: EC2 and S3
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
Is shared_preferences encrypted?
Answer: No; it is for non-sensitive settings
Use secure storage for secrets.
Which package suits a list of 5,000 transactions with queries?
Answer: sqflite or drift (SQLite)
Databases handle structured data.
Which folder may the operating system clear when space is low?
Answer: Temporary (cache) directory
Use it only for caches.
What should you do when changing a SQLite table in a released app?
Answer: Increase the version and migrate in onUpgrade
Existing users keep their data.
Who secures the physical data centre buildings?Related
Answer: The cloud provider
Physical security is always the provider's part.
Where should a login token be stored?Related
Answer: Encrypted storage backed by the Keystore
Secrets need encryption.
A company's storage bucket of invoices was left public and was downloaded by strangers. Whose responsibility was that setting?Related
Answer: The customer's
Bucket access settings are configuration, which is security IN the cloud.
Which storage loses its data when the instance is stopped?Related
Answer: Instance store
Instance store disks are physically attached to the host and are wiped on stop or terminate.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 1 more topic in “Networking, storage and Firebase” before its exam: Firebase in Flutter.
- Module 8 exam: Networking, storage and Firebase · 13 questions · 25 min, without help. 4 topics of this module still to finish first.
- Then the next module, Animations and performance. 50 topics left in the course before the final exam.