Rastreamento de desinstalação
Rastreie desinstalações de aplicativos para medir a retenção de usuários e otimizar campanhas de reengajamento integrando serviços de notificação por push com o SDK Singular.
Importante: o Google descontinuou as APIs do GCM em abril de 2018. Use o Firebase Cloud Messaging (FCM) para todas as implementações de rastreamento de desinstalação do Android.
Rastreamento de desinstalação do Android
Pré-requisitos
Antes de implementar o rastreamento de desinstalação em seu aplicativo React Native, configure seu aplicativo na plataforma Singular seguindo o guia Configurando o rastreamento de desinstalação do Android.
Requisitos do sistema
O rastreamento de desinstalação requer o Firebase Cloud Messaging e configurações específicas do dispositivo.
Requisitos do FCM(fonte):
- Versão do Android: Os dispositivos devem executar o Android 4.1 (API 16) ou superior
- Serviços do Google Play: Os dispositivos devem ter o aplicativo Google Play Store instalado
- Suporte de emulador: São suportados emuladores Android 4.1+ com APIs do Google
- Distribuição: As aplicações podem ser distribuídas fora da Google Play Store, continuando a suportar o controlo de desinstalações
Nota: os utilizadores de versões do Android não suportadas ou de dispositivos sem o Google Play Services não serão rastreados para desinstalações.
Etapas de implementação
Etapa 1: instalar os pacotes do Firebase
Adicione as dependências do React Native Firebase para a funcionalidade principal e o suporte a mensagens.
npm install @react-native-firebase/app
npm install @react-native-firebase/messaging
Etapa 2: Configurar o Firebase
Adicione os arquivos de configuração do Firebase ao seu projeto React Native para Android.
- Registre seu aplicativo Android no projeto do Console do Firebase
-
Baixe
google-services.jsone coloque-o emandroid/app/ - Verifique se as dependências de mensagens do Firebase foram adicionadas ao seu projeto
Para obter instruções detalhadas de configuração, consulte Configuração do React Native Firebase para Android.
Etapa 3: solicitar permissão de notificação
Solicite permissões de notificação do usuário (necessário para Android 13+) antes de recuperar o token FCM.
import messaging from '@react-native-firebase/messaging';
import { Platform, PermissionsAndroid } from 'react-native';
async function requestNotificationPermission() {
if (Platform.OS === 'android') {
if (Platform.Version >= 33) {
// Android 13+ requires explicit permission request
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
);
return granted === PermissionsAndroid.RESULTS.GRANTED;
}
// Android 12 and below automatically have permission
return true;
}
// iOS permission handled separately
return true;
}
Etapa 4: recuperar e registrar o token FCM
Obtenha o token de dispositivo FCM e registe-o no Singular utilizando setUninstallToken() depois de pedir permissões.
// TurboModule direct API (React Native 0.76+ New Architecture)
import React, { useEffect } from 'react';
import NativeSingular from 'singular-react-native/jsNativeSingular';
import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';
export default function App() {
useEffect(() => {
if (Platform.OS === 'android') {
initializeAndroidUninstallTracking();
}
}, []);
async function initializeAndroidUninstallTracking() {
try {
// Request notification permission (Android 13+)
const hasPermission = await requestNotificationPermission();
if (!hasPermission) {
console.warn('Notification permission denied - uninstall tracking unavailable');
return;
}
// Get FCM token
const token = await messaging().getToken();
if (token) {
// Register token with Singular for uninstall tracking
NativeSingular.setUninstallToken(token);
console.log('FCM token registered with Singular:', token);
} else {
console.warn('No FCM token available');
}
} catch (error) {
console.error('Error setting up uninstall tracking:', error);
}
}
async function requestNotificationPermission() {
// Implementation from Step 3 above
if (Platform.Version >= 33) {
const { PermissionsAndroid } = require('react-native');
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
);
return granted === PermissionsAndroid.RESULTS.GRANTED;
}
return true;
}
return (
// Your app components
null
);
}
import React, { useEffect } from 'react';
import { Singular } from 'singular-react-native';
import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';
export default function App() {
useEffect(() => {
if (Platform.OS === 'android') {
initializeAndroidUninstallTracking();
}
}, []);
async function initializeAndroidUninstallTracking() {
try {
// Request notification permission (Android 13+)
const hasPermission = await requestNotificationPermission();
if (!hasPermission) {
console.warn('Notification permission denied - uninstall tracking unavailable');
return;
}
// Get FCM token
const token = await messaging().getToken();
if (token) {
// Register token with Singular for uninstall tracking
Singular.setUninstallToken(token);
console.log('FCM token registered with Singular:', token);
} else {
console.warn('No FCM token available');
}
} catch (error) {
console.error('Error setting up uninstall tracking:', error);
}
}
async function requestNotificationPermission() {
// Implementation from Step 3 above
if (Platform.Version >= 33) {
const { PermissionsAndroid } = require('react-native');
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
);
return granted === PermissionsAndroid.RESULTS.GRANTED;
}
return true;
}
return (
// Your app components
);
}
Para obter a documentação completa do método, consulte a referência setUninstallToken.
Etapa 5: tratar a atualização do token
Atualize o token FCM com o Singular sempre que ele for atualizado para manter o rastreamento preciso da desinstalação.
// TurboModule direct API (React Native 0.76+ New Architecture)
import React, { useEffect } from 'react';
import NativeSingular from 'singular-react-native/jsNativeSingular';
import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';
export default function App() {
useEffect(() => {
if (Platform.OS === 'android') {
// Set up token refresh listener
const unsubscribe = messaging().onTokenRefresh((token) => {
console.log('FCM token refreshed:', token);
// Update Singular with new token
NativeSingular.setUninstallToken(token);
});
// Clean up listener on unmount
return () => unsubscribe();
}
}, []);
return (
// Your app components
null
);
}
import React, { useEffect } from 'react';
import { Singular } from 'singular-react-native';
import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';
export default function App() {
useEffect(() => {
if (Platform.OS === 'android') {
// Set up token refresh listener
const unsubscribe = messaging().onTokenRefresh((token) => {
console.log('FCM token refreshed:', token);
// Update Singular with new token
Singular.setUninstallToken(token);
});
// Clean up listener on unmount
return () => unsubscribe();
}
}, []);
return (
// Your app components
);
}
Melhores práticas: Os tokens FCM podem ser atualizados a qualquer momento (atualizações de aplicativos, restauração de dispositivos, etc.). Sempre assine o evento onTokenRefresh para manter o Singular atualizado com o token mais recente.
Rastreamento de desinstalação do iOS
Pré-requisitos
Configure seu aplicativo iOS na plataforma Singular seguindo o guia Configurando o rastreamento de desinstalação do iOS.
O rastreamento de desinstalação no iOS é baseado na tecnologia do serviço de notificação por push da Apple (APNs). Se o seu aplicativo não for compatível com notificações por push, consulte o guia da Apple para Registrar seu aplicativo com APNs.
Passos de implementação
Etapa 1: Solicitar autorização de notificação do iOS
Solicite permissões de notificação ao utilizador e recupere o token de dispositivo APNS.
import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';
async function requestIOSNotificationPermission() {
if (Platform.OS !== 'ios') {
return false;
}
try {
const authStatus = await messaging().requestPermission();
const enabled =
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
if (enabled) {
console.log('iOS notification authorization status:', authStatus);
return true;
}
return false;
} catch (error) {
console.error('Error requesting iOS notification permission:', error);
return false;
}
}
Passo 2: Recuperar e registar o Token APNS
Obtenha o token de dispositivo APNS e registre-o no Singular usando setUninstallToken() após a autorização ser concedida.
// TurboModule direct API (React Native 0.76+ New Architecture)
import React, { useEffect } from 'react';
import NativeSingular from 'singular-react-native/jsNativeSingular';
import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';
export default function App() {
useEffect(() => {
if (Platform.OS === 'ios') {
initializeIOSUninstallTracking();
}
}, []);
async function initializeIOSUninstallTracking() {
try {
// Request notification authorization
const hasPermission = await requestIOSNotificationPermission();
if (!hasPermission) {
console.warn('Notification permission denied - uninstall tracking unavailable');
return;
}
// Register for remote notifications (required for APNS)
await messaging().registerDeviceForRemoteMessages();
// Get APNS token
const apnsToken = await messaging().getAPNSToken();
if (apnsToken) {
// Register token with Singular for uninstall tracking
NativeSingular.setUninstallToken(apnsToken);
console.log('APNS token registered with Singular:', apnsToken);
} else {
console.warn('No APNS token available');
}
} catch (error) {
console.error('Error setting up iOS uninstall tracking:', error);
}
}
async function requestIOSNotificationPermission() {
// Implementation from Step 1 above
const authStatus = await messaging().requestPermission();
return authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
}
return (
// Your app components
null
);
}
import React, { useEffect } from 'react';
import { Singular } from 'singular-react-native';
import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';
export default function App() {
useEffect(() => {
if (Platform.OS === 'ios') {
initializeIOSUninstallTracking();
}
}, []);
async function initializeIOSUninstallTracking() {
try {
// Request notification authorization
const hasPermission = await requestIOSNotificationPermission();
if (!hasPermission) {
console.warn('Notification permission denied - uninstall tracking unavailable');
return;
}
// Register for remote notifications (required for APNS)
await messaging().registerDeviceForRemoteMessages();
// Get APNS token
const apnsToken = await messaging().getAPNSToken();
if (apnsToken) {
// Register token with Singular for uninstall tracking
Singular.setUninstallToken(apnsToken);
console.log('APNS token registered with Singular:', apnsToken);
} else {
console.warn('No APNS token available');
}
} catch (error) {
console.error('Error setting up iOS uninstall tracking:', error);
}
}
async function requestIOSNotificationPermission() {
// Implementation from Step 1 above
const authStatus = await messaging().requestPermission();
return authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
}
return (
// Your app components
);
}
Formato do token: O token APNS recuperado de getAPNSToken() já está formatado como uma cadeia hexadecimal, que é o formato correto para o Singular.
Etapa 3: lidar com a atualização do token (iOS)
Atualize o token APNS com o Singular se ele for alterado durante o ciclo de vida do aplicativo.
// TurboModule direct API (React Native 0.76+ New Architecture)
import React, { useEffect } from 'react';
import NativeSingular from 'singular-react-native/jsNativeSingular';
import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';
export default function App() {
useEffect(() => {
if (Platform.OS === 'ios') {
// Set up token refresh listener
const unsubscribe = messaging().onTokenRefresh((token) => {
console.log('APNS token refreshed:', token);
// Update Singular with new token
NativeSingular.setUninstallToken(token);
});
// Clean up listener on unmount
return () => unsubscribe();
}
}, []);
return (
// Your app components
null
);
}
import React, { useEffect } from 'react';
import { Singular } from 'singular-react-native';
import messaging from '@react-native-firebase/messaging';
import { Platform } from 'react-native';
export default function App() {
useEffect(() => {
if (Platform.OS === 'ios') {
// Set up token refresh listener
const unsubscribe = messaging().onTokenRefresh((token) => {
console.log('APNS token refreshed:', token);
// Update Singular with new token
Singular.setUninstallToken(token);
});
// Clean up listener on unmount
return () => unsubscribe();
}
}, []);
return (
// Your app components
);
}
Implementação completa entre plataformas
Configuração unificada do rastreamento de desinstalação
Implemente o rastreamento de desinstalação para as plataformas Android e iOS com tratamento adequado de erros e lógica de atualização de token.
// TurboModule direct API (React Native 0.76+ New Architecture)
import React, { useEffect } from 'react';
import NativeSingular from 'singular-react-native/jsNativeSingular';
import messaging from '@react-native-firebase/messaging';
import { Platform, PermissionsAndroid } from 'react-native';
export default function App() {
useEffect(() => {
initializeUninstallTracking();
const unsubscribe = setupTokenRefreshListener();
// Clean up listener on unmount
return () => {
if (typeof unsubscribe === 'function') unsubscribe();
};
}, []);
async function initializeUninstallTracking() {
try {
if (Platform.OS === 'android') {
await setupAndroidUninstallTracking();
} else if (Platform.OS === 'ios') {
await setupIOSUninstallTracking();
}
} catch (error) {
console.error('Error initializing uninstall tracking:', error);
}
}
async function setupAndroidUninstallTracking() {
// Request permission for Android 13+
if (Platform.Version >= 33) {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
);
if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
console.warn('Android notification permission denied');
return;
}
}
// Get and register FCM token
const token = await messaging().getToken();
if (token) {
NativeSingular.setUninstallToken(token);
console.log('Android FCM token registered:', token);
} else {
console.warn('Failed to retrieve Android FCM token');
}
}
async function setupIOSUninstallTracking() {
// Request iOS notification authorization
const authStatus = await messaging().requestPermission();
const authorized =
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
if (!authorized) {
console.warn('iOS notification permission denied');
return;
}
// Register for remote notifications
await messaging().registerDeviceForRemoteMessages();
// Get and register APNS token
const apnsToken = await messaging().getAPNSToken();
if (apnsToken) {
NativeSingular.setUninstallToken(apnsToken);
console.log('iOS APNS token registered:', apnsToken);
} else {
console.warn('Failed to retrieve iOS APNS token');
}
}
function setupTokenRefreshListener() {
// Listen for token refresh events
const unsubscribe = messaging().onTokenRefresh((token) => {
console.log(`${Platform.OS.toUpperCase()} token refreshed:`, token);
NativeSingular.setUninstallToken(token);
});
return unsubscribe;
}
return (
// Your app components
null
);
}
import React, { useEffect } from 'react';
import { Singular } from 'singular-react-native';
import messaging from '@react-native-firebase/messaging';
import { Platform, PermissionsAndroid } from 'react-native';
export default function App() {
useEffect(() => {
initializeUninstallTracking();
setupTokenRefreshListener();
}, []);
async function initializeUninstallTracking() {
try {
if (Platform.OS === 'android') {
await setupAndroidUninstallTracking();
} else if (Platform.OS === 'ios') {
await setupIOSUninstallTracking();
}
} catch (error) {
console.error('Error initializing uninstall tracking:', error);
}
}
async function setupAndroidUninstallTracking() {
// Request permission for Android 13+
if (Platform.Version >= 33) {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
);
if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
console.warn('Android notification permission denied');
return;
}
}
// Get and register FCM token
const token = await messaging().getToken();
if (token) {
Singular.setUninstallToken(token);
console.log('Android FCM token registered:', token);
} else {
console.warn('Failed to retrieve Android FCM token');
}
}
async function setupIOSUninstallTracking() {
// Request iOS notification authorization
const authStatus = await messaging().requestPermission();
const authorized =
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
if (!authorized) {
console.warn('iOS notification permission denied');
return;
}
// Register for remote notifications
await messaging().registerDeviceForRemoteMessages();
// Get and register APNS token
const apnsToken = await messaging().getAPNSToken();
if (apnsToken) {
Singular.setUninstallToken(apnsToken);
console.log('iOS APNS token registered:', apnsToken);
} else {
console.warn('Failed to retrieve iOS APNS token');
}
}
function setupTokenRefreshListener() {
// Listen for token refresh events
const unsubscribe = messaging().onTokenRefresh((token) => {
console.log(`${Platform.OS.toUpperCase()} token refreshed:`, token);
Singular.setUninstallToken(token);
});
return unsubscribe;
}
return (
// Your app components
);
}
Verificação e solução de problemas
Verificar a implementação
Confirme se o rastreamento de desinstalação está funcionando corretamente antes de implantar na produção.
- Verifique os logs: Verifique se o registro do token aparece nos logs do console com o formato correto
- Teste a geração de tokens: Certifique-se de que os tokens sejam gerados na primeira inicialização do aplicativo após a concessão de permissões
- Monitorar o painel: Verifique o painel do Singular para obter dados de rastreamento de desinstalação após 24-48 horas
- Testar atualização de token: Limpar os dados do aplicativo e verificar se o token é atualizado corretamente quando o aplicativo é reiniciado
Problemas comuns
- Token não gerado: Verifique se as dependências do Firebase estão instaladas corretamente e se o Firebase está configurado no seu projeto React Native
- Permissão negada: Verifique se os usuários concederam permissões de notificação (necessário para Android 13+ e todas as versões do iOS)
-
Token não está sendo atualizado: Certifique-se de que você se inscreveu no evento
onTokenRefreshpara ambas as plataformas - Dados ausentes: Confirme se os dispositivos cumprem os requisitos da plataforma (Android 4.1+ com Google Play Services, iOS com suporte para APNs)
- Erro de configuração: Verifique se o rastreamento de desinstalação está ativado nas configurações da plataforma Singular para seu aplicativo
-
Configuração do Firebase: Para Android, verifique se
google-services.jsonestá emandroid/app/. Para iOS, verifique seGoogleService-Info.plistfoi adicionado ao projeto Xcode
Recursos adicionais: Para obter uma solução de problemas detalhada, consulte o Guia de configuração do rastreamento de desinstalação do Android, o Guia de configuração do rastreamento de desinstalação do iOS e a Documentação de mensagens do React Native Firebase.