> For the complete documentation index, see [llms.txt](https://flutteruniversity.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://flutteruniversity.gitbook.io/docs/learn-flutter/intermediate/persistence.md).

# Persistence

Data persistence is crucial for maintaining data across app launches. Flutter offers several options for data persistence, and one of the most common is using the `shared_preferences` package for storing simple data, and the `sqflite` package for more complex or structured data.

## 1. Shared Preferences 🔄

For simple data storage, `shared_preferences` is a great choice. It allows you to store simple data in key-value pairs.

### Setup:

Add the `shared_preferences` package to your `pubspec.yaml` file:

```yaml
dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.2.2
```

### Usage:

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

Future<void> saveName() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  await prefs.setString('name', 'John Doe');
}

Future<String?> getName() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  return prefs.getString('name');
}
```

## 2. SQLite with sqflite 🗄️

For more structured data, you might want to use a local database such as SQLite.

### Setup:

Add the `sqflite` and `path_provider` packages to your `pubspec.yaml` file:

```yaml
dependencies:
  flutter:
    sdk: flutter
  sqflite: ^2.3.0
  path_provider: ^2.1.1
```

### Usage:

```dart
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';

Future<Database> getDatabase() async {
  final directory = await getApplicationDocumentsDirectory();
  final path = directory.path + 'app.db';
  return openDatabase(
    path,
    version: 1,
    onCreate: (db, version) {
      db.execute('CREATE TABLE Users(id INTEGER PRIMARY KEY, name TEXT)');
    },
  );
}

Future<void> addUser(String name) async {
  final db = await getDatabase();
  await db.insert('Users', {'name': name});
}

Future<List<Map<String, dynamic>>> getUsers() async {
  final db = await getDatabase();
  return db.query('Users');
}
```

***

## Complete Example Code 📜

Here's a simple example demonstrating how to use `sqflite` or `shared_preference` for data persistence in Flutter:

{% tabs %}
{% tab title="shared\_preferences" %}

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SharedPreferencesExample(),
    );
  }
}

class SharedPreferencesExample extends StatefulWidget {
  @override
  _SharedPreferencesExampleState createState() => _SharedPreferencesExampleState();
}

class _SharedPreferencesExampleState extends State<SharedPreferencesExample> {
  final _nameController = TextEditingController();
  String _name = '';

  Future<void> _saveName() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setString('name', _nameController.text);
  }

  Future<void> _loadName() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      _name = prefs.getString('name') ?? 'No name saved';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Shared Preferences Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: <Widget>[
            TextField(
              controller: _nameController,
              decoration: InputDecoration(labelText: 'Name'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _saveName,
              child: Text('Save Name'),
            ),
            ElevatedButton(
              onPressed: _loadName,
              child: Text('Load Name'),
            ),
            SizedBox(height: 20),
            Text('Saved Name: $_name'),
          ],
        ),
      ),
    );
  }
}
```

{% endtab %}

{% tab title="sqflite" %}

```dart
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SQLiteExample(),
    );
  }
}

class SQLiteExample extends StatefulWidget {
  @override
  _SQLiteExampleState createState() => _SQLiteExampleState();
}

class _SQLiteExampleState extends State<SQLiteExample> {
  final _nameController = TextEditingController();
  Database? _database;
  List<Map<String, dynamic>> _users = [];

  Future<void> _initDatabase() async {
    final directory = await getApplicationDocumentsDirectory();
    final path = directory.path + 'app.db';
    _database = await openDatabase(
      path,
      version: 1,
      onCreate: (db, version) {
        return db.execute('CREATE TABLE Users(id INTEGER PRIMARY KEY, name TEXT)');
      },
    );
  }

  Future<void> _addUser() async {
    await _database?.insert('Users', {'name': _nameController.text});
    _loadUsers();
  }

  Future<void> _loadUsers() async {
    final users = await _database?.query('Users');
    setState(() {
      _users = users ?? [];
    });
  }

  @override
  void initState() {
    super.initState();
    _initDatabase().then((_) => _loadUsers());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('SQLite Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: <Widget>[
            TextField(
              controller: _nameController,
              decoration: InputDecoration(labelText: 'Name'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _addUser,
              child: Text('Add User'),
            ),
            Expanded(
              child: ListView.builder(
                itemCount: _users.length,
                itemBuilder: (context, index) {
                  final user = _users[index];
                  return ListTile(
                    title: Text(user['name'] ?? ''),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

```

{% endtab %}
{% endtabs %}

***

## Assignments 📝

* [ ] Create an app that uses `shared_preferences` to save and load a user's name.
* [ ] Create an app that uses `sqflite` to save, load, and display a list of users.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://flutteruniversity.gitbook.io/docs/learn-flutter/intermediate/persistence.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
