If you're serving ads you can use ASIdentifierManager. You should only use it for ads. There is no general UDID mechanism provided by the OS on iOS, for privacy reasons.
If you're using firebase_auth plugin you could signInAnonymously and then use the id of the FirebaseUser. This will give you an identifier that is specific to your Firebase app.
I just published a plugin to provide a solution to your problem.
It uses Settings.Secure.ANDROID_ID for Android and relies on identifierForVendor and the keychain for iOS to make the behaviour equivalent to Android's.
Here's the link.
Update 1/3/2021: The recommended way is now the extended community plugin called device_info_plus. It supports more platforms than device_info and aims to support all that are supported by flutter. Here is an example usage:
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:device_info_plus/device_info_plus.dart';
import 'dart:io';
Future<String> getDeviceIdentifier() async {
String deviceIdentifier = "unknown";
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
if (Platform.isAndroid) {
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
deviceIdentifier = androidInfo.androidId;
} else if (Platform.isIOS) {
IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
deviceIdentifier = iosInfo.identifierForVendor;
} else if (kIsWeb) {
// The web doesnt have a device UID, so use a combination fingerprint as an example
WebBrowserInfo webInfo = await deviceInfo.webBrowserInfo;
deviceIdentifier = webInfo.vendor + webInfo.userAgent + webInfo.hardwareConcurrency.toString();
} else if (Platform.isLinux) {
LinuxDeviceInfo linuxInfo = await deviceInfo.linuxInfo;
deviceIdentifier = linuxInfo.machineId;
}
return deviceIdentifier;
}
Use device_info_plus package developed by Flutter community. This is how you can get IDs on both platform.
In your pubspec.yaml file add this:
dependencies:
device_info_plus: ^3.2.3
Create a method:
Future<String> getUniqueDeviceId() async {
String uniqueDeviceId = '';
var deviceInfo = DeviceInfoPlugin();
if (Platform.isIOS) { // import 'dart:io'
var iosDeviceInfo = await deviceInfo.iosInfo;
uniqueDeviceId = '${iosDeviceInfo.name}:${iosDeviceInfo.identifierForVendor}'; // unique ID on iOS
} else if(Platform.isAndroid) {
var androidDeviceInfo = await deviceInfo.androidInfo;
uniqueDeviceId = '${androidDeviceInfo.name}:${androidDeviceInfo.id}' ; // unique ID on Android
}
return uniqueDeviceId;
}
Usage:
String deviceId = await getUniqueDeviceId();
Output:
M2102J20SG::SKQ1.211006.001
Note:
Do not use androidDeviceInfo.androidId. This would change when your mac address changes. Mobile devices above Android OS 10/11 will generate a randomized MAC. This feature is enabled by default unless disabled manually. This would cause the androidId to change when switiching networks. You can confirm this by yourself by changing androidDeviceInfo.id to androidDeviceInfo.androidId above.
you can probably get away with using only androidDeviceInfo.name as it would not change ever.
androidDeviceInfo.id can also change if OS is updated as it is an android os version.
androidDeviceInfo.androidId should only be used if device uses fix mac address as mentioned in point 1. Otherwise, either use *.name only or androidDeviceInfo.id alongside with *.name.