Popular Searches
Popular Course Categories
Popular Courses

SharedPreferences in Flutter

SharedPreferences in Flutter

Flutter Packages & Local Storage


SharedPreferences in Flutter


SharedPreferences is a Flutter plugin used for storing and retrieving simple key-value data persistently. It is useful when an application needs to remember small pieces of user or application preferences such as login status, theme mode, language selection, onboarding completion, settings, counters, and other simple values.


The shared_preferences package supports simple data types such as int, double, bool, String, and List. The current package also provides SharedPreferencesAsync and SharedPreferencesWithCache; the older SharedPreferences API is considered legacy for new code. :contentReference[oaicite:0]{index=0}


1. What is SharedPreferences?


SharedPreferences provides a simple persistent key-value storage mechanism. Data stored in it can remain available when the application is closed and opened again.


Simple Example


Key                 Value
--------------------------------
username            Manish
isLoggedIn          true
age                 25
theme               dark

Each value is associated with a unique key. The key is used to save, retrieve, update, or remove the corresponding value.


2. Why Use SharedPreferences?



  • Store simple application preferences.

  • Remember whether a user has completed onboarding.

  • Store login or session-related flags.

  • Save theme preferences.

  • Save language preferences.

  • Store simple counters.

  • Store small configuration values.

  • Persist simple settings between application launches.


3. How SharedPreferences Works


Flutter Application
        |
        v
shared_preferences Package
        |
        v
Key-Value Storage
        |
        v
Platform Storage
        |
        +-- Android
        +-- iOS
        +-- Web
        +-- Windows
        +-- macOS
        +-- Linux

The package provides a common Flutter API while using platform-specific persistent storage underneath. The current package supports Android, iOS, Linux, macOS, web, and Windows. :contentReference[oaicite:1]{index=1}


4. Installing SharedPreferences


Add the shared_preferences package to your Flutter project.


flutter pub add shared_preferences

Alternatively, add it manually to pubspec.yaml.


dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.5.5

The package version changes over time, so for a new project it is better to check the current package version and SDK requirements before choosing a version constraint. :contentReference[oaicite:2]{index=2}


5. Importing SharedPreferences


After installing the package, import it into the Dart file.


import 'package:shared_preferences/shared_preferences.dart';

6. Getting a SharedPreferences Instance


The legacy SharedPreferences API obtains an instance asynchronously using getInstance().


final SharedPreferences prefs =
    await SharedPreferences.getInstance();

This loads the preferences for the application. The current package documentation recommends SharedPreferencesAsync or SharedPreferencesWithCache for new code instead of the legacy API. :contentReference[oaicite:3]{index=3}


7. Saving String Data


Use setString() to store a string value.


final prefs = await SharedPreferences.getInstance();

await prefs.setString('username', 'Manish');


Reading String Data


final prefs = await SharedPreferences.getInstance();

String? username = prefs.getString('username');

print(username);


If the key does not exist, the getter returns null.


8. Saving Integer Data


Use setInt() to store an integer.


final prefs = await SharedPreferences.getInstance();

await prefs.setInt('age', 25);


Reading Integer Data


final prefs = await SharedPreferences.getInstance();

int? age = prefs.getInt('age');

print(age);


9. Saving Boolean Data


Boolean values are commonly used for flags such as login status or onboarding completion.


final prefs = await SharedPreferences.getInstance();

await prefs.setBool('isLoggedIn', true);


Reading Boolean Data


final prefs = await SharedPreferences.getInstance();

bool? isLoggedIn = prefs.getBool('isLoggedIn');

print(isLoggedIn);


10. Saving Double Data


Use setDouble() to store a decimal number.


final prefs = await SharedPreferences.getInstance();

await prefs.setDouble('price', 199.99);


Reading Double Data


final prefs = await SharedPreferences.getInstance();

double? price = prefs.getDouble('price');

print(price);


11. Saving a List of Strings


SharedPreferences also supports List.


final prefs = await SharedPreferences.getInstance();

await prefs.setStringList(
  'categories',
  ['Flutter', 'Dart', 'Firebase'],
);


Reading String List


final prefs = await SharedPreferences.getInstance();

List? categories =
    prefs.getStringList('categories');

print(categories);


12. Supported Data Types









Data TypeSave MethodRead Method
StringsetString()getString()
intsetInt()getInt()
doublesetDouble()getDouble()
boolsetBool()getBool()
ListsetStringList()getStringList()

These are the simple data types supported by the package. :contentReference[oaicite:4]{index=4}


13. Complete Save and Read Example


import 'package:shared_preferences/shared_preferences.dart';

Future saveUserData() async {
  final prefs = await SharedPreferences.getInstance();

  await prefs.setString('username', 'Manish');
  await prefs.setInt('age', 25);
  await prefs.setBool('isLoggedIn', true);
  await prefs.setDouble('score', 95.5);
}

Future readUserData() async {
  final prefs = await SharedPreferences.getInstance();

  final username = prefs.getString('username');
  final age = prefs.getInt('age');
  final isLoggedIn = prefs.getBool('isLoggedIn');
  final score = prefs.getDouble('score');

  print(username);
  print(age);
  print(isLoggedIn);
  print(score);
}


14. Updating Stored Data


Saving a value using the same key updates the existing value.


final prefs = await SharedPreferences.getInstance();

await prefs.setString('username', 'Manish');

await prefs.setString('username', 'Rahul');

final username = prefs.getString('username');

print(username);


The value associated with username is now Rahul.


15. Removing a Specific Value


Use the remove() method to delete a specific key and its stored value.


final prefs = await SharedPreferences.getInstance();

await prefs.remove('username');


Checking After Removal


final username = prefs.getString('username');

print(username);


The result will normally be null if the key no longer exists.


16. Checking Whether a Key Exists


The containsKey() method checks whether a particular key exists.


final prefs = await SharedPreferences.getInstance();

if (prefs.containsKey('username')) {
  print('Username exists');
} else {
  print('Username does not exist');
}


17. Clearing Preferences


The clear() method removes the preferences stored through the API.


final prefs = await SharedPreferences.getInstance();

await prefs.clear();


Use clear() carefully because it is much broader than removing one specific key.


18. SharedPreferences for Login Status


One common use case is remembering whether the user has logged in.


Future saveLoginStatus() async {
  final prefs = await SharedPreferences.getInstance();

  await prefs.setBool('isLoggedIn', true);
}


Checking Login Status


Future checkLoginStatus() async {
  final prefs = await SharedPreferences.getInstance();

  return prefs.getBool('isLoggedIn') ?? false;
}


19. Login and Logout Example


import 'package:shared_preferences/shared_preferences.dart';

Future login() async {
  final prefs = await SharedPreferences.getInstance();

  await prefs.setBool('isLoggedIn', true);
}

Future logout() async {
  final prefs = await SharedPreferences.getInstance();

  await prefs.setBool('isLoggedIn', false);
}

Future isUserLoggedIn() async {
  final prefs = await SharedPreferences.getInstance();

  return prefs.getBool('isLoggedIn') ?? false;
}


20. SharedPreferences for Onboarding


SharedPreferences can remember whether a user has already completed an onboarding screen.


Future completeOnboarding() async {
  final prefs = await SharedPreferences.getInstance();

  await prefs.setBool('onboardingCompleted', true);
}


Checking Onboarding Status


Future isOnboardingCompleted() async {
  final prefs = await SharedPreferences.getInstance();

  return prefs.getBool('onboardingCompleted') ?? false;
}


21. SharedPreferences for Theme Mode


An application can store whether the user selected light mode or dark mode.


Future saveDarkMode(bool value) async {
  final prefs = await SharedPreferences.getInstance();

  await prefs.setBool('darkMode', value);
}


Reading Theme Preference


Future getDarkMode() async {
  final prefs = await SharedPreferences.getInstance();

  return prefs.getBool('darkMode') ?? false;
}


22. SharedPreferences for Language Selection


Language preferences can be stored using a string.


Future saveLanguage(String language) async {
  final prefs = await SharedPreferences.getInstance();

  await prefs.setString('language', language);
}


Reading Language


Future getLanguage() async {
  final prefs = await SharedPreferences.getInstance();

  return prefs.getString('language') ?? 'English';
}


23. Complete Flutter UI Example


import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'SharedPreferences Demo',
      home: const PreferencesPage(),
    );
  }
}

class PreferencesPage extends StatefulWidget {
  const PreferencesPage({super.key});

  @override
  State createState() => _PreferencesPageState();
}

class _PreferencesPageState extends State {
  String username = '';

  @override
  void initState() {
    super.initState();
    loadUsername();
  }

  Future loadUsername() async {
    final prefs = await SharedPreferences.getInstance();

    setState(() {
      username = prefs.getString('username') ?? 'Guest';
    });
  }

  Future saveUsername() async {
    final prefs = await SharedPreferences.getInstance();

    await prefs.setString('username', 'Manish');

    await loadUsername();
  }

  Future removeUsername() async {
    final prefs = await SharedPreferences.getInstance();

    await prefs.remove('username');

    await loadUsername();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('SharedPreferences'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              'Username: $username',
              style: const TextStyle(fontSize: 20),
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: saveUsername,
              child: const Text('Save Username'),
            ),
            ElevatedButton(
              onPressed: removeUsername,
              child: const Text('Remove Username'),
            ),
          ],
        ),
      ),
    );
  }
}


24. Async Nature of SharedPreferences


Accessing the legacy SharedPreferences instance is asynchronous because the preferences need to be initialized from platform storage.


final prefs = await SharedPreferences.getInstance();

Methods such as setString(), setInt(), and setBool() return Future in the legacy API, so they can be awaited.


25. SharedPreferences vs Database


SharedPreferences is designed for simple key-value data. It is not a replacement for a relational or document database.









FeatureSharedPreferencesDatabase
Data StructureSimple key-value pairs.Structured and potentially complex data.
Best ForSettings and preferences.Large or relational application data.
QueriesVery limited.Supports database queries.
RelationshipsNot designed for relationships.Can support relationships depending on database.
Typical DataTheme, language, flags, simple settings.Users, products, orders, messages, transactions.

26. What Should Not Be Stored?


SharedPreferences is intended for simple preference data and should not be treated as a secure database or a general-purpose database.



  • Passwords.

  • Authentication secrets.

  • Private encryption keys.

  • Highly sensitive information.

  • Large amounts of application data.

  • Complex relational data.

  • Critical data that requires transactional database guarantees.


The package documentation specifically cautions that writes are not guaranteed to have been persisted to disk after returning, so it should not be used for critical data. :contentReference[oaicite:5]{index=5}


27. SharedPreferences and JSON


SharedPreferences does not directly provide a general-purpose object storage mechanism. If complex data needs to be represented as JSON, it can be converted to a string before storing it.


Example


import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';

Future saveUser() async {
  final prefs = await SharedPreferences.getInstance();

  final user = {
    'name': 'Manish',
    'age': 25,
  };

  final jsonString = jsonEncode(user);

  await prefs.setString('user', jsonString);
}


Reading JSON


Future readUser() async {
  final prefs = await SharedPreferences.getInstance();

  final jsonString = prefs.getString('user');

  if (jsonString != null) {
    final user = jsonDecode(jsonString);

    print(user['name']);
    print(user['age']);
  }
}


For complex or large application data, a dedicated database or appropriate storage solution is generally more suitable.


28. SharedPreferencesWithCache


The current shared_preferences package provides SharedPreferencesWithCache, which uses a local cache while providing asynchronous initialization. It can be useful when an application wants cached access after initialization. :contentReference[oaicite:6]{index=6}


Basic Example


final prefs = await SharedPreferencesWithCache.create(
  cacheOptions: const SharedPreferencesWithCacheOptions(),
);

await prefs.setBool('isLoggedIn', true);

final isLoggedIn = prefs.getBool('isLoggedIn');


29. SharedPreferencesAsync


SharedPreferencesAsync is another newer API provided by the package. It provides asynchronous access to preference storage without relying on the same local cache model as the legacy API.


Basic Example


final prefs = SharedPreferencesAsync();

await prefs.setBool('isLoggedIn', true);

final isLoggedIn =
    await prefs.getBool('isLoggedIn');


The current package documentation recommends considering SharedPreferencesAsync or SharedPreferencesWithCache for new code rather than the legacy SharedPreferences API. :contentReference[oaicite:7]{index=7}


30. SharedPreferences APIs Comparison







APIDescriptionRecommendation
SharedPreferencesLegacy API using a local cache after initialization.Useful for existing applications; consider migration for new code.
SharedPreferencesAsyncAsynchronous preference access.Recommended option to consider for new code.
SharedPreferencesWithCachePreference access using a managed cache.Recommended option to consider when caching is appropriate.

The package introduced the newer APIs in version 2.3.0 and documents the original SharedPreferences API as legacy. :contentReference[oaicite:8]{index=8}


31. Cache Considerations


The legacy SharedPreferences API and SharedPreferencesWithCache use a local cache. When multiple isolates or external processes modify the same preference storage, cached values can become stale unless they are refreshed appropriately. :contentReference[oaicite:9]{index=9}


32. Reloading Preferences


Existing applications using the legacy API may use reload() when they need to refresh cached values from the platform storage.


final prefs = await SharedPreferences.getInstance();

await prefs.reload();

final value = prefs.getString('username');


33. Key Naming Best Practices


Use clear and consistent names for preference keys.


Good Examples


isLoggedIn
username
darkMode
selectedLanguage
onboardingCompleted
notificationEnabled

Avoid Unclear Keys


x
data1
temp
abc

Clear key names make the code easier to understand and maintain.


34. Creating a Preferences Service


Instead of accessing SharedPreferences throughout the entire application, a dedicated service can centralize preference operations.


import 'package:shared_preferences/shared_preferences.dart';

class PreferencesService {
  Future saveUsername(String username) async {
    final prefs = await SharedPreferences.getInstance();

    await prefs.setString('username', username);
  }

  Future getUsername() async {
    final prefs = await SharedPreferences.getInstance();

    return prefs.getString('username');
  }

  Future removeUsername() async {
    final prefs = await SharedPreferences.getInstance();

    await prefs.remove('username');
  }
}


35. Using the Preferences Service


final preferences = PreferencesService();

await preferences.saveUsername('Manish');

final username =
    await preferences.getUsername();

print(username);


This approach keeps storage-related code organized and makes the application easier to maintain.


36. Practical Login Flow


Login Screen
     |
     v
User Enters Credentials
     |
     v
Authentication Successful
     |
     v
Save isLoggedIn = true
     |
     v
Open Home Screen
     |
     v
Application Restart
     |
     v
Read isLoggedIn
     |
     +---- true ----> Home Screen
     |
     +---- false ---> Login Screen

37. Practical Onboarding Flow


Application Starts
       |
       v
Read onboardingCompleted
       |
       +---- false ----> Show Onboarding
       |                       |
       |                       v
       |               Save true
       |                       |
       +-----------------------+
       |
       +---- true -----> Show Home Screen

38. Best Practices



  • Use SharedPreferences for small and simple key-value data.

  • Use meaningful key names.

  • Keep preference access centralized when the application becomes large.

  • Use await for asynchronous operations.

  • Provide default values when a key may not exist.

  • Do not store passwords or highly sensitive secrets in SharedPreferences.

  • Do not use SharedPreferences as a replacement for a database.

  • Review the current package API when starting a new project.

  • For new code, consider SharedPreferencesAsync or SharedPreferencesWithCache.

  • Test preference behavior when the application is restarted.


39. Common Mistakes










MistakeProblemBetter Approach
Storing passwordsSharedPreferences is not designed as secure secret storage.Use an appropriate secure-storage solution.
Storing large dataSharedPreferences is designed for simple preferences.Use a database or suitable storage solution.
Using unclear keysMakes maintenance difficult.Use descriptive key names.
Forgetting awaitCan cause asynchronous operations to be handled incorrectly.Await asynchronous methods.
Using clear() unnecessarilyCan remove more preferences than intended.Use remove() for a specific key.
Ignoring cache behaviorValues can become stale in certain multi-isolate or external-update scenarios.Choose the appropriate current API and refresh strategy.

40. Interview Questions


Q1. What is SharedPreferences in Flutter?


SharedPreferences is a plugin for storing and retrieving simple key-value data persistently.


Q2. What data types can SharedPreferences store?


It supports int, double, bool, String, and List. :contentReference[oaicite:10]{index=10}


Q3. How do you install SharedPreferences?


flutter pub add shared_preferences

Q4. How do you get a SharedPreferences instance?


final prefs = await SharedPreferences.getInstance();

Q5. How do you store a string?


await prefs.setString('username', 'Manish');

Q6. How do you retrieve a string?


final username = prefs.getString('username');

Q7. How do you remove a value?


await prefs.remove('username');

Q8. How do you clear stored preferences?


await prefs.clear();

Q9. Can SharedPreferences store objects directly?


No. The standard supported values are simple primitive types and List. Complex objects need to be transformed into a supported representation, such as a JSON string, or stored using a more appropriate database or storage solution. :contentReference[oaicite:11]{index=11}


Q10. Is SharedPreferences suitable for passwords?


No. SharedPreferences is intended for simple preferences and should not be treated as secure storage for sensitive secrets.


Q11. What is SharedPreferencesAsync?


SharedPreferencesAsync is a newer API in the shared_preferences package that provides asynchronous access to preference storage.


Q12. Which API should new applications consider?


The current package documentation recommends considering SharedPreferencesAsync or SharedPreferencesWithCache for new code instead of the legacy SharedPreferences API. :contentReference[oaicite:12]{index=12}


41. Summary



  • SharedPreferences is used for simple persistent key-value storage.

  • The package can store strings, integers, doubles, booleans, and string lists.

  • The package can be added using flutter pub add shared_preferences.

  • The legacy API uses SharedPreferences.getInstance().

  • setString(), setInt(), setDouble(), setBool(), and setStringList() save data.

  • getString(), getInt(), getDouble(), getBool(), and getStringList() retrieve data.

  • remove() deletes a specific preference.

  • clear() removes stored preferences.

  • SharedPreferences is useful for settings, flags, onboarding status, and simple preferences.

  • It should not be used as a secure storage mechanism for passwords or sensitive secrets.

  • It should not replace a database for large or complex application data.

  • The current package provides SharedPreferencesAsync and SharedPreferencesWithCache for newer usage patterns.


Learn Flutter


JustAcademy Flutter Training Course


Register for Flutter Course Demo


whatsapp