flutterdartdeviceid

Can the device ID information vary?


I am trying to keep the device ID of applications unique by using the device_info_plus package in Flutter. For example, even if a person deletes the application and reinstalls it, they cannot log in from different accounts. I want to use it for device-based restrictions, but I don't know if this device ID changes under all conditions.

I would be very grateful if you could help me.


Solution

  • So let's simplify the question first:

    Does device_info_plus package include PERSISTENT UUID in the same device across different sessions. And under which conditions it's being changed/reseted/deleted etc.

    Since Flutter is a hybrid application and I'm assuming you are targeting both Android and iOS. We must consider both method channels while deciding if it's providing persistent UUIDs.

    On Android, androidId:

    On some devices, this ID may change when:

    • The device is factory reset

    • A new user profile is created on the device

    • Some Android OEMs (e.g., Samsung, Xiaomi) generate different IDs after system updates

    So, the Android device identifier is not a stable, hardware-bound unique ID—it can change under those conditions.

    On iOS, the identifierForVendor—which is scoped per app vendor (i.e., apps under the same developer account)—can change when:

    • The user uninstalls and reinstalls the app

    • The app is installed on another device

    • The app is installed via a different Apple Developer account (e.g., TestFlight vs. App Store)

    Here is also a real world example from one of the project's I've worked for:

    I emulated the application using my Android emulator and did most of the tests on the Android.

    However, I've also used TestFlight builds in-order to test the application. As we can see from the example outputs, the devicekey doesn't persist between different sessions/updates etc.

    Id and clientId are generic UUID of the object.

    enum AppOsType { android, ios }
    
    "devices": [
      {
        "id": "2bd102a3-ac56-4bed-b680-08dd3d283c59",
        "devicekey": "f-gXWb7OAkF3r0YaWXvy_0:APA91bEeLY71z3vgCtVhSxmf88W3TG0EYjpg3fcTXZLxgsR2AK_zZFGuif_LblVsru6IXW_5BC30SjJyoychKCJmloJpLk6NC5DnkAfZuwuNzDssFC1KOC3ZEF-aNlziSvGDvLMKJNvG",
        "clientId": "44d33e94-2370-40ec-b4bd-3581f7ef2634",
        "appType": 0,
        "appOsType": 1,
        "bundleId": "com.example.companyname",
        "deviceModel": null
      },
      {
        "id": "ae5d54e8-55db-476b-5d86-08dd3d3aa49e",
        "devicekey": "cr67EhR1TuCd8n5bSvIYax:APA91bHBk-UnQilKhmEvJgwxDdZIu-h3KYhg_MSCBPrd1GAONg7uoxcrKvzhZTWFubikp8JW6ZRD3uPU8D4azURw9qOV-KZLSzOBEoFz8-301cxCWQ2dMkU",
        "clientId": "00e068d2-1e25-41ac-8e0e-c75a5e85a3d4",
        "appType": 0,
        "appOsType": 0,
        "bundleId": "com.example.companyname",
        "deviceModel": null
      },
      {
        "id": "c859c42c-7224-410e-033e-08dd687f8681",
        "devicekey": "crBKv6P07EVWqZoI9XXENz:APA91bGQ0xNzThGKAaDMBzm9-OrdWuIgJ48T7qzrr0RR67qq7L_7-BFRaEcf4Nd9DswxPMvdxoYzpOxbSHs0Fo2WJ7tAYOz-1c-TZyV4K2Bc1DPa0sVj_5g",
        "clientId": "fb55452d-b19e-4d47-9de6-2a80d6cf9102",
        "appType": 0,
        "appOsType": 1,
        "bundleId": "com.example.companyname",
        "deviceModel": null
      },
      {
        "id": "36b7b917-65bd-4e18-de27-08ddd725c186",
        "devicekey": "fYCJex2LqEisjr10liuiRj:APA91bGrAj_4BGDtNs9aKEoJ6bzQR2q-YNhrFFSiwc5G3QHbkqDuvZLax_RtSnqvDxVRCTdDFqpBz9rrKiqaAb4kex13_k5epT8ufJWQnj1TPzVVRj6krfQ",
        "clientId": "c00a71c9-b194-4c31-a540-e21dbe638c6c",
        "appType": 0,
        "appOsType": 1,
        "bundleId": "com.example.companyname",
        "deviceModel": null
      }
    ]
    

    What I recommend as a solution:

    Mobile banking applications also track deviceIds but they update it and confirm by SMS when they detect a user has changed their devices.

    Still collecting it and maintaining it as a pseudo-primary-key could be the way to go while acknowledging it's not reliable by native channels, so changing packages won't help you because the native code under the hood(Swift and Kotlin parts, the native parts) do not provide persistent UUIDs.

    If you prefer to use this way, don't forget to remove the deviceId on log-out/account deletions.