27

This library allows you to get unique device id / Mac address of Android devices, which doesn't change after reinstallation.

Expo.Constants.deviceId changes after every reinstallation (even if the app version number is the same).

Is there a way to get an unique id for Android that doesn't change after reinstallation (at least for if it's the same version), without ejecting?

Avery235
  • 4,756
  • 12
  • 49
  • 83

6 Answers6

25

For Expo IOS theres currently very limited options, Since Apple forbids getting private device info. We will need to create our own unique identifier below.

Solution:

My solution is a combination of uuid and Expo SecureStore works for IOS and Android.

import * as SecureStore from 'expo-secure-store';
import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';


let uuid = uuidv4();
await SecureStore.setItemAsync('secure_deviceid', JSON.stringify(uuid));
let fetchUUID = await SecureStore.getItemAsync('secure_deviceid');
console.log(fetchUUID)

This solution will work even if app gets reinstalled, or if user switches devices and copy's all data to new device. (Expo.Constants.deviceId is deprecated and will be removed in Expo SDK 44).

Full Example:

To check if you already stored the uuid in SecureStore

import * as SecureStore from 'expo-secure-store';
import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';

let uuid = uuidv4();
let fetchUUID = await SecureStore.getItemAsync('secure_deviceid');
  //if user has already signed up prior
  if (fetchUUID) {
    uuid = fetchUUID
  }
await SecureStore.setItemAsync('secure_deviceid', JSON.stringify(uuid));
console.log(uuid)
Morris S
  • 2,337
  • 25
  • 30
  • 1
    I guess the 'secure_deviceid' kept after app updates but not between installs ? – Michael Bahl Jul 28 '21 at 09:22
  • 1
    It will be kept even for reinstalls since `SecureStore` is stored to the system keychain and according to Expo docs will be kept around "data stored with expo-secure-store can persist across app installs". https://docs.expo.io/versions/latest/sdk/securestore/ – Morris S Jul 28 '21 at 18:48
  • Will it persist between app installs on Android too? Doc says: Please note that for iOS standalone apps, data stored with expo-secure-store can persist across app installs. But nothing is mentionned for Android – yemd Jan 13 '22 at 00:39
  • @yemd `SecureStore` for Android is stored in `SharedPreferences` this might be helpful https://stackoverflow.com/questions/24650870/sharedpreferences-values-do-not-persist – Morris S Jan 13 '22 at 16:42
  • it give different values each time for same device I need to implement same unique id for one device – Ibad Ur Rehman Feb 26 '22 at 11:50
  • 1
    @IbadUrRehman `uuid` gives a new unique id each time called. for your case you will need to check if theres already a uuid first and retrieve from `SecureStore`. – Morris S Apr 05 '22 at 15:53
  • the docs say that it will persist on iOS specifically, which implies that it wont for android – ICW Jan 07 '23 at 01:38
6

Use Application.androidId from expo-application. Id will not change after reinstall or update. The value may change if a factory reset is performed on the device or if an APK signing key changes. https://docs.expo.dev/versions/latest/sdk/application/#applicationandroidid

Example:

import * as Application from 'expo-application';
import { Platform } from 'expo-modules-core';
import * as SecureStore from 'expo-secure-store';
import Constants from 'expo-constants';

const getDeviceId = async () => {
  if (Platform.OS === 'android') {
    return Application.androidId;
  } else {
    let deviceId = await SecureStore.getItemAsync('deviceId');

    if (!deviceId) {
      deviceId = Constants.deviceId; //or generate uuid
      await SecureStore.setItemAsync('deviceId', deviceId);
    }

    return deviceId;
  }
}
Dmitro_
  • 451
  • 2
  • 8
0

Guess you can use facebook module for this purpose. https://docs.expo.io/versions/latest/sdk/facebook-ads/#currentdevicehash

Not sure what happens under hood - but looks like it unique between app reinstal, device restart etc.

Keiser
  • 44
  • 1
0

Best way to do is use ANDROID_ID for android or IDFV for iOS.

For Expo here is package: https://docs.expo.dev/versions/latest/sdk/application/#applicationgetiosidforvendorasync

My code:

const newUniqueId = Platform.OS === 'android'
            ? Application.androidId ?? uuid.v4().toString()
            : await Application.getIosIdForVendorAsync() ?? uuid.v4().toString();

let uniqueId = null;
try {
    uniqueId = await SecureStore.getItemAsync('uniqueId');
} catch (error) {
    LoggerService.logToSentry(error);
}

try {
    if (!uniqueId) {
        uniqueId = newUniqueId;
        await SecureStore.setItemAsync('uniqueId', uniqueId);
    }
} catch (error) {
    uniqueId = newUniqueId;
    LoggerService.logToSentry(error);
}

return uniqueId;

If some one use only uuid.v4() and stores with SecureStore after app deletion all data will be deleted except iOS phones. On Android all App data will be deleted with stored keys

Ernestyno
  • 797
  • 1
  • 10
  • 16
-1

Just use getuniqueid() method from react-native-device-info. Works on iOS and android to uniquely identify a device .

Bharat Varma
  • 154
  • 1
  • 6
-1

To get the device UniqueId in expo project,

  1. npm install react-native-device-info
  2. expo run:ios or expo run:android

Please note: expo start will throw an error

enter image description here

nrooban
  • 59
  • 1
  • 2