设置用户 ID 和哈希 User Details
向 Singular 发送内部用户 ID,以实现跨设备跟踪和用户级数据报告。
注:如果使用Singular 的跨设备解决方案,则必须在所有平台上收集用户 ID。
用户ID要求
隐私和最佳实践
在实施用户 ID 跟踪时,请遵循以下准则,以确保隐私合规和正确的跨设备测量。
- 无 PII:用户 ID 不应暴露个人身份信息 (PII),如电子邮件地址、用户名或电话号码。使用与第一方数据独一无二的哈希值。
- 跨平台一致性:用户 ID 值必须是您在所有平台(网络/移动/PC/控制台/离线)上获取的相同内部标识符,以便进行准确的跨设备测量。
- 第一方数据:Singular会在用户级导出、ETL和内部商业智能回传(如有配置)中包含用户ID。用户 ID 是第一方数据,不会与第三方共享。
-
持久性:用户 ID 会一直存在,直到使用
unsetCustomUserId()明确取消设置或卸载应用程序为止。关闭或重启应用程序不会清除用户 ID。
实施概述
何时设置用户 ID
使用Singular.setCustomUserId() 设置用户标识符,使用Singular.unsetCustomUserId() 注销时清除用户标识符。
最佳实践:如果多个用户共用一台设备,请执行注销流程,登录时调用setCustomUserId() ,注销时调用unsetCustomUserId() 。
如果已经知道应用程序打开时的用户 ID,请在初始化 Singular SDK 之前使用customUserId 属性进行配置。这将确保 Singular 从第一次会话中接收到用户 ID。不过,在用户注册或登录之前,用户 ID 通常是不可用的,在这种情况下,请在注册或身份验证流程完成后调用setCustomUserId() 。
SDK 方法
设置自定义用户 ID
向 Singular 发送内部用户 ID,用于跨设备跟踪和用户级报告。
import 'package:singular_flutter_sdk/singular.dart';
// Set the user ID after login or registration
Singular.setCustomUserId('user_123456');
方法签名:
static void setCustomUserId(String customUserId)
示例:登录后设置用户 ID
在用户成功完成身份验证后立即调用setCustomUserId() ,以确保所有后续事件都与用户 ID 相关联。
import 'package:singular_flutter_sdk/singular.dart';
Future<void> handleUserLogin(String email, String password) async {
try {
// Your authentication logic
final response = await authenticateUser(email, password);
if (response.success) {
// Set the user ID in Singular after successful login
Singular.setCustomUserId(response.userId);
print('User ID set: ${response.userId}');
// Navigate to home screen
navigateToHome();
}
} catch (error) {
print('Login failed: $error');
}
}
取消设置自定义用户 ID
在用户注销时清除用户 ID,以确保多用户设备的准确会话跟踪。
import 'package:singular_flutter_sdk/singular.dart';
// Unset the user ID on logout
Singular.unsetCustomUserId();
方法签名:
static void unsetCustomUserId()
示例:注销时取消设置用户 ID
在注销流程中调用unsetCustomUserId() ,清除用户 ID,防止后续事件的错误归因。
import 'package:singular_flutter_sdk/singular.dart';
Future<void> handleUserLogout() async {
try {
// Clear app data and user session
await clearUserSession();
// Unset the user ID in Singular
Singular.unsetCustomUserId();
print('User ID cleared');
// Navigate to login screen
navigateToLogin();
} catch (error) {
print('Logout failed: $error');
}
}
在初始化过程中设置用户 ID
如果用户 ID 在应用程序启动时可用(例如,用户已登录),可在 SDK 初始化期间使用customUserId 属性进行配置。这样可确保首次会话包含用户 ID。
import 'package:flutter/material.dart';
import 'package:singular_flutter_sdk/singular.dart';
import 'package:singular_flutter_sdk/singular_config.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
initializeSingular();
}
Future<void> initializeSingular() async {
// Check if user is already logged in
final prefs = await SharedPreferences.getInstance();
final userId = prefs.getString('user_id');
// Create configuration
SingularConfig config = SingularConfig(
'YOUR_SDK_KEY',
'YOUR_SDK_SECRET'
);
// If user ID exists, set it during initialization
if (userId != null) {
config.customUserId = userId;
}
// Initialize SDK
Singular.start(config);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
配置属性:
String? customUserId
建议:对于具有持续登录会话的应用程序,请在初始化过程中使用customUserId配置属性。对于用户必须每次登录的应用程序,请在验证后调用setCustomUserId() 。
哈希 User Details(电子邮件和电话号码)
上面的用户 ID 是您自己的不透明标识符。如果您还想向 Singular 发送用户的电子邮件地址或电话号码,请使用单独的 SingularUserDetails API。SDK 会在设备上对这些值进行规范化并使用 SHA-256 哈希,因此原始电子邮件地址和电话号码绝不会被传输。
适用版本: Flutter SDK 1.9.1 及更高版本,其中捆绑了原生 iOS 12.14.2 和 Android 12.16.1。
选择哈希模式
提供 User Details 有两种方式。请为每个用户选择一种并保持一致。
- 由 SDK 哈希(推荐): 设置明文的电子邮件或电话号码。SDK 会规范化该值、进行哈希,并生成 Singular 可用于匹配的所有变体。
- 预先哈希: 设置您已自行规范化并使用 SHA-256 哈希的值。SDK 会原样存储,不做任何进一步处理。当您的应用在调用时不允许持有明文 User Details 时,请使用此方式。
重要: 如果您同时设置了明文值及其对应的预哈希变体,则以预哈希值为准。
SingularUserDetails 属性
SingularUserDetails 提供六个可为空的 String 属性。请仅赋值您拥有的属性,其余保持未设置。
| 属性 | 详细信息 |
|---|---|
email |
模式: 由 SDK 哈希 明文电子邮件地址。SDK 会在哈希前去除空白并转换为小写。对于 示例: |
phoneNumber |
模式: 由 SDK 哈希 明文电话号码。SDK 会生成两个变体:保留前导 示例: |
emailSTD |
模式: 预先哈希 去除空白并转换为小写后的电子邮件地址的 SHA-256 哈希值。 |
emailNoDots |
模式: 预先哈希 去除空白、转换为小写,并移除 |
phoneE164 |
模式: 预先哈希 保留前导 |
phoneDigits |
模式: 预先哈希 移除所有非数字字符(包括前导 |
在初始化时设置 User Details
在调用 Singular.start 之前,在 SingularConfig 上设置 User Details,这样它们会被附加到 SDK 发送的首个会话上。您可以直接赋值 userDetails 属性,也可以调用 withUserDetails,两者等效。
import 'package:singular_flutter_sdk/singular.dart';
import 'package:singular_flutter_sdk/singular_config.dart';
import 'package:singular_flutter_sdk/singular_user_details.dart';
SingularUserDetails userDetails = SingularUserDetails();
userDetails.email = 'user@example.com';
userDetails.phoneNumber = '+15551234567';
SingularConfig config = SingularConfig('SDK KEY', 'SDK SECRET');
config.withUserDetails(userDetails);
Singular.start(config);
方法签名:
void withUserDetails(SingularUserDetails userDetails)
注意: withUserDetails 返回 void,因此无法链接到 SingularConfig 构造函数上。请在单独的一行调用它,或直接赋值 config.userDetails。
在初始化后设置 User Details
如果只有在登录或注册之后才能获得电子邮件地址或电话号码,请在那时调用 Singular.setUserDetails。此后,这些值会被附加到 SDK 发送的每个会话和事件上。
import 'package:singular_flutter_sdk/singular.dart';
import 'package:singular_flutter_sdk/singular_user_details.dart';
// 明文值,由 SDK 哈希
SingularUserDetails userDetails = SingularUserDetails();
userDetails.email = 'user@example.com';
userDetails.phoneNumber = '+15551234567';
Singular.setUserDetails(userDetails);
// 或提供您自己的 SHA-256 哈希值
SingularUserDetails hashed = SingularUserDetails();
hashed.emailSTD = 'b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514';
hashed.phoneE164 = '8a59780bb8cd2ba022bfa5ba2ea3b6e07af17a7d8b30c1f9b3390e36f69019e4';
Singular.setUserDetails(hashed);
方法签名:
static void setUserDetails(SingularUserDetails userDetails)
清除 User Details
已存储的 User Details 会在应用多次启动之间保留在设备上,并在卸载应用时被移除。请在用户登出时,或在用户撤回同意时调用 Singular.clearUserDetails 将其移除。
import 'package:singular_flutter_sdk/singular.dart';
// 在登出时移除已存储的 User Details
Singular.clearUserDetails();
方法签名:
static void clearUserDetails()
清除已存储详细信息的三种方式。 clearUserDetails 并不是唯一的方式。使用未设置任何属性的 SingularUserDetails 对象调用 setUserDetails 同样会清除它们;使用所有值都因无效而被拒绝的对象调用时也是如此——后一种情况会清除已存储的载荷,而不是保持不变。如果您希望保留已存储的详细信息,请完全不要调用 setUserDetails。
注意: 在后续启动中设置 userDetails 不会抹除先前存储的内容,因此在您清除之前,先前存储的载荷会继续被发送。
验证与隐私行为
-
电子邮件验证: 明文电子邮件必须恰好包含一个
@,且其后须有一个点号。无效值会被拒绝并记录日志,不会被发送。 - 电话号码验证: 明文电话号码必须至少包含 6 位数字。更短的值会被拒绝并记录日志。
-
错误模式保护: 看起来已经过哈希的值会被
email和phoneNumber拒绝。同样,预哈希属性会拒绝任何不是 64 个字符 SHA-256 十六进制字符串的值。 - 存储: 哈希后的载荷保存在各平台应用自身的私有存储中,并在卸载应用时被移除。明文值绝不会被存储。
- Limit Data Sharing: 在启用 Limit Data Sharing 期间,User Details 载荷会从所有请求中排除。请参阅数据隐私。
- 同意: 仅在您有合法依据时才收集和发送电子邮件地址与电话号码。哈希并不能免除您在 GDPR、CCPA 或同等法规下的义务。