SDK de Flutter - Establecer un ID de usuario y User Details hasheados

Establecer un ID de usuario y User Details hasheados

Envíe su ID de usuario interno a Singular para permitir el seguimiento entre dispositivos y la generación de informes de datos a nivel de usuario.

Nota: Si utiliza la solución Cross-Device de Singular, debe recopilar el ID de usuario en todas las plataformas.

Requisitos de ID de usuario

Privacidad y buenas prácticas

Siga estas directrices cuando implemente el seguimiento de ID de usuario para garantizar el cumplimiento de la privacidad y la medición adecuada entre dispositivos.

  • Sin PII: El ID de usuario no debe exponer información personal identificable (PII) como direcciones de correo electrónico, nombres de usuario o números de teléfono. Utilice un valor hash único para sus datos de origen.
  • Coherencia entre plataformas: El valor del ID de usuario debe ser el mismo identificador interno que capture en todas las plataformas (Web/Móvil/PC/Consola/Offline) para una medición precisa entre dispositivos.
  • Datos de primera parte: Singular incluye el ID de Usuario en las exportaciones a nivel de usuario, ETL y postbacks de BI Interno (si está configurado). El ID de usuario es un dato de origen y no se comparte con terceros.
  • Persistencia: El ID de usuario persiste hasta que se anula explícitamente mediante unsetCustomUserId() o hasta que se desinstala la aplicación. Cerrar o reiniciar la aplicación no borra el ID de usuario.

Resumen de la implementación

Cuándo establecer el ID de usuario

Utilice Singular.setCustomUserId() para establecer el identificador de usuario y Singular.unsetCustomUserId() para borrarlo durante el cierre de sesión.

Práctica recomendada: Si varios usuarios comparten un mismo dispositivo, implementa un flujo de cierre de sesión que llame a setCustomUserId() al iniciar sesión y a unsetCustomUserId() al finalizarla.

Si ya conoce el identificador de usuario cuando se abre la aplicación, configúrelo mediante la propiedad customUserId antes de inicializar Singular SDK. Esto garantiza que Singular reciba el ID de usuario desde la primera sesión. Sin embargo, el ID de usuario no suele estar disponible hasta que el usuario se registra o inicia sesión, en cuyo caso llame a setCustomUserId() una vez finalizado el flujo de registro o autenticación.


Métodos SDK

Establecer ID de usuario personalizado

Envíe su ID de usuario interno a Singular para el seguimiento entre dispositivos y la generación de informes a nivel de usuario.

Dart
import 'package:singular_flutter_sdk/singular.dart';

// Set the user ID after login or registration
Singular.setCustomUserId('user_123456');

Firma del método:

static void setCustomUserId(String customUserId)

Ejemplo: Establecer ID de usuario después del inicio de sesión

Llame a setCustomUserId() inmediatamente después de que el usuario complete con éxito la autenticación para asegurarse de que todos los eventos posteriores se asocian con su ID de usuario.

Dart
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');
  }
}

Desactivar ID de usuario personalizado

Borre el ID de usuario cuando un usuario cierre la sesión para garantizar un seguimiento preciso de la sesión en dispositivos multiusuario.

Dart
import 'package:singular_flutter_sdk/singular.dart';

// Unset the user ID on logout
Singular.unsetCustomUserId();

Firma del método:

static void unsetCustomUserId()

Ejemplo: Anulación del ID de usuario al cerrar la sesión

Llame a unsetCustomUserId() durante el flujo de cierre de sesión para borrar el ID de usuario y evitar la atribución incorrecta de eventos posteriores.

Dart
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');
  }
}

Establecer ID de usuario durante la inicialización

Si el ID de usuario está disponible cuando se inicia la aplicación (por ejemplo, el usuario ya ha iniciado sesión), configúrelo durante la inicialización del SDK utilizando la propiedad customUserId. Esto asegura que la primera sesión incluya el ID de usuario.

Dart
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(),
    );
  }
}

Propiedad de configuración:

String? customUserId

Recomendación: Utilice la propiedad de configuración customUserIddurante la inicialización para aplicaciones con sesiones de inicio de sesión persistentes. Para aplicaciones en las que los usuarios deben iniciar sesión cada vez, llame a setCustomUserId() después de la autenticación.


User Details hasheados (correo electrónico y teléfono)

El ID de usuario anterior es tu propio identificador opaco. Si además quieres enviar a Singular la dirección de correo electrónico o el número de teléfono del usuario, usa la API independiente SingularUserDetails. El SDK normaliza y aplica SHA-256 a estos valores en el dispositivo, de modo que la dirección de correo y el número de teléfono originales nunca se transmiten.

Disponibilidad: SDK de Flutter versión 1.9.1 y posteriores, que incluye las versiones nativas iOS 12.14.2 y Android 12.16.1.

Elegir un modo de hasheo

Hay dos formas de proporcionar los User Details. Elige una por usuario y mantén la coherencia.

  • Hasheado por el SDK (recomendado): Establece el correo electrónico o el número de teléfono en texto plano. El SDK normaliza el valor, lo hashea y genera todas las variantes con las que Singular puede hacer coincidencias.
  • Pre-hasheado: Establece valores que ya hayas normalizado y hasheado con SHA-256. El SDK los almacena tal cual y no realiza ningún procesamiento adicional. Úsalo cuando tu app no pueda manejar User Details en texto plano en el momento de la llamada.

Importante: Si estableces tanto un valor en texto plano como su variante pre-hasheada correspondiente, prevalece el valor pre-hasheado.

Propiedades de SingularUserDetails

SingularUserDetails expone seis propiedades String nullable. Asigna las que tengas y deja las demás sin establecer.

Propiedad Detalles
email

Modo: Hasheado por el SDK

Dirección de correo electrónico en texto plano. El SDK recorta los espacios y convierte el valor a minúsculas antes de hashearlo. Para las direcciones gmail.com y googlemail.com también genera una segunda variante sin el sufijo +tag y sin los puntos de la parte local.

Ejemplo: user@example.com

phoneNumber

Modo: Hasheado por el SDK

Número de teléfono en texto plano. El SDK genera dos variantes: una en formato E.164 que conserva el + inicial y elimina los demás caracteres no numéricos, y otra solo con dígitos que también elimina el +. Incluye el código de país para que la variante E.164 sea utilizable.

Ejemplo: +15551234567

emailSTD

Modo: Pre-hasheado

Hash SHA-256 de la dirección de correo electrónico después de recortarla y convertirla a minúsculas.

emailNoDots

Modo: Pre-hasheado

Hash SHA-256 de la dirección de correo electrónico después de recortarla, convertirla a minúsculas y eliminar el sufijo +tag y todos los puntos de la parte local. Se aplica a las direcciones de tipo Gmail.

phoneE164

Modo: Pre-hasheado

Hash SHA-256 del número de teléfono en formato E.164, conservando el + inicial.

phoneDigits

Modo: Pre-hasheado

Hash SHA-256 del número de teléfono con todos los caracteres no numéricos eliminados, incluido el + inicial.


Establecer los User Details en la inicialización

Establece los User Details en tu SingularConfig antes de llamar a Singular.start para que se adjunten a la primera sesión que envíe el SDK. Puedes asignar directamente la propiedad userDetails o llamar a withUserDetails; ambas opciones son equivalentes.

Dart
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);

Firma del método:

void withUserDetails(SingularUserDetails userDetails)

Nota: withUserDetails devuelve void, por lo que no se puede encadenar al constructor de SingularConfig. Llámalo en su propia línea o asigna directamente config.userDetails.


Establecer los User Details después de la inicialización

Si la dirección de correo electrónico o el número de teléfono solo se conocen después del inicio de sesión o el registro, llama a Singular.setUserDetails en ese momento. A partir de entonces, los valores se adjuntan a todas las sesiones y eventos que envíe el SDK.

Dart
import 'package:singular_flutter_sdk/singular.dart';
import 'package:singular_flutter_sdk/singular_user_details.dart';

// Valores en texto plano, hasheados por el SDK
SingularUserDetails userDetails = SingularUserDetails();
userDetails.email = 'user@example.com';
userDetails.phoneNumber = '+15551234567';
Singular.setUserDetails(userDetails);

// O proporciona tus propios hashes SHA-256
SingularUserDetails hashed = SingularUserDetails();
hashed.emailSTD = 'b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514';
hashed.phoneE164 = '8a59780bb8cd2ba022bfa5ba2ea3b6e07af17a7d8b30c1f9b3390e36f69019e4';
Singular.setUserDetails(hashed);

Firma del método:

static void setUserDetails(SingularUserDetails userDetails)

Borrar los User Details

Los User Details almacenados persisten en el dispositivo entre inicios de la app y se eliminan al desinstalarla. Llama a Singular.clearUserDetails al cerrar sesión, o cuando el usuario retire su consentimiento, para eliminarlos.

Dart
import 'package:singular_flutter_sdk/singular.dart';

// Eliminar los User Details almacenados al cerrar sesión
Singular.clearUserDetails();

Firma del método:

static void clearUserDetails()

Tres formas de borrar los datos almacenados. clearUserDetails no es la única. Llamar a setUserDetails con un objeto SingularUserDetails que no tenga ninguna propiedad establecida también los borra, al igual que llamarlo con un objeto cuyos valores sean todos rechazados por inválidos: en ese último caso se borra el payload almacenado en lugar de dejarlo intacto. Si tu intención es no tocar los datos almacenados, no llames a setUserDetails en absoluto.

Nota: Establecer userDetails en un inicio posterior no borra lo que se almacenó antes, por lo que un payload almacenado previamente se sigue enviando hasta que lo borres.


Validación y comportamiento de privacidad

  • Validación del correo electrónico: Un correo electrónico en texto plano debe contener exactamente una @ y un punto después de ella. Los valores inválidos se rechazan y se registran, y no se envían.
  • Validación del teléfono: Un número de teléfono en texto plano debe contener al menos 6 dígitos. Los valores más cortos se rechazan y se registran.
  • Protección contra modo incorrecto: Un valor que ya parece hasheado es rechazado por email y phoneNumber. Del mismo modo, las propiedades pre-hasheadas rechazan cualquier valor que no sea una cadena hexadecimal SHA-256 de 64 caracteres.
  • Almacenamiento: El payload hasheado se guarda en el almacenamiento privado de la app en cada plataforma y se elimina al desinstalarla. Los valores en texto plano nunca se almacenan.
  • Limit Data Sharing: Mientras Limit Data Sharing esté activado, el payload de User Details se excluye de todas las solicitudes. Consulta Privacidad de datos.
  • Consentimiento: Recopila y envía direcciones de correo electrónico y números de teléfono solo cuando tengas una base legal para hacerlo. El hasheo no elimina tus obligaciones bajo el GDPR, la CCPA o normativas equivalentes.