SDK do React Native - Privacidade de dados

Documento

Conformidade com as leis de privacidade de dados

Implementar a recolha de dados em conformidade com a privacidade, notificando a Singular das escolhas de consentimento do utilizador para GDPR, CCPA, COPPA e outros regulamentos de privacidade do consumidor.

Quando os utilizadores consentirem ou recusarem a partilha das suas informações com terceiros, utilize os métodos de privacidade da Singular para comunicar a sua escolha. Isto assegura a conformidade com regulamentos como o California Consumer Privacy Act (CCPA)e permite que os parceiros respeitem as preferências de privacidade dos utilizadores.

Saiba mais: Consulte Privacidade do usuário e Limitar compartilhamento de dadospara obter informações detalhadas sobre como a Singular processa o consentimento de privacidade.


Limitar a partilha de dados

Controlar o compartilhamento de dados de terceiros

Notificar a Singular se os usuários consentiram em compartilhar seus dados pessoais com parceiros terceiros usando o método limitDataSharing().

Assinatura do método:

static limitDataSharing(shouldLimitDataSharing: boolean): void

Parâmetros:

  • false: O utilizador optou e consentiu a partilha dos seus dados
  • true: O utilizador optou por não participar e não consente a partilha dos seus dados

Importante: Embora opcional, este método afecta a partilha de dados de atribuição. Alguns parceiros só partilham informações de atribuição completas quando são explicitamente notificados de que os utilizadores optaram por participar.

Para obter a documentação completa do método, consulte a referência limitDataSharing.


Exemplos de utilização

Implementar controlos de partilha de dados com base nas preferências de privacidade do utilizador.

New AchitectureOld Achitecture
// TurboModule direct API (React Native 0.76+ New Architecture)
import NativeSingular from 'singular-react-native/jsNativeSingular';

// User has opted in to share their data
export const onUserOptedInToDataSharing = () => {
  NativeSingular.limitDataSharing(false);
  console.log('Data sharing enabled');
};

// User has opted out and declined to share their data
export const onUserOptedOutOfDataSharing = () => {
  NativeSingular.limitDataSharing(true);
  console.log('Data sharing limited');
};

// Set based on user preference
export const handlePrivacyConsent = (userConsented) => {
  // Pass inverse: false = opted in, true = opted out
  NativeSingular.limitDataSharing(!userConsented);

  console.log(`Data sharing: ${userConsented ? 'Enabled' : 'Limited'}`);
};

Como funciona:

A Singular usa essa configuração em Postbacks de privacidade do usuárioe a passa para parceiros que a exigem para conformidade regulatória.


Métodos de conformidade com o GDPR

Gerencie o consentimento de rastreamento do usuário e controle a funcionalidade do SDK para estar em conformidade com o GDPR (Regulamento Geral de Proteção de Dados) e outros regulamentos de privacidade.

Gestão do consentimento de rastreio

TrackingOptIn

Regista o consentimento explícito do utilizador para o rastreio, enviando um evento GDPR opt-in para os servidores Singular.

Assinatura do método:

static trackingOptIn(): void

Quando usar:

  • Conformidade com o GDPR: Chamar quando os usuários consentirem explicitamente com o rastreamento em regiões regulamentadas pelo GDPR
  • Registro de consentimento: Marca os usuários como tendo fornecido consentimento GDPR nos sistemas da Singular
  • Comportamento padrão: Sem esta chamada, o SDK continua a rastrear mas não regista especificamente o consentimento

Para obter a documentação completa do método, consulte a referência trackingOptIn.


Exemplo de implementação

Chame trackingOptIn() depois de os utilizadores aceitarem o consentimento de rastreio através da caixa de diálogo de consentimento da sua aplicação.

New AchitectureOld Achitecture
// TurboModule direct API (React Native 0.76+ New Architecture)
import React, { useState, useEffect } from 'react';
import { View, Text, Button, Alert } from 'react-native';
import NativeSingular from 'singular-react-native/jsNativeSingular';
import AsyncStorage from '@react-native-async-storage/async-storage';

export default function GDPRManager() {
  const [hasConsent, setHasConsent] = useState(null);

  useEffect(() => {
    checkStoredConsent();
  }, []);

  const checkStoredConsent = async () => {
    try {
      const consent = await AsyncStorage.getItem('gdpr_consent');
      if (consent === null) {
        // Show consent dialog
        showGDPRConsentDialog();
      } else {
        setHasConsent(consent === 'true');
      }
    } catch (error) {
      console.error('Error checking consent:', error);
    }
  };

  const showGDPRConsentDialog = () => {
    Alert.alert(
      'Privacy Consent',
      'We would like your permission to track app usage and improve your experience.',
      [
        {
          text: 'Accept',
          onPress: onUserAcceptedTracking
        },
        {
          text: 'Decline',
          style: 'cancel',
          onPress: () => setHasConsent(false)
        }
      ]
    );
  };

  const onUserAcceptedTracking = async () => {
    // Record user consent
    NativeSingular.trackingOptIn();
    console.log('User opted in to tracking');

    // Save preference
    await AsyncStorage.setItem('gdpr_consent', 'true');
    setHasConsent(true);
  };

  return (
    <View>
      {hasConsent !== null && (
        <Text>Privacy Status: {hasConsent ? 'Opted In' : 'Declined'}</Text>
      )}
    </View>
  );
}

Métodos de controlo de rastreio

StopAllTracking

Desactiva completamente todas as actividades de rastreio do SDK para o utilizador atual neste dispositivo.

Assinatura do método:

static stopAllTracking(): void

Crítico Aviso: Este método desactiva permanentemente o SDK até que resumeAllTracking() seja chamado. O estado de desativação persiste durante as reinicializações da aplicação e só pode ser revertido programaticamente.

Comportamento:

  • Efeito imediato: Interrompe todo o rastreamento, relatório de eventos e coleta de dados instantaneamente
  • Estado persistente: Permanece desativado mesmo depois de a aplicação ser fechada e reaberta
  • Sem reinicialização automática: Tem de chamar explicitamente resumeAllTracking() para voltar a ativar

Para obter a documentação completa do método, consulte a referência stopAllTracking.


Exemplo de implementação

Parar o rastreio quando os utilizadores recusam o consentimento ou optam por sair através das definições de privacidade.

New AchitectureOld Achitecture
// TurboModule direct API (React Native 0.76+ New Architecture)
import NativeSingular from 'singular-react-native/jsNativeSingular';
import AsyncStorage from '@react-native-async-storage/async-storage';

// User declined all tracking
export const onUserDeclinedTracking = async () => {
  NativeSingular.stopAllTracking();
  console.log('All tracking stopped');

  // Store preference
  await AsyncStorage.setItem('tracking_enabled', 'false');
};

// Handle user opt-out from settings menu
export const handlePrivacySettingsChange = (trackingEnabled) => {
  if (!trackingEnabled) {
    NativeSingular.stopAllTracking();
    console.log('Privacy settings: Tracking disabled');
  }
};

RetomarTudoRastreio

Reativar o rastreio depois de ter sido interrompido com stopAllTracking().

Assinatura do método:

static resumeAllTracking(): void

Casos de utilização:

  • Alteração de consentimento: O utilizador altera as preferências de privacidade e volta a optar pelo rastreio
  • Definições de privacidade: O utilizador actualiza o consentimento através do menu de definições da aplicação
  • Conformidade regional: Voltar a ativar o rastreio quando o utilizador se desloca para regiões não regulamentadas

Para obter a documentação completa do método, consulte a referência resumeAllTracking.


Exemplo de implementação

Retomar o rastreio quando os utilizadores optarem por voltar a participar ou actualizarem as suas preferências de privacidade.

New AchitectureOld Achitecture
// TurboModule direct API (React Native 0.76+ New Architecture)
import NativeSingular from 'singular-react-native/jsNativeSingular';
import AsyncStorage from '@react-native-async-storage/async-storage';

// User opted back in to tracking
export const onUserResumedTracking = async () => {
  NativeSingular.resumeAllTracking();
  console.log('Tracking resumed');

  // Update stored preference
  await AsyncStorage.setItem('tracking_enabled', 'true');
};

// Handle consent update from settings
export const handlePrivacySettingsChange = (trackingEnabled) => {
  if (trackingEnabled) {
    NativeSingular.resumeAllTracking();
    console.log('Privacy settings: Tracking enabled');
  }
};

IsAllTrackingStopped

Verificar se o rastreio foi desativado para o utilizador atual.

Assinatura do método:

static isAllTrackingStopped(): Promise<boolean>

Retorna:

  • Promise<true>: O rastreamento está atualmente parado via stopAllTracking()
  • Promessa<false>: O rastreio está ativo (nunca parou ou foi retomado)

Para obter a documentação completa do método, consulte a referência isAllTrackingStopped.


Exemplo de implementação

Verificar o estado do rastreio para sincronizar o estado da IU com o estado do rastreio do SDK.

New AchitectureOld Achitecture
// TurboModule direct API (React Native 0.76+ New Architecture)
import React, { useState, useEffect } from 'react';
import { View, Text, Switch } from 'react-native';
import NativeSingular from 'singular-react-native/jsNativeSingular';

export default function PrivacySettingsUI() {
  const [trackingEnabled, setTrackingEnabled] = useState(false);
  const [statusText, setStatusText] = useState('Checking...');

  useEffect(() => {
    updatePrivacyUI();
  }, []);

  // Check current tracking status
  const isTrackingEnabled = async () => {
    const isStopped = await NativeSingular.isAllTrackingStopped();
    return !isStopped;
  };

  // Display privacy status in settings
  const getPrivacyStatusText = async () => {
    const isStopped = await NativeSingular.isAllTrackingStopped();
    return isStopped ? 'Tracking: Disabled' : 'Tracking: Enabled';
  };

  // Sync UI with tracking state
  const updatePrivacyUI = async () => {
    const isStopped = await NativeSingular.isAllTrackingStopped();
    setTrackingEnabled(!isStopped);

    const status = await getPrivacyStatusText();
    setStatusText(status);

    console.log(`Current tracking state: ${isStopped ? 'Stopped' : 'Active'}`);
  };

  // Handle toggle change from UI
  const onTrackingToggleChanged = async (enabled) => {
    if (enabled) {
      NativeSingular.resumeAllTracking();
    } else {
      NativeSingular.stopAllTracking();
    }

    await updatePrivacyUI();
  };

  return (
    <View>
      <Text>{statusText}</Text>
      <Switch
        value={trackingEnabled}
        onValueChange={onTrackingToggleChanged}
      />
    </View>
  );
}

Proteção da privacidade das crianças

TrackingUnder13

Notifica a Singular de que o utilizador tem menos de 13 anos de idade para cumprir a COPPA (Children's Online Privacy Protection Act) e outros regulamentos de privacidade infantil.

Assinatura do método:

static trackingUnder13(): void

Requisitos de conformidade:

  • Conformidade com a COPPA: Necessário para aplicações que recolhem dados de crianças com menos de 13 anos nos Estados Unidos
  • Conteúdo com limite de idade: Utilizar quando os utilizadores se identificam como tendo menos de 13 anos durante o registo ou a verificação da idade
  • Rastreio restrito: Limita a recolha de dados para cumprir as leis de proteção da privacidade das crianças

Para obter a documentação completa do método, consulte a referência trackingUnder13.


Exemplo de implementação

Chame trackingUnder13() imediatamente após determinar que o utilizador tem menos de 13 anos através da verificação da idade.

New AchitectureOld Achitecture
// TurboModule direct API (React Native 0.76+ New Architecture)
import React, { useState } from 'react';
import { View, TextInput, Button, Alert } from 'react-native';
import NativeSingular from 'singular-react-native/jsNativeSingular';
import AsyncStorage from '@react-native-async-storage/async-storage';

export default function COPPAManager() {
  const [age, setAge] = useState('');

  // User identified as under 13
  const onUserUnder13 = async () => {
    NativeSingular.trackingUnder13();
    console.log('COPPA mode enabled for user under 13');

    // Store age category for app restart
    await AsyncStorage.setItem('user_age_category', 'under_13');
  };

  // Call after age verification
  const onAgeVerified = async (userAge) => {
    if (userAge < 13) {
      NativeSingular.trackingUnder13();
      console.log('COPPA restrictions applied');

      // Also limit advertising identifiers
      NativeSingular.setLimitAdvertisingIdentifiers(true);

      await AsyncStorage.setItem('user_age_category', 'under_13');

      Alert.alert('Child Account', 'Special privacy protections have been applied.');
    } else {
      await AsyncStorage.setItem('user_age_category', 'adult');
      console.log('Adult account - standard tracking');
    }
  };

  const handleAgeSubmit = () => {
    const userAge = parseInt(age, 10);

    if (isNaN(userAge) || userAge < 1 || userAge > 120) {
      Alert.alert('Invalid Age', 'Please enter a valid age.');
      return;
    }

    onAgeVerified(userAge);
  };

  return (
    <View>
      <TextInput
        placeholder="Enter your age"
        value={age}
        onChangeText={setAge}
        keyboardType="number-pad"
      />
      <Button title="Submit" onPress={handleAgeSubmit} />
    </View>
  );
}

Importante: Chame este método o mais cedo possível depois de determinar que o utilizador tem menos de 13 anos, idealmente durante a inicialização da aplicação ou imediatamente após a verificação da idade. Isso garante que todo o rastreamento subsequente respeite os regulamentos de privacidade das crianças.


SetLimitAdvertisingIdentifiers

Restringe a coleta e o uso de identificadores de publicidade (GAID no Android, IDFA no iOS) após a inicialização do SDK para aplicativos de público misto.

Assinatura do método:

static setLimitAdvertisingIdentifiers(isEnabled: boolean): void

Parâmetros:

  • true: Ativar o modo de identificadores de publicidade limitados (restringir a recolha)
  • false: Desativar o modo de identificadores de publicidade limitados (recolha normal)

Casos de uso:

  • Aplicações de público misto: Aplicações que servem tanto adultos como crianças, em que a idade é determinada após o lançamento da aplicação
  • Controlos de privacidade dinâmicos: Ajustar o rastreio com base nas acções do utilizador ou no conteúdo acedido
  • Restrições de tempo de execução: Aplicar limitações de identificadores de publicidade após a configuração inicial do SDK

Para obter a documentação completa do método, consulte a referência setLimitAdvertisingIdentifiers.


Exemplo de implementação

Limitar dinamicamente os identificadores de publicidade com base na idade do utilizador, no tipo de conteúdo ou no modo de aplicação.

New AchitectureOld Achitecture
// TurboModule direct API (React Native 0.76+ New Architecture)
import NativeSingular from 'singular-react-native/jsNativeSingular';

// Limit advertising identifiers after initialization
export const enableLimitedMode = () => {
  NativeSingular.setLimitAdvertisingIdentifiers(true);
  console.log('Advertising identifiers limited');
};

// Mixed audience app with age gate
export const onKidsModeSwitched = (isKidsMode) => {
  if (isKidsMode) {
    NativeSingular.setLimitAdvertisingIdentifiers(true);
    console.log('Advertising identifiers limited for kids mode');
  } else {
    NativeSingular.setLimitAdvertisingIdentifiers(false);
    console.log('Advertising identifiers unrestricted for adult mode');
  }
};

// Content-based restrictions
export const onViewingChildrensContent = () => {
  NativeSingular.setLimitAdvertisingIdentifiers(true);
  console.log('Ad identifiers restricted for children\'s content');
};

// Combined with TrackingUnder13
export const onAgeVerified = (age) => {
  if (age < 13) {
    NativeSingular.trackingUnder13();
    NativeSingular.setLimitAdvertisingIdentifiers(true);
    console.log('Full COPPA restrictions applied');
  }
};

Alternativa de configuração: Também pode limitar os identificadores de publicidade durante a inicialização do SDK definindo a opção de configuração limitAdvertisingIdentifiers se conhecer os requisitos de privacidade antes do início do SDK.


Propriedade de configuração

Defina limitações de identificadores de publicidade durante a inicialização do SDK para aplicações que conhecem os requisitos de privacidade antecipadamente.

New AchitectureOld Achitecture
// TurboModule direct API (React Native 0.76+ New Architecture)
import NativeSingular from 'singular-react-native/jsNativeSingular';

// Limit advertising identifiers at initialization
const config: SingularConfig = {
  apikey: 'YOUR_SDK_KEY',
  secret: 'YOUR_SDK_SECRET',
  limitAdvertisingIdentifiers: true
};

NativeSingular.init(config);

Para obter a documentação de configuração completa, consulte a referência withLimitAdvertisingIdentifiers.


Melhores práticas de implementação

Exemplo de gestão de privacidade completa

Implemente controlos de privacidade abrangentes que respeitem as preferências do utilizador e cumpram os regulamentos.

New AchitectureOld Achitecture
// TurboModule direct API (React Native 0.76+ New Architecture)
import React, { useEffect } from 'react';
import NativeSingular from 'singular-react-native/jsNativeSingular';
import AsyncStorage from '@react-native-async-storage/async-storage';

const PREF_USER_CONSENT = 'privacy_user_consent';
const PREF_DATA_SHARING = 'privacy_data_sharing';
const PREF_AGE_CATEGORY = 'user_age_category';

/**
 * Initialize privacy settings on app startup based on stored preferences
 */
export const initializePrivacySettings = async () => {
  const hasUserConsent = await getUserConsent();
  const allowDataSharing = await getDataSharingPreference();
  const ageCategory = await getAgeCategory();

  // Apply age-based restrictions first
  if (ageCategory === 'under_13') {
    NativeSingular.trackingUnder13();
    NativeSingular.setLimitAdvertisingIdentifiers(true);
    console.log('COPPA restrictions applied on startup');
  }

  // Apply stored tracking preference
  if (hasUserConsent) {
    NativeSingular.trackingOptIn();
    NativeSingular.resumeAllTracking();
    console.log('Privacy initialized: Tracking enabled with consent');
  } else {
    NativeSingular.stopAllTracking();
    console.log('Privacy initialized: Tracking disabled');
  }

  // Set data sharing preference (inverse logic)
  NativeSingular.limitDataSharing(!allowDataSharing);

  console.log(`Privacy initialized: consent=${hasUserConsent}, sharing=${allowDataSharing}`);
};

/**
 * User accepts tracking via consent dialog
 */
export const onUserAcceptedTracking = async () => {
  await saveUserConsent(true);

  NativeSingular.trackingOptIn();
  NativeSingular.resumeAllTracking();

  console.log('User accepted tracking');
};

/**
 * User declines tracking
 */
export const onUserDeclinedTracking = async () => {
  await saveUserConsent(false);

  NativeSingular.stopAllTracking();

  console.log('User declined tracking');
};

/**
 * User updates data sharing preference
 */
export const setDataSharingEnabled = async (enabled) => {
  await saveDataSharingPreference(enabled);

  // Note: LimitDataSharing uses inverse logic
  // false = data sharing enabled, true = data sharing limited
  NativeSingular.limitDataSharing(!enabled);

  console.log(`Data sharing: ${enabled ? 'Enabled' : 'Limited'}`);
};

/**
 * Check if tracking is currently enabled
 */
export const isTrackingEnabled = async () => {
  const isStopped = await NativeSingular.isAllTrackingStopped();
  return !isStopped;
};

/**
 * Get current privacy status as readable text
 */
export const getPrivacyStatus = async () => {
  const isEnabled = await isTrackingEnabled();
  const dataSharingEnabled = await getDataSharingPreference();
  const ageCategory = await getAgeCategory();

  let status = `Tracking: ${isEnabled ? 'Enabled' : 'Disabled'}\n`;
  status += `Data Sharing: ${dataSharingEnabled ? 'Enabled' : 'Limited'}`;

  if (ageCategory === 'under_13') {
    status += '\nCOPPA: Restrictions Applied';
  }

  return status;
};

// Private helper methods for AsyncStorage

const getUserConsent = async () => {
  const value = await AsyncStorage.getItem(PREF_USER_CONSENT);
  return value === 'true';
};

const saveUserConsent = async (consent) => {
  await AsyncStorage.setItem(PREF_USER_CONSENT, consent.toString());
};

const getDataSharingPreference = async () => {
  const value = await AsyncStorage.getItem(PREF_DATA_SHARING);
  return value === 'true';
};

const saveDataSharingPreference = async (enabled) => {
  await AsyncStorage.setItem(PREF_DATA_SHARING, enabled.toString());
};

const getAgeCategory = async () => {
  return await AsyncStorage.getItem(PREF_AGE_CATEGORY);
};

// React component example
export default function PrivacyInitializer() {
  useEffect(() => {
    initializePrivacySettings();
  }, []);

  return null;
}

Principais diretrizes de implementação

Melhores práticas:

  • Armazenamento persistente: Guardar as preferências do utilizador utilizando o AsyncStorage ou uma solução de armazenamento seguro
  • Inicialização antecipada: Aplicar configurações de privacidade antes da inicialização do SDK, quando possível
  • Sincronização da IU: Manter as configurações da interface do usuário sincronizadas com o estado real do SDK usando isAllTrackingStopped()
  • Comunicação clara: Fornecer controlos de privacidade claros e acessíveis nas definições da aplicação
  • Lógica inversa: Lembre-se de que limitDataSharing(false) significa que a partilha de dados está activada, enquanto true significa que está limitada
  • Prioridade COPPA: Aplicar as protecções de privacidade das crianças (trackingUnder13()) antes de outras definições de privacidade
  • Documentação de conformidade: Manter registos de quando e como os utilizadores fornecem ou revogam o consentimento