Seguimiento de desinstalaciones
Realiza un seguimiento de las desinstalaciones de apps para medir la retención de usuarios y optimizar las campañas de reenganche integrando servicios de notificaciones push con Singular SDK.
Importante: Google dejó obsoletas las API de GCM en abril de 2018. Utiliza Firebase Cloud Messaging (FCM) para todas las implementaciones de seguimiento de desinstalación de Android.
Seguimiento de desinstalación de Android
Requisitos previos
Antes de implementar el seguimiento de desinstalación en tu app React Native, configura tu app en la plataforma Singular siguiendo la guía Configuración del seguimiento de desinstalación de Android.
Requisitos del sistema
El seguimiento de desinstalación requiere Firebase Cloud Messaging y configuraciones de dispositivo específicas.
Requisitos de FCM(fuente):
- Versión de Android: Los dispositivos deben ejecutar Android 4.1 (API 16) o superior
- Servicios de Google Play: Los dispositivos deben tener instalada la aplicación Google Play Store
- Compatibilidad con emuladores: Se admiten emuladores de Android 4.1+ con API de Google
- Distribución: Las aplicaciones se pueden distribuir fuera de Google Play Store sin dejar de admitir el seguimiento de desinstalaciones.
Nota: no se realizará el seguimiento de las desinstalaciones de los usuarios que utilicen versiones de Android no compatibles o dispositivos sin Google Play Services.
Pasos de implementación
Paso 1: Instalar paquetes Firebase
Añade las dependencias de React Native Firebase para la funcionalidad principal y el soporte de mensajería.
npm install @react-native-firebase/app
npm install @react-native-firebase/messaging
Paso 2: Configurar Firebase
Añade los archivos de configuración de Firebase a tu proyecto React Native para Android.
- Registra tu app Android en tu proyecto Firebase Console
-
Descarga
google-services.jsony colócalo enandroid/app/ - Verifica que las dependencias de mensajería de Firebase están añadidas a tu proyecto
Para obtener instrucciones detalladas de configuración, consulta React Native Firebase Android Setup.
Paso 3: Solicitar permisos de notificación
Solicita permisos de notificación al usuario (necesario para Android 13+) antes de recuperar el 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;
}
Paso 4: Recuperar y registrar el token FCM
Obtenga el token del dispositivo FCM y regístrelo en Singular utilizando setUninstallToken() después de solicitar los permisos.
// 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 obtener la documentación completa del método, consulte la referencia setUninstallToken.
Paso 5: Gestionar la actualización del token
Actualice el token FCM con Singular cada vez que se actualice para mantener un seguimiento preciso de la desinstalación.
// 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
);
}
Práctica recomendada: Los tokens FCM pueden actualizarse en cualquier momento (actualizaciones de aplicaciones, restauración de dispositivos, etc.). Suscríbase siempre al evento onTokenRefresh para mantener Singular actualizado con el token más reciente.
Seguimiento de la desinstalación de iOS
Requisitos previos
Configure su aplicación iOS en la plataforma Singular siguiendo la guía Configuración del seguimiento de desinstalación de iOS.
El seguimiento de desinstalaciones en iOS se basa en la tecnología del servicio de notificaciones push de Apple (APNs). Si su aplicación no es compatible con las notificaciones push, consulte la guía de Apple para Registrar su aplicación con APNs.
Pasos de implementación
Paso 1: Solicitar autorización de notificaciones de iOS
Solicita permisos de notificación al usuario y recupera el 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;
}
}
Paso 2: Recuperar y registrar el token APNS
Obtenga el token de dispositivo APNS y regístrelo en Singular mediante setUninstallToken() una vez concedida la autorización.
// 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 del token: El token APNS recuperado de getAPNSToken() ya está formateado como cadena hexadecimal, que es el formato correcto para Singular.
Paso 3: Actualización del token (iOS)
Actualice el token APNS con Singular si cambia durante el ciclo de vida de la aplicación.
// 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
);
}
Implementación completa multiplataforma
Configuración unificada de seguimiento de desinstalación
Implemente el seguimiento de desinstalación para las plataformas Android e iOS con el manejo adecuado de errores y la lógica de actualización 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
);
}
Verificación y resolución de problemas
Verificación de la implementación
Confirme que el seguimiento de desinstalación funciona correctamente antes de implementarlo en producción.
- Compruebe los registros: Compruebe que el registro de tokens aparece en los registros de la consola con el formato correcto.
- Pruebe la generación de tokens: Asegúrese de que los tokens se generan en el primer lanzamiento de la aplicación después de conceder los permisos.
- Supervise el panel de control: Compruebe los datos de seguimiento de desinstalación del panel de Singular transcurridas 24-48 horas.
- Prueba de actualización de tokens: Borre los datos de la aplicación y compruebe que los tokens se actualizan correctamente al reiniciar la aplicación.
Problemas comunes
- Token no generado: Comprueba que las dependencias de Firebase están correctamente instaladas y que Firebase está configurado en tu proyecto React Native.
- Permiso denegado: Comprueba que los usuarios han concedido permisos de notificación (necesario tanto para Android 13+ como para todas las versiones de iOS)
-
Token no actualizado: Asegúrate de que te has suscrito al evento
onTokenRefreshpara ambas plataformas - Faltan datos: Confirme que los dispositivos cumplen los requisitos de la plataforma (Android 4.1+ con Google Play Services, iOS compatible con APNs)
- Error de configuración: Verifica que el seguimiento de desinstalación está habilitado en la configuración de la plataforma Singular para tu app
-
Configuración de Firebase: Para Android, asegúrese de que
google-services.jsonestá enandroid/app/. Para iOS, asegúrese de queGoogleService-Info.plistse ha añadido al proyecto Xcode.
Recursos adicionales: Para obtener información detallada sobre la solución de problemas, consulta la Guía de configuración del seguimiento de desinstalación de Android, la Guía de configuración del seguimiento de desinstalación de iOS y la Documentación de mensajería Firebase de React Native.