Expo如何在不弹出的情况下获取唯一设备ID

28

这个库可以让你获取 Android 设备的唯一设备 ID / Mac 地址,在应用重新安装后不会改变。

Expo.Constants.deviceId 在每次重新安装后都会改变(即使应用程序版本号相同)。

有没有办法在不弹出的情况下获得 Android 的唯一 ID,而在重新安装后不改变(至少对于相同的版本)?


你找到解决方案了吗? - user1623454
2
您可以在 Github 的问题中找到更多关于该主题的信息。看起来这是出于隐私原因而不需要的。https://github.com/expo/expo/issues/825 - Laszlo Schürg
https://github.com/react-native-device-info/react-native-device-info#getuniqueid 不是提供了这个吗? - therightstuff
是的,但这需要从Expo中弹出(在旧的弹出时代)。 - Avery235
react-native-device-info 通常不会与 Expo 兼容,除非您使用的是 Expo 裸应用程序。 - Morris S
显示剩余2条评论
6个回答

26

对于Expo IOS,目前的选择非常有限,因为苹果禁止获取私人设备信息。我们需要在下面创建自己的唯一标识符。

解决方案:

我的解决方案是uuid和Expo SecureStore的组合,在IOS和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)

即使应用程序被重新安装,或者用户更换设备并将所有数据复制到新设备上,此解决方案也可以正常工作。 (Expo.Constants.deviceId已过时,将在Expo SDK 44中删除。)

完整示例:

要检查是否已在uuid中存储了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)

1
我猜 'secure_deviceid' 在应用更新后会被保留,但在重新安装时不会? - Michael Bahl
1
由于“SecureStore”存储在系统钥匙串中,并且根据Expo文档,将保留“使用expo-secure-store存储的数据可以跨应用程序安装持久存在”,因此即使重新安装,它也将被保留。 - Morris S
它是否也会在 Android 应用程序安装之间持久存在?文档说明:请注意,对于 iOS 独立应用程序,使用 expo-secure-store 存储的数据可以在应用程序安装之间持久存在。但是对于 Android 没有提到任何内容。 - yemd
它为同一设备每次提供不同的值,我需要为一个设备实现相同的唯一标识符。 - Ibad Ur Rehman
1
@IbadUrRehman uuid 每次调用都会给出一个新的唯一标识符。 对于您的情况,您需要先检查是否已经有 uuid 并从 SecureStore 中检索。 - Morris S
显示剩余2条评论

7

使用来自 expo-application 的 Application.androidId。该 ID 不会因为应用的重新安装或更新而变化。如果设备进行出厂设置或者 APK 签名密钥发生了改变,该值可能会发生更改。 https://docs.expo.dev/versions/latest/sdk/application/#applicationandroidid

示例:

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;
  }
}

但是iOS呢?它说在iOS上会返回null。我需要一个可以在两个平台上运行的东西。 - Abhishek Anand
@AbhishekAnand 我添加了一个例子。 - Dmitro_
1
对于iOS,我们可以使用此链接 https://docs.expo.dev/versions/v45.0.0/sdk/application/#applicationgetiosidforvendorasync - Rajendran Nadar

2

最佳方法是在Android中使用ANDROID_ID,在iOS中使用IDFV

对于Expo,这是一个包:https://docs.expo.dev/versions/latest/sdk/application/#applicationgetiosidforvendorasync

我的代码:

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;

如果有人只使用uuid.v4()并在使用SecureStore存储后删除应用程序,除了iOS手机外,所有数据都将被删除。在Android上,所有App数据将与存储的密钥一起被删除。

0

2
请在您的回答中添加所有相关信息,而不是链接到外部资源。 - Nico Haase

-1

在 Expo 项目中获取设备唯一标识符的方法:

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

请注意:expo start 会报错。

enter image description here


很遗憾,您需要退出 Expo 应用程序才能使用 react-native-device-info - undefined

-1

只需使用react-native-device-info中的getuniqueid()方法。适用于iOS和Android以唯一标识设备。


1
这在Expo托管工作流中不起作用。 - pors

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接