getDeviceId method

  1. @override
Future<String> getDeviceId()
override

Gets the current device's unique identifier.

Returns a stable UUIDv4 that uniquely identifies this app install/profile. The ID is generated once and persisted locally:

  • Mobile/Desktop: SharedPreferences
  • Web: IndexedDB → localStorage → in-memory fallback

Stability

  • Stable across app restarts
  • May reset on uninstall/reinstall (mobile/desktop)
  • May reset on "Clear site data" (web)
  • Web is best-effort (storage can be cleared/blocked)

Returns

The device ID string (UUIDv4 format).

Example

final deviceId = await deviceService.getDeviceId();
print('Device ID: $deviceId');
// Output: Device ID: 550e8400-e29b-41d4-a716-446655440000

Implementation

@override
Future<String> getDeviceId() async {
  // Return cached value if available
  if (_deviceId != null) {
    return _deviceId!;
  }

  try {
    final prefs = await SharedPreferences.getInstance();
    final storedId = prefs.getString(_kDeviceIdKey);

    if (storedId != null && storedId.isNotEmpty) {
      _deviceId = storedId;
      logd('DeviceService: Loaded existing device ID: $_deviceId');
      return _deviceId!;
    }

    // Generate new UUID
    _deviceId = _uuid.v4();
    logd('DeviceService: Generated new device ID: $_deviceId');

    // Persist the new ID
    final saved = await prefs.setString(_kDeviceIdKey, _deviceId!);
    if (!saved) {
      logw('DeviceService: Failed to persist device ID to SharedPreferences');
    }

    return _deviceId!;
  } catch (e) {
    // Fallback: generate ephemeral ID if storage fails (e.g., web with blocked storage)
    logw('DeviceService: Storage unavailable, using ephemeral device ID: $e');
    _deviceId ??= _uuid.v4();
    return _deviceId!;
  }
}