Scanning database...
Tools
Articles

No matches found for ""

View All Results
Home Dev Lab flutter
Developer Lab

UUID in Flutter

Production-ready implementation guide with CSPRNG-backed code snippets.



Generate UUID in Flutter

Flutter uses the same Dart uuid package — works identically on iOS, Android, Web, and Desktop. One package, one API, all platforms. No native code, no platform channels.

Quick Reference

Method Version Sortable Use Case
uuid.v4() v4 No Widget keys, model IDs, session tokens
uuid.v7() v7 Yes Local DB PKs (Hive, SQFlite, Isar)
uuid.v5() v5 No Deterministic — deduplication, content IDs

Primary Implementation

Production Ready
dart snippet
import 'package:uuid/uuid.dart';

// Declare once at the top level — reuse everywhere
const _uuid = Uuid();

// UUID v4 — random, CSPRNG-backed, works on all Flutter platforms
final id = _uuid.v4();
print(id);
// → f47ac10b-58cc-4372-a567-0e02b2c3d479

// UUID v7 — time-ordered, great for local database PKs
final idV7 = _uuid.v7();

// Generate multiple
final ids = List.generate(5, (_) => _uuid.v4());

All UUID Versions

UUID v4 — Random (recommended default)

dart snippet
import 'package:uuid/uuid.dart';

const uuid = Uuid();
final id = uuid.v4();
print(id); // → "550e8400-e29b-41d4-a716-446655440000"

Flutter model with UUID — Hive local database

dart snippet
import 'package:hive/hive.dart';
import 'package:uuid/uuid.dart';

const _uuid = Uuid();

part 'note.g.dart';

@HiveType(typeId: 0)
class Note extends HiveObject {
  @HiveField(0)
  final String id;

  @HiveField(1)
  String title;

  @HiveField(2)
  String content;

  Note({
    String? id,
    required this.title,
    required this.content,
  }) : id = id ?? _uuid.v4();
}

SQFlite — UUID primary key

dart snippet
import 'package:sqflite/sqflite.dart';
import 'package:uuid/uuid.dart';

const _uuid = Uuid();

Future<void> createTable(Database db) async {
  await db.execute('''
    CREATE TABLE IF NOT EXISTS tasks (
      id TEXT PRIMARY KEY,
      title TEXT NOT NULL,
      completed INTEGER NOT NULL DEFAULT 0
    )
  ''');
}

Future<String> insertTask(Database db, String title) async {
  final id = _uuid.v4();
  await db.insert('tasks', {'id': id, 'title': title, 'completed': 0});
  return id;
}

Real-World Use Cases

1. ListView with stable item keys

dart snippet
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';

const _uuid = Uuid();

class TodoItem {
  final String id;
  final String text;
  bool done;

  TodoItem(this.text) : id = _uuid.v4(), done = false;
}

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

  @override
  State<TodoList> createState() => _TodoListState();
}

class _TodoListState extends State<TodoList> {
  final List<TodoItem> _items = [];

  void _addItem(String text) {
    setState(() => _items.add(TodoItem(text)));
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: _items.length,
      itemBuilder: (context, index) {
        final item = _items[index];
        return ListTile(
          key: ValueKey(item.id), // UUID as stable widget key
          title: Text(item.text),
        );
      },
    );
  }
}

2. Riverpod state management — UUID entity IDs

dart snippet
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:uuid/uuid.dart';

const _uuid = Uuid();

class Note {
  final String id;
  final String content;
  const Note({required this.id, required this.content});
}

class NotesNotifier extends StateNotifier<List<Note>> {
  NotesNotifier() : super([]);

  void add(String content) {
    state = [...state, Note(id: _uuid.v4(), content: content)];
  }

  void remove(String id) {
    state = state.where((n) => n.id != id).toList();
  }
}

final notesProvider = StateNotifierProvider<NotesNotifier, List<Note>>(
  (ref) => NotesNotifier(),
);

3. Offline-first sync — generate IDs before server confirmation

dart snippet
import 'package:uuid/uuid.dart';

const _uuid = Uuid();

class SyncService {
  // Generate UUID locally — works offline
  // When connectivity returns, sync to server using the same UUID
  Future<String> createRecord(Map<String, dynamic> data) async {
    final id = _uuid.v4();
    data['id'] = id;

    // Save locally first
    await localDb.insert(data);

    // Queue for sync when online
    await syncQueue.add({'id': id, 'data': data, 'action': 'create'});

    return id; // Return immediately — no server round-trip needed
  }
}

Common Mistakes

Calling Uuid().v4() inside a build() method

Generating a UUID inside build() creates a new ID on every rebuild, breaking widget identity and causing unnecessary re-renders. Always generate UUIDs in model constructors or state initialization.

Not using ValueKey(item.id) in list widgets

Without a stable key, Flutter's diffing algorithm can't track items correctly when the list changes. Use key: ValueKey(item.id) in ListView.builder and AnimatedList for correct animations and state preservation.

Creating a new Uuid() instance on every call

Declare const _uuid = Uuid() once at the top of your file or as a static field. The instance is stateless and safe to reuse — creating a new one each time is unnecessary overhead.

How It Works

The uuid package is pure Dart — no native code, no platform channels. It uses dart:math's Random.secure() which maps to the OS CSPRNG on every Flutter platform.

This means the same code works identically on iOS, Android, Web (using crypto.getRandomValues), macOS, Windows, and Linux — no conditional imports needed.

Output Example

uuid.v4()

f47ac10b-58cc-4372-a567-0e02b2c3d479

uuid.v7() — time-ordered

018e8f6a-1b2c-7d3e-9f4a-5b6c7d8e9f0a

Best Practices

Generate UUIDs in model constructors, not in build() methods.

Use ValueKey(item.id) in list widgets for correct diffing and animations.

Use uuid.v7() for local database PKs — sequential inserts are faster in B-tree indexes.

Performance

UUID generation is negligible overhead in Flutter. The pure-Dart implementation runs in AOT-compiled code with no native bridge latency.

Generating UUIDs for list items, form fields, or local DB records has zero measurable impact on frame rate or UI responsiveness.

Installation

flutter pub add uuid

Works on Flutter 3.0+ (Dart 2.17+). No native linking, no pod install, no Android Gradle changes needed.

Security

Entropy source: Random.secure() — OS CSPRNG on all platforms. iOS: SecRandomCopyBytes. Android: SecureRandom. Web: crypto.getRandomValues.

Cryptographically secure on all Flutter platforms. Suitable for session tokens, device IDs, and API keys.