113

In Android we have, Settings.Secure.ANDROID_ID. I do not know the iOS equivalent. Is there a flutter plugin or a way to get a unique device id for both Android and IOS in flutter?

CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
karan vs
  • 3,044
  • 4
  • 19
  • 26
  • 4
    Does this unique ID be changed in any case or would remain same and never changed? If changed, what are the scenarios in which it would change? – Ravi Garg Aug 27 '20 at 20:18
  • 7
    **UPDATE**: Because this thread has a very high Google ranking I wanted to mention here that the [device_id](https://pub.dev/packages/device_id) package has been discontinued. The package [platform_device_id](https://pub.dev/packages/platform_device_id) looks like it works about the same way though, and has very recent activity. We're switching over to that after seeing errors in the log after iOS crashes which point to the old package. – Adam Bellas Nov 03 '20 at 15:22
  • On Android devices, there can be multiple users for the device. Is there a way to get a unique ID per user on the device? – Jarl Mar 14 '21 at 09:38
  • @spycbanda did you find the answer of your question, I have the same question like yours – wahyu Jan 21 '22 at 03:24

14 Answers14

134

Null safe code

Use device_info_plus plugin 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?> _getId() async {
  var deviceInfo = DeviceInfoPlugin();
  if (Platform.isIOS) { // import 'dart:io'
    var iosDeviceInfo = await deviceInfo.iosInfo;
    return iosDeviceInfo.identifierForVendor; // unique ID on iOS
  } else if(Platform.isAndroid) {
    var androidDeviceInfo = await deviceInfo.androidInfo;
    return androidDeviceInfo.androidId; // unique ID on Android
  }
}

Usage:

String? deviceId = await _getId();
DiyorbekDev
  • 706
  • 1
  • 5
  • 19
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
  • Does this unique ID be changed in any case or would remain same and never changed? If changed, what are the scenarios in which it would change? – Ravi Garg Aug 27 '20 at 20:17
  • 2
    It's known to be null sometimes, it's documented as "can change upon factory reset". Use at your own risk, and it can be easily changed on a rooted phone. – Kamlesh Aug 31 '20 at 08:55
  • 1
    @spycbanda Google Play Store release had a different ID vs debug development for me. – Elmer Sep 14 '20 at 13:31
  • 21
    Just tested this: The ID stays the same until the program is deleted. If re-installed, the ID is different. – William Terrill Sep 26 '20 at 20:53
  • After adding this plugin app not working in iPhone emulator – Midhilaj Oct 10 '20 at 11:51
  • @Midhilaj It may not work on the iPhone simulator, you need to use it in real device. – CopsOnRoad Oct 10 '20 at 15:04
  • The serial number returned by iosDeviceInfo.identifierForVendor seems to change every time I upgrade the IOS version/build in Xcode Identity block on my app. Anyone knows a way to avoid this serial change? – Cassio Seffrin Jun 28 '21 at 12:45
  • 1
    Is there a way to get an ID that stays the same across installs? – user2233706 May 29 '22 at 22:13
  • 14
    Looks like androidDeviceInfo.androidId does not exist in 4.1.2. – Ville Aug 19 '22 at 20:25
  • 6
    For device_info_plus: "Remove androidId (that already got removed from the method channel in 4.0.0, thus always returned null) There is a new, separate pub.dev package for getting the correct androidId" , so you now need to get it from the package "android_id" – Unreality Aug 19 '22 at 21:03
  • @Unreality are you sure that AndroidDeviceInfo.id is not that androidId that we need? Also the version of android_id package is currently 0.3.3 which honestly scares me a little bit to use it in production – Oleg Yablokov May 23 '23 at 19:43
97

There is a plugin called device_info. You can get it here.

Check the official example here

 static Future<List<String>> getDeviceDetails() async {
    String deviceName;
    String deviceVersion;
    String identifier;
    final DeviceInfoPlugin deviceInfoPlugin = new DeviceInfoPlugin();
    try {
      if (Platform.isAndroid) {
        var build = await deviceInfoPlugin.androidInfo;
        deviceName = build.model;
        deviceVersion = build.version.toString();
        identifier = build.androidId;  //UUID for Android
      } else if (Platform.isIOS) {
        var data = await deviceInfoPlugin.iosInfo;
        deviceName = data.name;
        deviceVersion = data.systemVersion;
        identifier = data.identifierForVendor;  //UUID for iOS
      }
    } on PlatformException {
      print('Failed to get platform version');
    }

//if (!mounted) return;
return [deviceName, deviceVersion, identifier];
}

You can store this UUID in the Keychain. This way you can set an unique ID for your device.

UPDATE

device_info is now device_info_plus

griffins
  • 7,079
  • 4
  • 29
  • 54
Chaythanya Nair
  • 4,774
  • 6
  • 32
  • 40
  • How do I get the android device id? can it be retrieved from device_info? – Mattias Apr 02 '19 at 08:08
  • if (Platform.isAndroid) { .... identifier = build.androidId; ...} else if (Platform.isIOS) { ..... } – mara-mfa Aug 10 '19 at 21:19
  • Does this require any permissions from the user? – Scorb Jun 13 '20 at 12:48
  • @ScottF Did you ever figure out if it is legal and requires any permission from the user? – David Luong Jun 26 '20 at 16:12
  • @Chaythanya example_here link is not working, i think it is broken. Please check and update it. Thanks. – Kamlesh Aug 13 '20 at 12:40
  • @Chaythanya Does this unique ID be changed in any case or would remain same and never changed? If changed, what are the scenarios in which it would change? – Ravi Garg Aug 27 '20 at 20:18
  • It's known to be null sometimes, it's documented as "can change upon factory reset". Use at your own risk, and it can be easily changed on a rooted phone. – Kamlesh Aug 31 '20 at 08:55
  • now you should use device_info_plus: https://pub.dev/packages/device_info_plus – Navid Sep 11 '21 at 20:04
  • On iOS devices, `identifierForVendor` [does change](https://stackoverflow.com/a/48154497/5301229) if the user uninstalls, then reinstalls your app, so it's not a 100% reliable constant. – Lee Mordell Oct 27 '21 at 15:49
  • `build.version` will return an instance, which variable that we should use? – Arief Wijaya Feb 03 '22 at 00:33
  • On the latest version of the plugin androidId was replaced with just id and is no longer unigue, i learned it the hard way identifier = build.androidId -> identifier = build.id; – KgaboL Dec 20 '22 at 16:06
15

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.

user3517658
  • 349
  • 3
  • 14
15

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;
}
Oswin Noetzelmann
  • 9,166
  • 1
  • 33
  • 46
  • 5
    As stated in [Android](https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID) and [IOS](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor#1965828) documentations, androidId and identifierForVendor can change over time. – Maël Pedretti Apr 19 '21 at 07:53
  • 2
    For device_info_plus: "Remove androidId (that already got removed from the method channel in 4.0.0, thus always returned null) There is a new, separate pub.dev package for getting the correct androidId" , so you now need to get it from the package "android_id" – Unreality Aug 19 '22 at 21:04
9

As of 2022, December, last status about getting device id :

device_info_plus don't give unique device id anymore. So I started to use platform_device_id package.

I tested it on Android and it worked as same as device_info previously and provide the same id value. It also has a simple usage :

   String deviceId = await PlatformDeviceId.getDeviceId;

This package uses updated android embedding version and also has null safety support.

cansu
  • 958
  • 1
  • 12
  • 23
  • that package has been abandoned because last update is 20 months ago – Tony Hart Dec 05 '22 at 14:59
  • device_info: ^2.0.3 platform_device_id: ^1.0.1 These both packages are depricated and old. However everyone can use android_id: ^0.1.3+1 package just for android. – Sanny khan Dec 06 '22 at 10:39
  • eventhough `platform_device_id` is an old package, it is Dart 3 compatible and got me unique deviceId unlike `device_info_plus`. Thank you @cansu for mentioning it – Solomon Tesfaye Aug 09 '23 at 00:48
7

Use device_id plugin

  1. Add in your following code in your .yaml file.

    device_id: ^0.1.3
    
  2. Add import in your class

    import 'package:device_id/device_id.dart';
    
  3. Now get device id from:

    String deviceid = await DeviceId.getID;
    
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
  • 2
    This will force your app to have `android.permission.READ_PHONE_STATE`. And this will cause a warning while publishinh your app to Play Store as `Apps using these permissions in an APK are required to have a privacy policy set.` – Sisir Aug 27 '20 at 14:52
  • 13
    This plugin is discontinued – Code on the Rocks Oct 11 '20 at 18:28
7

Latest:

The plugin device_info has given deprecation notice and replaced by device_info_plus

Example:

dependencies:
  device_info_plus: ^9.0.2

How to use:

import 'package:device_info_plus/device_info_plus.dart';

DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();

AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
print('Running on ${androidInfo.model}');  // e.g. "Moto G (4)"

IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
print('Running on ${iosInfo.utsname.machine}');  // e.g. "iPod7,1"

WebBrowserInfo webBrowserInfo = await deviceInfo.webBrowserInfo;
print('Running on ${webBrowserInfo.userAgent}');  // e.g. "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0"

You can check here full example:

For Unique ID:

You can use following code to get Unique ID:

String deviceIdentifier = '';
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
if (kIsWeb) {
  final WebBrowserInfo webInfo = await deviceInfo.webBrowserInfo;
  deviceIdentifier = webInfo.vendor! +
      webInfo.userAgent! +
      webInfo.hardwareConcurrency.toString();
} else {
  if (Platform.isAndroid) {
    final AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
    deviceIdentifier = androidInfo.id;
  } else if (Platform.isIOS) {
    final IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
    deviceIdentifier = iosInfo.identifierForVendor!;
  } else if (Platform.isLinux) {
    final LinuxDeviceInfo linuxInfo = await deviceInfo.linuxInfo;
    deviceIdentifier = linuxInfo.machineId!;
  }
}

edit: There is no androidId on since v4.1.0.

Mahesh Jamdade
  • 17,235
  • 8
  • 110
  • 131
Pratik Butani
  • 60,504
  • 58
  • 273
  • 437
  • 1
    It's not a good solution because ``iosInfo`` changes with each app upgrade/reinstall. – Oliver Dixon Apr 28 '22 at 10:26
  • ```hardwareConcurrency``` is not a good example. It will return the number of cores on the machine, not very unique.. – Oliver Dixon May 28 '22 at 10:31
  • For device_info_plus: "Remove androidId (that already got removed from the method channel in 4.0.0, thus always returned null) There is a new, separate pub.dev package for getting the correct androidId" , so you now need to get it from the package "android_id" – Unreality Aug 19 '22 at 21:05
  • UPDATE: device_info_plus does not give unique androidId anymore – Z. Cajurao Feb 09 '23 at 11:28
  • IMO for platform web you should not use browser info or user agent, instead generate a unique identifier using `uuid` package – Mahesh Jamdade Jun 03 '23 at 01:01
6

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:

  1. 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.

  2. you can probably get away with using only androidDeviceInfo.name as it would not change ever.

  3. androidDeviceInfo.id can also change if OS is updated as it is an android os version.

  4. 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.

Ariel
  • 2,471
  • 1
  • 26
  • 43
5

I release a new flutter plugin client_information might help. It provide a simple way to get some basic device information from your application user.

  1. add to pubspec.yaml
  dependencies:
    ...
    client_information: ^1.0.1
  1. import to your project
import 'package:client_information/client_information.dart';
  1. then you can get device ID like this
/// Support on iOS, Android and web project
Future<String> getDeviceId() async {
  return (await ClientInformation.fetch()).deviceId;
}

KentChien
  • 51
  • 1
  • 1
4

androidID is removed since v4.1.0. Check the changelog.

android_id package is recommanded to get the correct androidId.

李华良
  • 224
  • 3
  • 10
3

Add the following code in your .yaml file.

device_info_plus: ^1.0.0

I used the following approach to get the device info that support in all platforms (i.e.) Android, IOS and Web.

import 'dart:io';  
import 'package:device_info_plus/device_info_plus.dart';  
import 'package:flutter/foundation.dart' show kIsWeb;  

Future<String> getDeviceIdentifier() async { 

    String deviceIdentifier = "unknown";  
    DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();  

    if (kIsWeb) {
      WebBrowserInfo webInfo = await deviceInfo.webBrowserInfo;
      deviceIdentifier = webInfo.vendor +
          webInfo.userAgent +
          webInfo.hardwareConcurrency.toString();
    } else {
      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 (Platform.isLinux) {
        LinuxDeviceInfo linuxInfo = await deviceInfo.linuxInfo;
        deviceIdentifier = linuxInfo.machineId;
      }
    }
    return deviceIdentifier;
}
Gowtham. R
  • 698
  • 5
  • 11
2

android_id: ^0.1.3+1 Use this package but it only works on android.

device_info_plus: ^8.0.0 Use this package it works on IOS, Android, Web.

Sanny khan
  • 177
  • 1
  • 1
  • 7
-1

In You Main.dart File Just these codes You will Get the Player Id of the Your Flutter App//

  final status = await OneSignal.shared.getDeviceState();` final String? osUserID = status?.userId;

print(osUserID);

Asim Khan
  • 309
  • 3
  • 2
-2

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.

Collin Jackson
  • 110,240
  • 31
  • 221
  • 152
  • I am not using firebase , neither I am serving ads. I need a unique identifier to id the device like Settings.Secure.ANDROID_ID in android. I want to know if there a plugin out there for this or shall I have to make a new one for this ? – karan vs Jul 17 '17 at 05:54
  • 1
    I don't think what you are asking for is possible on iOS. You can easily identify an app install by writing a guid to a file, though. – Collin Jackson Jul 17 '17 at 05:55
  • Firebase token has been changed automatically when we uninstall and reinstall mobile app so uniqueness of token does not work. We cannot use it to identify the same user. – Kamlesh Aug 31 '20 at 08:57