React Native SDK - 추적 제거

문서

앱 삭제 추적

앱 제거를 추적하여 사용자 리텐션을 측정하고 푸시 알림 서비스를 Singular SDK와 연동하여 리인게이지먼트 캠페인을 최적화하세요.

중요: 구글은 2018년 4월에 GCM API를 더 이상 사용하지 않습니다. 모든 안드로이드 앱 제거 추적 구현에는 Firebase 클라우드 메시징(FCM)을 사용하세요.

Android 제거 추적

전제 조건

리액트 네이티브 앱에서 앱 제거 추적을 구현하기 전에 안드로이드 앱 제거 추적 설정 가이드에 따라 Singular 플랫폼에서 앱을 구성하세요.


시스템 요구 사항

제거 추적을 사용하려면 Firebase 클라우드 메시징 및 특정 기기 구성이 필요합니다.

FCM 요구 사항(소스):

  • Android 버전: 기기는 Android 4.1(API 16) 이상을 실행해야 합니다.
  • Google Play 서비스: 기기에 Google Play 스토어 앱이 설치되어 있어야 합니다.
  • 에뮬레이터 지원: Google API가 포함된 Android 4.1 이상 에뮬레이터가 지원됩니다.
  • 배포: 앱 제거 추적을 지원하면서 Google Play 스토어 외부에 앱을 배포할 수 있습니다.

참고: 지원되지 않는 Android 버전 또는 Google Play 서비스가 없는 기기를 사용하는 사용자는 제거 추적이 되지 않습니다.


구현 단계

1단계: Firebase 패키지 설치

핵심 기능 및 메시징 지원을 위해 React Native Firebase 종속성을 추가합니다.

bash
npm install @react-native-firebase/app
npm install @react-native-firebase/messaging

2단계: Firebase 구성

Android용 React Native 프로젝트에 Firebase 구성 파일을 추가합니다.

  1. Firebase 콘솔 프로젝트에 안드로이드 앱을 등록하세요.
  2. google-services.json 을 다운로드하고 android/app/에 배치합니다.
  3. 프로젝트에 Firebase 메시징 종속성이 추가되었는지 확인합니다.

자세한 설정 지침은 React Native Firebase 안드로이드 설정을 참조하세요.


3단계: 알림 권한 요청

FCM 토큰을 검색하기 전에 사용자에게 알림 권한을 요청합니다(Android 13 이상에서 필요).

JavaScript
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;
}

4단계: FCM 토큰 검색 및 등록하기

권한을 요청한 후 setUninstallToken() 을 사용하여 FCM 디바이스 토큰을 가져와 Singular에 등록합니다.

New ArchitectureOld Achitecture
// 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
  );
}

전체 메서드 설명서는 setUninstallToken 참조를 참조하세요.


5단계: 토큰 새로 고침 처리

정확한 제거 추적을 유지하기 위해 새로 고침할 때마다 Singular로 FCM 토큰을 업데이트하세요.

New ArchitectureOld Achitecture
// 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
  );
}

모범 사례: FCM 토큰은 언제든지 새로 고칠 수 있습니다(앱 업데이트, 디바이스 복원 등). 항상 onTokenRefresh 이벤트를 구독하여 Singular를 최신 토큰으로 업데이트하세요.


iOS 앱 제거 추적

전제 조건

iOS제거 추적 설정 가이드에 따라 Singular 플랫폼에서 iOS 앱을 구성합니다.

iOS의 앱 제거 추적은 Apple 푸시 알림 서비스(APN) 기술을 기반으로 합니다. 앱이 푸시 알림을 지원하지 않는 경우 Apple의 APN에 앱 등록하기 가이드를 참조하세요.


구현 단계

1단계: iOS 알림 권한 요청

사용자에게 알림 권한을 요청하고 APNS 디바이스 토큰을 검색합니다.

JavaScript
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;
  }
}

2단계: APNS 토큰 검색 및 등록하기

권한이 부여된 후 APNS 디바이스 토큰을 가져와 setUninstallToken() 을 사용하여 Singular에 등록합니다.

New ArchitectureOld Achitecture
// 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
  );
}

토큰 형식: getAPNSToken() 에서 검색한 APNS 토큰은 이미 16진수 문자열로 형식이 지정되어 있으며, 이는 Singular에 적합한 형식입니다.


3단계: 토큰 새로 고침 처리하기(iOS)

앱 수명 주기 동안 변경되는 경우 APNS 토큰을 Singular로 업데이트합니다.

New ArchitectureOld Achitecture
// 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
  );
}

완벽한 크로스 플랫폼 구현

연동 제거 추적 설정

적절한 오류 처리 및 토큰 새로 고침 로직을 통해 Android 및 iOS 플랫폼 모두에 대한 제거 추적을 구현하세요.

New ArchitectureOld Achitecture
// 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
  );
}

검증 및 문제 해결

구현 확인

프로덕션에 배포하기 전에 제거 추적이 올바르게 작동하는지 확인하세요.

  1. 로그를 확인합니다: 콘솔 로그에 토큰 등록이 올바른 형식으로 표시되는지 확인합니다.
  2. 토큰 생성 테스트: 권한 부여 후 앱을 처음 실행할 때 토큰이 생성되는지 확인합니다.
  3. 대시보드 모니터링: 대시보드 모니터링: 24-48시간 후 Singular 대시보드에서 제거 추적 데이터를 확인합니다.
  4. 토큰 새로 고침 테스트: 앱 재실행 시 앱 데이터를 지우고 토큰 업데이트가 올바르게 수행되는지 확인합니다.

일반적인 문제

  • 토큰이 생성되지 않음: Firebase 종속성이 올바르게 설치되어 있고 React Native 프로젝트에 Firebase가 구성되어 있는지 확인합니다.
  • 권한이 거부되었습니다: 사용자가 알림 권한을 부여했는지 확인합니다(Android 13 이상 및 모든 iOS 버전에 필요).
  • 토큰이 업데이트되지 않음: 두 플랫폼 모두에 대해 onTokenRefresh 이벤트를 구독했는지 확인하세요.
  • 데이터 누락: 디바이스가 플랫폼 요구 사항을 충족하는지 확인합니다(Android 4.1+는 Google Play 서비스, iOS는 APN 지원).
  • 구성 오류: 앱의 Singular 플랫폼 설정에서 앱 제거 추적이 활성화되어 있는지 확인합니다.
  • 파이어베이스 설정: Android의 경우 google-services.jsonandroid/app/ 에 있는지 확인합니다. iOS의 경우 GoogleService-Info.plist 이 Xcode 프로젝트에 추가되었는지 확인합니다.

추가 리소스: 자세한 문제 해결 방법은 Android 제거 추적 설정 가이드, iOS 제거 추적 설정 가이드React Native Firebase 메시징 설명서를 참조하세요.