设置用户 ID 和哈希 User Details
向 Singular 发送内部用户 ID,以实现跨设备跟踪和用户级数据报告。
注:如果使用Singular 的跨设备解决方案,则必须在所有平台上收集用户 ID。
用户ID要求
隐私和最佳实践
在实施用户 ID 跟踪时,请遵循以下准则,以确保隐私合规和正确的跨设备测量。
- 无 PII:用户 ID 不应暴露个人身份信息 (PII),如电子邮件地址、用户名或电话号码。使用与第一方数据独一无二的哈希值。 如需发送电子邮件地址或电话号码,请改用专用的 哈希 User Details API。
- 跨平台一致性:用户 ID 值必须是您在所有平台(网络/移动/PC/控制台/离线)上获取的相同内部标识符,以便进行准确的跨设备测量。
- 第一方数据:用户 ID 是第一方数据,不会与第三方共享。
-
持久性:用户 ID 会一直存在,直到使用
unsetCustomUserId()明确取消设置或卸载应用程序为止。关闭或重启应用程序不会清除用户 ID。
实施概述
何时设置用户 ID
使用Singular.setCustomUserId() 设置用户标识符,使用Singular.unsetCustomUserId() 注销时清除用户标识符。
最佳实践:如果多个用户共用一台设备,请执行注销流程,登录时调用setCustomUserId() ,注销时调用unsetCustomUserId() 。
如果已经知道应用程序打开时的用户 ID,请在初始化 Singular SDK 之前使用withCustomUserId() 进行配置。这样可以确保 Singular 从第一次会话中接收到用户 ID。不过,在用户注册或登录之前,用户 ID 通常是不可用的,在这种情况下,请在注册或身份验证流程完成后调用setCustomUserId() 。
SDK 方法
设置自定义用户 ID
向 Singular 发送内部用户 ID,用于跨设备跟踪和用户级报告。
// TurboModule direct API (React Native 0.76+ New Architecture)
import NativeSingular from 'singular-react-native/js/NativeSingular';
// Set the user ID after login or registration
NativeSingular.setCustomUserId('user_123456');
import { Singular } from 'singular-react-native';
// Set the user ID after login or registration
Singular.setCustomUserId('user_123456');
方法签名:
static setCustomUserId(customUserId: string): void
示例:登录后设置用户 ID
在用户成功完成身份验证后立即调用setCustomUserId() ,以确保所有后续事件都与用户 ID 相关联。
// TurboModule direct API (React Native 0.76+ New Architecture)
import NativeSingular from 'singular-react-native/js/NativeSingular';
async function handleUserLogin(email, password) {
try {
// Your authentication logic
const response = await authenticateUser(email, password);
if (response.success) {
// Set the user ID in Singular after successful login
NativeSingular.setCustomUserId(response.userId);
console.log('User ID set:', response.userId);
// Navigate to home screen
navigateToHome();
}
} catch (error) {
console.error('Login failed:', error);
}
}
import { Singular } from 'singular-react-native';
async function handleUserLogin(email, password) {
try {
// Your authentication logic
const response = await authenticateUser(email, password);
if (response.success) {
// Set the user ID in Singular after successful login
Singular.setCustomUserId(response.userId);
console.log('User ID set:', response.userId);
// Navigate to home screen
navigateToHome();
}
} catch (error) {
console.error('Login failed:', error);
}
}
取消设置自定义用户 ID
在用户注销时清除用户 ID,以确保多用户设备的准确会话跟踪。
// TurboModule direct API (React Native 0.76+ New Architecture)
import NativeSingular from 'singular-react-native/js/NativeSingular';
// Unset the user ID on logout
NativeSingular.unsetCustomUserId();
import { Singular } from 'singular-react-native';
// Unset the user ID on logout
Singular.unsetCustomUserId();
方法签名:
static unsetCustomUserId(): void
示例:注销时取消设置用户 ID
在注销流程中调用unsetCustomUserId() ,清除用户 ID,防止后续事件的错误归因。
// TurboModule direct API (React Native 0.76+ New Architecture)
import NativeSingular from 'singular-react-native/js/NativeSingular';
async function handleUserLogout() {
try {
// Clear app data and user session
await clearUserSession();
// Unset the user ID in Singular
NativeSingular.unsetCustomUserId();
console.log('User ID cleared');
// Navigate to login screen
navigateToLogin();
} catch (error) {
console.error('Logout failed:', error);
}
}
import { Singular } from 'singular-react-native';
async function handleUserLogout() {
try {
// Clear app data and user session
await clearUserSession();
// Unset the user ID in Singular
Singular.unsetCustomUserId();
console.log('User ID cleared');
// Navigate to login screen
navigateToLogin();
} catch (error) {
console.error('Logout failed:', error);
}
}
在初始化过程中设置用户 ID
如果用户 ID 在应用程序启动时可用(例如,用户已登录),可在 SDK 初始化期间使用withCustomUserId() 进行配置。这样可确保首次会话包含用户 ID。
// TurboModule direct API (React Native 0.76+ New Architecture)
import React, { useEffect } from 'react';
import NativeSingular from 'singular-react-native/js/NativeSingular';
import type { SingularConfig } from 'singular-react-native/js/NativeSingular';
import AsyncStorage from '@react-native-async-storage/async-storage';
export default function App() {
useEffect(() => {
initializeSingular();
}, []);
async function initializeSingular() {
// Check if user is already logged in
const userId = await AsyncStorage.getItem('user_id');
// Create configuration object
const config: SingularConfig = {
apikey: 'YOUR_SDK_KEY',
secret: 'YOUR_SDK_SECRET',
...(userId ? { customUserId: userId } : {}),
};
// Initialize SDK
NativeSingular.init(config);
}
return (
// Your app components
null
);
}
import React, { useEffect } from 'react';
import { Singular, SingularConfig } from 'singular-react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
export default function App() {
useEffect(() => {
initializeSingular();
}, []);
async function initializeSingular() {
// Check if user is already logged in
const userId = await AsyncStorage.getItem('user_id');
// Create configuration
const config = new SingularConfig(
'YOUR_SDK_KEY',
'YOUR_SDK_SECRET'
);
// If user ID exists, set it during initialization
if (userId) {
config.withCustomUserId(userId);
}
// Initialize SDK
Singular.init(config);
}
return (
// Your app components
);
}
配置方法签名:
withCustomUserId(customUserId: string): SingularConfig
建议:对于具有持续登录会话的应用程序,在初始化过程中使用withCustomUserId()。对于用户必须每次登录的应用程序,请在验证后调用setCustomUserId() 。
哈希 User Details(电子邮件和电话号码)
上述用户 ID 是您自己的不透明标识符。如果您还想将用户的电子邮件地址或电话号码发送到 Singular,请使用独立的 SingularUserDetails API。SDK 会在设备上对这些值进行规范化并使用 SHA-256 哈希,因此原始的电子邮件地址和电话号码不会被传输。
适用版本: React Native SDK 4.3.0 及以上版本。
选择哈希模式
提供 User Details 有两种方式。请为每位用户选择一种并保持一致。
- SDK 哈希(推荐): 传入明文电子邮件地址或电话号码。SDK 会规范化该值、进行哈希,并生成 Singular 可用于匹配的所有变体。
- 预哈希: 传入您已自行规范化并使用 SHA-256 哈希的值。SDK 会完全按照提供的内容存储,不做任何进一步处理。当您的应用在调用时不能持有明文 User Details 时,请使用此方式。
重要: 如果您同时设置了明文值及其对应的预哈希变体,预哈希值优先。
SingularUserDetails Setter
| Setter | 详情 |
|---|---|
setEmail
|
模式: SDK 哈希
明文电子邮件地址。SDK 会在哈希前去除空格并转换为小写。对于
示例:
|
setPhoneNumber
|
模式: SDK 哈希
明文电话号码。SDK 会生成两个变体:一个是保留开头
示例:
|
setEmailSTD
|
模式: 预哈希 去除空格并转换为小写后的电子邮件地址的 SHA-256 哈希值。 |
setEmailNoDots
|
模式: 预哈希
去除空格、转换为小写,并从本地部分移除 |
setPhoneE164
|
模式: 预哈希
保留开头 |
setPhoneDigits
|
模式: 预哈希
去除所有非数字字符(包括开头的 |
每个 setter 都会返回同一个对象,因此可以链式调用。在 New Architecture 中,您也可以传入使用相同六个键的普通对象:email、phoneNumber、emailSTD、emailNoDots、phoneE164 和 phoneDigits。
在初始化时设置 User Details
请在调用 init() 之前设置 SingularConfig.userDetails,或使用 withUserDetails() 构建器,这样 User Details 就会附加到 SDK 发送的第一个会话中。
// TurboModule direct API (React Native 0.76+ New Architecture)
import NativeSingular from 'singular-react-native/js/NativeSingular';
import type { SingularConfig } from 'singular-react-native/js/NativeSingular';
const config: SingularConfig = {
apikey: 'YOUR_SDK_KEY',
secret: 'YOUR_SDK_SECRET',
userDetails: {
email: 'user@example.com',
phoneNumber: '+15551234567'
}
};
NativeSingular.init(config);import { Singular, SingularConfig, SingularUserDetails } from 'singular-react-native';
const userDetails = new SingularUserDetails()
.setEmail('user@example.com')
.setPhoneNumber('+15551234567');
const config = new SingularConfig('YOUR_SDK_KEY', 'YOUR_SDK_SECRET')
.withUserDetails(userDetails);
Singular.init(config);配置方法签名:
withUserDetails(userDetails: SingularUserDetails): SingularConfig
在初始化后设置 User Details
如果只有在登录或注册后才能获取电子邮件地址或电话号码,请在那时调用 setUserDetails。此后,这些值会附加到 SDK 发送的每个会话和事件中。
// TurboModule direct API (React Native 0.76+ New Architecture)
import NativeSingular from 'singular-react-native/js/NativeSingular';
// Cleartext values, hashed on the device by the SDK
NativeSingular.setUserDetails({
email: 'user@example.com',
phoneNumber: '+15551234567'
});
// Or supply your own SHA-256 hashes
NativeSingular.setUserDetails({
emailSTD: 'b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514',
phoneE164: '8a59780bb8cd2ba022bfa5ba2ea3b6e07af17a7d8b30c1f9b3390e36f69019e4'
});import { Singular, SingularUserDetails } from 'singular-react-native';
// Cleartext values, hashed on the device by the SDK
const userDetails = new SingularUserDetails()
.setEmail('user@example.com')
.setPhoneNumber('+15551234567');
Singular.setUserDetails(userDetails);
// Or supply your own SHA-256 hashes
const hashed = new SingularUserDetails()
.setEmailSTD('b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514')
.setPhoneE164('8a59780bb8cd2ba022bfa5ba2ea3b6e07af17a7d8b30c1f9b3390e36f69019e4');
Singular.setUserDetails(hashed);方法签名:
static setUserDetails(userDetails: SingularUserDetails): void
注意: setUserDetails() 在 init() 之前无效,原生 SDK 会记录错误并返回。如需覆盖第一个会话,请使用 SingularConfig.userDetails。
清除 User Details
存储的 User Details 会持久保存在设备上:iOS 使用 Keychain,Android 使用加密存储,并在应用多次启动之间保持。请在登出时,或用户撤回同意时调用 clearUserDetails() 将其移除。
// TurboModule direct API (React Native 0.76+ New Architecture)
import NativeSingular from 'singular-react-native/js/NativeSingular';
// Remove stored user details on logout
NativeSingular.clearUserDetails();import { Singular } from 'singular-react-native';
// Remove stored user details on logout
Singular.clearUserDetails();方法签名:
static clearUserDetails(): void
注意:
由于这些值会被持久化,在后续启动中赋值 SingularConfig.userDetails 不会清除之前存储的内容。clearUserDetails 是唯一的移除方式。
验证与隐私行为
-
JavaScript 层:
SingularUserDetails会丢弃任何非空字符串以外的值,包括字面量字符串"null"和"undefined"。它不会检查值的格式。 -
电子邮件验证:
明文电子邮件必须包含且仅包含一个
@,且其后需有一个点号。无效值会被拒绝并记录到日志,不会被发送。 - 电话号码验证: 明文电话号码必须包含至少 6 位数字。更短的值会被拒绝并记录到日志。
-
模式误用防护:
看起来已经过哈希的值会被
setEmail和setPhoneNumber拒绝。同样,预哈希 setter 会拒绝任何非 64 位 SHA-256 十六进制字符串的值。 - Limit Data Sharing: 在启用 Limit Data Sharing 期间,User Details 载荷将从所有请求中排除。 参阅: 数据隐私.
- 同意: 仅在您具有合法依据的情况下收集和发送电子邮件地址和电话号码。哈希处理并不免除您在 GDPR、CCPA 或同等法规下的义务。