SETUP GUIDE · v4.0

선주 모바일 GA4 측정 설계서

선주앱(RN 셸 + 풀웹뷰) GA4 신규 세팅 절차서입니다.
웹 스트림 · gtag.js 기준이며, 네이티브 SDK는 붙이지 않습니다.
STEP 1 → 10 순서대로 진행하며, 각 단계에 완료 확인 기준이 있습니다.

웹 스트림STEP 10단계이벤트 10개탐색 리포트 5개커스텀 정의 10개앱 빌드 불필요

선주 모바일 GA4 세팅 가이드


0. 사전 정보 — 용어와 동작 방식

GA4는 앱에서 발생한 행동을 이벤트 단위로 수집해 리포트로 조회하는 도구입니다. 이 문서에서 쓰는 용어는 아래 6개입니다.

용어

용어의미선주앱 적용
속성(Property)데이터가 쌓이는 큰 통aboutfishing-product (ID 295704822) — 이미 있음, 새로 만들지 마세요
데이터 스트림(Stream)통에 데이터를 붓는 파이프. 앱·웹마다 하나씩선주앱용 웹 스트림을 새로 만듭니다
이벤트(Event)"무슨 일이 일어났다" 한 줄 기록owner_confirm = 선주가 예약을 확정했다
파라미터(Parameter)그 일에 딸린 상세 정보count: 3 = 3건을 확정했다
커스텀 정의파라미터를 GA 화면에서 볼 수 있게 등록하는 절차등록 안 하면 보내도 안 보입니다 ⚠️
DebugView내가 보낸 이벤트가 실시간으로 들어오는지 보는 화면개발 중엔 여기만 봅니다

미리 알아둘 GA4 동작 3가지

  1. 파라미터는 커스텀 정의에 등록해야 리포트에 노출됩니다. 전송만으로는 조회되지 않습니다. (STEP 6)
  2. GA4 리포트는 24~48시간 지연됩니다. 개발 중 검증은 DebugView(실시간)로 합니다. (STEP 8)
  3. 이벤트 이름은 한 번 수집되면 삭제할 수 없습니다. 명명 규칙을 먼저 확정하는 이유입니다.

1. 준비물 체크리스트

아래 5개가 선행돼야 합니다.

Firebase 콘솔·google-services.json·네이티브 SDK는 이번 범위에 없습니다. 선주앱은 RN 셸로 감싼 풀웹뷰라, 측정 코드는 웹 번들에만 들어갑니다.

2. 전체 구조

[RN 셸]  ── 웹뷰 하나만 띄움. 측정 코드 없음
   │
   └─ [웹 번들]  gtag.js  ──────────▶  [GA4 속성: aboutfishing-product]
                 track('owner_confirm', {...})      선주앱 웹 스트림 (새로 만듦)

핵심 규칙: 측정 코드는 웹 번들 한 곳에만 둡니다. RN 셸에는 아무것도 붙이지 않습니다.

선주앱은 RN으로 패킹만 한 풀웹뷰라 네이티브 화면이 없습니다. 셸에 SDK를 붙여도 잡을 게 없고, 웹과 양쪽에서 보내면 동일 행동이 이중 집계됩니다. 사후 보정이 불가능해 데이터를 폐기해야 하므로 경로를 하나로 고정합니다.

이 구조에서 포기하는 것 — 필요해지면 그때 SDK를 추가합니다.

못 보는 것대안
푸시 발송 대비 오픈률딥링크 URL에 UTM을 달면 유입까지는 집계됩니다
앱 설치·삭제·앱 버전별 지표웹 번들 버전(app_version)으로 배포 전후를 비교합니다
스토어 획득·설치 어트리뷰션이번 범위 밖

STEP 1. 선주앱 웹 스트림 생성 (15분)

선주앱 데이터가 유입될 웹 스트림을 생성하고 측정 ID를 받아옵니다.

  1. 브라우저에서 analytics.google.com/?authuser=1 접속 (반드시 ?authuser=1)
  2. 좌하단 관리(톱니바퀴) 클릭
  3. 속성 열에서 aboutfishing-product 선택돼 있는지 확인
  4. 데이터 수집 및 수정 → 데이터 스트림 클릭
  5. 우상단 스트림 추가 → 웹
  6. 웹사이트 URL에 선주앱 도메인(예: owner.aboutfishing.kr), 스트림 이름에 선주앱 입력
  7. 향상된 측정 토글을 끈 상태로 만듭니다 (기본값은 켜짐 — 이유는 STEP 2)
  8. 스트림 만들기 → 화면에 뜨는 측정 ID G-XXXXXXXXXX 를 복사해 둡니다. STEP 3에서 씁니다
⚠️ 손님앱 웹 스트림에 추가하지 않습니다. 반드시 신규 스트림으로 만듭니다. 한 스트림에 섞이면 이후 분리가 불가능합니다.

완료 기준: 데이터 스트림 목록에 선주앱 웹 스트림이 있고, 측정 ID를 확보했습니다.


STEP 2. 기본 설정 변경 (5분)

기본값 3개를 변경합니다. 특히 데이터 보관은 나중에 바꿔도 소급 적용되지 않습니다.

설정 위치바꿀 값
관리 → 데이터 보관2개월 → 14개월기본값 2개월. 3개월 전 데이터 조회가 불가능해집니다
관리 → 데이터 수집 → Google 신호 데이터사용 안 함선주는 사업자 계정이라 광고 타겟팅용 수집이 불필요합니다
스트림 상세 → 향상된 측정전부 끄기아래 설명

향상된 측정을 끄는 이유

향상된 측정은 페이지 조회·스크롤·이탈 클릭·파일 다운로드를 GA가 알아서 수집하는 기능입니다. 일반 웹사이트에는 편리하지만 선주앱에는 맞지 않습니다.

화면 조회를 포함해 전부 코드에서 직접 보냅니다. 경로가 하나여야 숫자를 신뢰할 수 있습니다.

완료 기준: 데이터 보관이 14개월이고, 스트림 상세의 향상된 측정 항목이 전부 꺼져 있습니다.


STEP 3. gtag 연결 + 웹뷰 설정 확인 (20분)

3-1. 웹 번들에 gtag 삽입

index.html<head> 최상단에 넣습니다. STEP 1에서 받은 측정 ID로 G-XXXXXXXXXX 를 교체합니다.

<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){ dataLayer.push(arguments); }
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXXXXX', {
    send_page_view: false   // 화면 조회는 STEP 5에서 직접 보냅니다
  });
</script>
send_page_view: false 가 핵심입니다. 빼면 앱 진입 시 page_view 가 자동으로 한 번 찍히고, STEP 5의 수동 전송과 겹쳐 첫 화면만 두 배로 집계됩니다.

3-2. RN WebView 설정 4개 — 이걸 놓치면 사용자 수가 부풀려집니다

gtag는 방문자 식별자(_ga)를 쿠키와 localStorage에 저장합니다. 웹뷰가 이걸 유지하지 못하면 앱을 켤 때마다 새 사용자로 잡혀서, 실제 선주 200명이 월 사용자 3,000명으로 나옵니다.

react-native-webview 에서 아래 4개를 확인합니다.

<WebView
  source={{ uri: 'https://owner.aboutfishing.kr' }}
  sharedCookiesEnabled={true}      // iOS — 쿠키를 앱 재시작 후에도 유지
  thirdPartyCookiesEnabled={true}  // Android — 쿠키 저장 허용
  domStorageEnabled={true}         // Android — localStorage 활성화
  incognito={false}                // ⚠️ true 면 종료 시 전부 삭제됩니다
  javaScriptEnabled={true}
/>
옵션없으면 생기는 일
sharedCookiesEnabled (iOS)앱 재시작마다 새 사용자. iOS 지표만 부풀려집니다
thirdPartyCookiesEnabled (Android)안드로이드에서 식별자 저장 실패
domStorageEnabled (Android)localStorage 폴백까지 막혀 세션이 매번 끊깁니다
incognito={false}앱 종료 시 전부 삭제. 재방문 사용자가 0이 됩니다
이 4개는 RN 셸 코드를 한 번 수정해야 하므로, 이 단계에서만 앱 빌드가 필요할 수 있습니다. 이미 켜져 있으면 빌드 없이 끝납니다. 이후 이벤트 추가·수정은 전부 웹 배포만으로 반영됩니다.

완료 기준: STEP 8의 DebugView에서 session_start·first_visit 가 확인되고, 앱을 완전히 종료했다 다시 켰을 때 first_visit 가 다시 찍히지 않습니다. (다시 찍히면 3-2 설정 누락)


STEP 4. 이벤트 이름 상수화 (10분)

이벤트명 오타는 GA에서 경고 없이 별도 이벤트로 집계됩니다. owner_confirmowner_comfirm 은 서로 다른 이벤트로 쌓입니다.

// analytics/events.ts  — 문자열을 코드에 직접 쓰지 말 것
export const EV = {
  CONFIRM          : 'owner_confirm',
  CANCEL           : 'owner_cancel',
  PRODUCT_CREATE   : 'owner_product_create',
  CLOSE_NOW        : 'owner_close_now',
  SEAT_ADJUST      : 'owner_seat_adjust',
  BULK_EDIT        : 'owner_bulk_edit',
  MANUAL_ADD       : 'owner_manual_add',
  CALL_TAP         : 'owner_call_tap',
  SETTLEMENT_EXCEL : 'owner_settlement_excel',
  FRICTION         : 'owner_friction',
} as const;

export const SCREEN = {
  HOME        : 'OWN_HOME',
  PROD_DAILY  : 'OWN_PROD_DAILY',
  PROD_MASTER : 'OWN_PROD_MASTER',
  PROD_CREATE : 'OWN_PROD_CREATE',
  RSV_LIST    : 'OWN_RSV_LIST',
  SETTLE      : 'OWN_SETTLE',
  FISH        : 'OWN_FISH',
} as const;

export const CANCEL_REASON = {
  OVERBOOKING : 'overbooking',      // 오버부킹
  POOR_CATCH  : 'poor_catch',       // 물때·조황부진
  MIN_PAX     : 'min_pax_unmet',    // 최소인원 미달
  BAD_WEATHER : 'bad_weather',      // 기상 악화
  MAINTENANCE : 'maintenance',      // 정비일
  HOLIDAY     : 'holiday',          // 휴무일
} as const;
값에는 한글을 쓰지 않습니다. GA 검색·필터·BigQuery에서 인코딩이 깨집니다. 화면 표기는 한글, 전송값은 영문 슬러그입니다.

STEP 5. 전송 코드 구현 (1~2일)

5-1. 전송 래퍼 (선행 작업)

파일 하나를 만들고, 앱 전체에서 이것만 호출합니다. gtag() 를 코드 곳곳에서 직접 부르지 않습니다.

// analytics/track.ts
type Params = Record<string, string | number>;

declare global { interface Window { gtag?: (...a: any[]) => void } }

// 모든 이벤트에 자동으로 붙는 값
let common: Params = {
  app_version: __BUNDLE_VERSION__,   // 웹 번들 배포 버전
  entry_from : 'tab',
};

export function setEntryFrom(v: string) { common.entry_from = v; }

export function track(name: string, params: Params = {}) {
  try {
    window.gtag?.('event', name, { ...common, ...params });
  } catch (_) {
    // 측정이 실패해도 화면은 절대 멈추면 안 됩니다
  }
}

export function screen(screenId: string, params: Params = {}) {
  track('page_view', { screen_id: screenId, page_title: screenId, ...params });
}
웹 스트림의 화면 조회 표준 이벤트는 screen_view 가 아니라 page_view 입니다. 화면 식별은 URL 대신 screen_id 파라미터로 합니다. 선주앱은 URL이 화면을 정확히 반영하지 않기 때문입니다.

5-2. 공통 파라미터 3개 — 모든 이벤트에 자동으로

개별 이벤트마다 넣지 않고 위 래퍼 한 곳에서 주입합니다.

파라미터값 예시용도
screen_idOWN_HOME발생 화면 식별
entry_fromtab / push / deeplink유입 경로 분석
app_version2.14.0배포 전후 비교 (웹 번들 버전)
이전 설계의 view_layer(네이티브/웹뷰)는 뺐습니다. 전 화면이 웹뷰라 값이 하나뿐이어서 분석에 쓸 수 없습니다.

5-3. user_id + user_property 3개 — 로그인 직후 한 번만

user_id 설정이 이 구조에서 가장 중요합니다. 쿠키가 초기화돼도 같은 사람으로 이어 붙일 수 있는 유일한 수단입니다.

window.gtag?.('config', 'G-XXXXXXXXXX', {
  user_id: hashedMemberId,        // ⚠️ 전화번호·이메일 절대 금지, 해시만
  send_page_view: false,
});

window.gtag?.('set', 'user_properties', {
  af_app_role           : 'owner',
  owner_ship_count_band : '2_3',   // 1 / 2_3 / 4_9 / 10p
  owner_tenure_band     : 'd8_30', // d0_7 / d8_30 / d31_90 / d90p
});
선박 수를 원시값으로 보내면 값 종류가 많아져 GA가 (other) 로 묶습니다. 구간(밴드)으로 전송합니다.

5-4. 화면 조회 — page_view 하나로

화면별 이벤트를 만들지 않습니다. 이벤트는 page_view 하나이고 screen_id 값만 바꿉니다.

screen(SCREEN.HOME);           // 홈 진입
screen(SCREEN.PROD_DAILY);     // 상품관리 진입

보내는 곳: 라우트가 바뀌는 화면 진입, 전체화면 모달 안 보내는 곳: 바텀시트·토스트·탭 전환 (단 예약자 명단 시트만 예외 — 체류가 길어 화면으로 취급)

5-5. 이벤트 10개 구현

#이벤트전송 시점파라미터
1owner_confirm예약 확정 완료 토스트가 뜰 때count(건수) · pax(인원) · hours_since_payment(결제 후 경과 시간)
2owner_cancel취소 처리 완료 후cancel_reason · count · refund_amount · days_to_departure
3owner_product_create상품 등록 저장 성공create_type(daily/master) · is_first_product(1/0)
4owner_close_now즉시마감 실행fill_rate(0.64 = 64% 찼을 때 마감)
5owner_seat_adjust남은좌석 저장before_seat · after_seat
6owner_bulk_edit일괄수정 저장date_count · changed_fields(seat,close)
7owner_manual_add예약자 직접 추가 완료pax
8owner_call_tap예약자 번호 탭number_type(safe/direct) · is_expired(1/0)
9owner_settlement_excel정산 엑셀 다운로드 클릭month(2026-08)
10owner_friction비활성 버튼 클릭·유효성 오류·권한 차단·API 오류friction_type · element · error_code(선택)

코드 예시

// 1) 확정 완료
track(EV.CONFIRM, {
  screen_id: SCREEN.HOME,
  count: 3,
  pax: 8,
  hours_since_payment: 18.5,
});

// 2) 취소 완료
track(EV.CANCEL, {
  screen_id: SCREEN.HOME,
  cancel_reason: CANCEL_REASON.BAD_WEATHER,
  count: 3,
  refund_amount: 396000,
  days_to_departure: 2,
});

// 10) 마찰 — 사유 미선택 상태로 [확인]을 눌렀을 때
track(EV.FRICTION, {
  screen_id: SCREEN.HOME,
  friction_type: 'disabled_click',
  element: 'btn_cancel_confirm',
});
owner_friction 을 단일 이벤트로 두는 이유: 버튼별 이벤트를 만들면 GA 고유 이벤트 한도(500개)를 빠르게 소진합니다. 하나로 수집하고 element 파라미터로 구분해도 분석 결과는 동일합니다.

5-6. 금지 사항 4가지

금지결과
이름·전화번호·안심번호·이메일·사업자번호를 파라미터에 넣기GA 정책 위반으로 데이터 삭제 대상. user_id 에 전화번호 사용도 금지
선주앱에서 purchase / booking_purchase 보내기손님앱 매출과 이중 집계돼 전사 GMV가 오염됩니다
RN 셸에 Firebase SDK를 추가로 붙이기동일 행동이 웹·앱 양쪽에서 잡혀 전환수가 2배가 됩니다
예약번호·타임스탬프·금액 원단위를 파라미터로 보내기값 종류가 폭발해 리포트가 (other) 로 뭉개집니다

STEP 6. 커스텀 정의 등록 (10분)

파라미터는 여기에 등록해야 GA 리포트에서 조회됩니다. 전송이 정상이어도 등록이 없으면 값이 보이지 않으므로 누락되기 쉬운 단계입니다.

관리 → 맞춤 정의맞춤 측정기준 만들기 에서 아래 8개를 등록합니다.

표시 이름범위이벤트 매개변수 (철자 일치 필수)
선주_화면ID이벤트screen_id
선주_진입경로이벤트entry_from
선주_앱버전이벤트app_version
선주_취소사유이벤트cancel_reason
선주_마찰유형이벤트friction_type
선주_역할사용자af_app_role
선주_선박수사용자owner_ship_count_band
선주_가입경과사용자owner_tenure_band

이어서 맞춤 측정항목(숫자용) 2개도 추가합니다.

표시 이름매개변수측정 단위
선주_환불액refund_amount통화(KRW)
선주_확정소요시간hours_since_payment표준
⚠️ 범위(Scope)를 정확히 선택합니다. 이벤트에 딸린 값은 "이벤트", 사용자에 딸린 값(역할·선박수)은 "사용자"입니다. 잘못 지정하면 값이 매칭되지 않습니다.

완료 기준: 맞춤 정의 목록에 10개 항목(측정기준 8 + 측정항목 2)이 등록돼 있습니다. 데이터는 등록 후 24시간부터 채워집니다.


STEP 7. 주요 이벤트(전환) 표시하기 (2분)

관리 → 이벤트 목록에서 아래 2개의 주요 이벤트로 표시 토글을 켭니다.

이벤트 목록에 해당 이름이 없으면 아직 수집 이력이 없는 것입니다. 앱에서 1회 발생시킨 뒤 하루 후 다시 확인합니다.

STEP 8. DebugView 검증 (반나절)

디버그 모드 활성화

웹 스트림은 adb 명령이 필요 없습니다. 개발 빌드에서 debug_mode 를 켜기만 하면 됩니다.

gtag('config', 'G-XXXXXXXXXX', {
  send_page_view: false,
  debug_mode: !IS_PRODUCTION,   // ⚠️ 운영 빌드에서는 반드시 false
});
운영 빌드에 debug_mode: true 가 남으면 실사용 데이터가 전부 DebugView로 흘러 리포트가 왜곡됩니다. 배포 전 STEP 14에서 다시 확인합니다.

브라우저에서 웹 번들을 직접 열어 검증해도 됩니다. 다만 웹뷰 설정(3-2) 검증만큼은 실제 앱에서 해야 합니다.

확인 위치

GA4 → 좌측 관리 → DebugView (또는 왼쪽 메뉴 하단 DebugView)

체크리스트 7개 — 전부 통과 후 배포


STEP 9. 배포 후 확인 (D+2)

  1. 실시간 리포트: 보고서 → 실시간 → 이벤트 이름에 owner_ 들이 보이는가
  2. 탐색 분석: 탐색 → 빈 탐색 → 측정기준에 선주_화면ID 추가 → 값이 채워지는가 ((not set) 이면 STEP 6 등록 누락)
  3. (other) 행이 생겼는가 — 생겼다면 값 종류가 너무 많은 파라미터가 있다는 뜻. 그 값을 구간으로 바꿔야 합니다
  4. 사용자 수가 실제 선주 수와 자릿수가 맞는가 — 실제의 5배 이상이면 STEP 3-2 웹뷰 쿠키 설정을 다시 확인합니다

STEP 10. 탐색 리포트 생성 (30분)

GA4 기본 보고서는 마케팅 지표 중심이라 선주앱에는 맞지 않습니다. 탐색(Exploration) 에서 아래 5개를 생성해 재사용합니다.

만드는 곳: 좌측 메뉴 탐색빈 탐색 만들기. 왼쪽에 세그먼트 / 측정기준 / 측정항목 을 추가한 뒤, 가운데 탭 설정으로 끌어다 놓는 구조입니다.

리포트 ① 확정 리드타임 — "선주가 얼마나 빨리 확정하는가"

리포트 ② 취소 손실 — "어떤 이유로 돈이 새는가"

리포트 ③ 온보딩 퍼널 — "신규 선주가 첫 매출까지 오는가"

리포트 ④ 마찰 히트맵 — "어디서 막히는가"

리포트 ⑤ 배포 전후 비교 — "이번 배포가 좋아진 건가"

생성한 탐색은 우상단에서 공유합니다. 각자 만들면 지표 정의가 달라져 회의에서 수치가 어긋납니다.

11. 무엇을 보고 무엇을 고치는가

지표와 개선 액션을 연결한 표입니다. 수치 이상 시 의심 항목과 개선 후보를 사전에 정의해 둡니다.

볼 숫자어디서나쁘다는 신호의심할 것개선 후보
확정 리드타임리포트 ①24시간 초과 비중이 큼선주가 알림을 못 보거나, 확정을 미룸푸시 재알림, 홈 상단 강조, 결제일시 표기(이번 8/18 반영분)로 방치 인지
확정 건수 대비 마찰①+④OWN_HOMEdisabled_click 급증확정 버튼 활성 조건이 헷갈림버튼 상태·안내 문구 재설계
취소 손실액리포트 ②특정 사유가 금액 과반사유별로 원인이 다름overbooking 이면 좌석 동기화 버그, min_pax_unmet 이면 최소인원 정책·모객 지원, poor_catch 면 상품 편성
취소 리드타임②의 days_to_departure0~1일에 몰림임박 취소 = 손님 피해 큼조기 취소 유도(사전 인원 체크 알림)
온보딩 통과율리포트 ③1→2 단계에서 50% 이상 이탈상품 등록이 어렵다등록 폼 단순화, 첫 상품 온보딩 코치마크
소진율owner_close_nowfill_rate0.5 미만에서 마감이 잦음빈 배로 출항 중잔여석 프로모션, 마감 전 알림
기능 채택owner_bulk_edit·owner_seat_adjust 사용 선주 비율10% 미만기능을 모르거나 어렵다사용법 영상 진입 개선, 진입 동선 노출
전화 연결owner_call_tapis_expired=1 비율만료 비중이 큼안심번호 만료 기준이 짧다만료 기간 재검토(현재 [미확인]), 만료 표기 개선
정산 이탈owner_settlement_excel 빈도조회 대비 다운로드가 매우 높음앱 안에서 정산을 못 끝냄정산 화면에 필요한 항목 보강
배포 후 악화리포트 ⑤신버전의 사용자당 마찰이 구버전보다 큼이번 배포가 원인웹 번들 롤백 후 해당 화면 재검토

개선건 도출 절차

  1. 월 1회, 리포트 ④ 마찰 히트맵에서 상위 5칸을 뽑는다
  2. 각 칸을 "화면 + 마찰 유형 + 건수" 로 티켓 제목을 만든다 — 예: [OWN_HOME] 비활성 클릭 320건 — 확정 버튼 조건 불명확
  3. 리포트 ①②③ 중 돈에 직결된 지표 1개와 묶어 우선순위를 매긴다. 마찰 건수만으로 정하면 사소한 것부터 고치게 됩니다

12. 운영 루틴

주기시간보는 것산출물
주 1회15분확정 리드타임(①) · 취소 손실 상위 사유(②) · 마찰 상위 3칸(④)이상치가 있으면 슬랙 공유
월 1회1시간리포트 ①~⑤ 전부 + 전월 대비개선 티켓 3~5건 발행
배포 직후 D+220분새 이벤트가 들어오는지 · (other) 발생 여부 · 리포트 ⑤ 버전 비교태깅 이상 시 즉시 수정
분기 1회30분12장 "지금은 안 하는 것" 목록 재검토필요한 이벤트만 추가(분기 10개 이내)
첫 4주는 기준선 수집 기간으로 둡니다. 비교 대상이 없으면 지표의 좋고 나쁨을 판단할 수 없으므로, 4주치가 쌓인 뒤 개선 티켓을 발행합니다.

13. 트러블슈팅

증상원인조치
DebugView에 아무것도 안 뜬다debug_mode 미적용 / 측정 ID 오타gtag('config') 의 측정 ID와 debug_mode: true 확인
이벤트는 보이는데 파라미터가 안 보인다커스텀 정의 미등록STEP 6. 등록 후 24시간 필요
리포트가 텅 비어 있다GA4 리포트는 24~48시간 지연개발 중엔 DebugView로만 확인
값이 (not set) 으로 나온다파라미터 철자 불일치코드의 철자와 커스텀 정의의 철자를 글자 단위로 대조
화면 조회가 두 배다send_page_view 미설정gtag('config')send_page_view: false 추가, 향상된 측정 OFF 확인
사용자 수가 실제의 몇 배다웹뷰가 쿠키·스토리지를 못 지킴STEP 3-2의 RN WebView 옵션 4개 확인. incognito={true} 가 가장 흔한 원인
재방문 사용자가 0에 가깝다위와 동일앱 재실행 시 first_visit 가 다시 찍히는지 DebugView에서 확인
로그인해도 사용자가 안 이어진다user_id 미설정STEP 5-3. 로그인 성공 직후 config 재호출
(other) 행이 생겼다파라미터 값 종류 과다원시 ID·금액·타임스탬프를 파라미터에서 빼고 구간으로
손님앱 매출이 갑자기 늘었다선주앱이 purchase 를 보냄즉시 제거. 이미 들어간 데이터는 되돌릴 수 없음

14. 배포 전 최종 체크리스트


15. 이번 범위에서 제외한 항목

아래는 이번 범위에서 의도적으로 제외했습니다.

뺀 것다시 넣을 조건
확정/취소 시작·중단 이벤트확정 전환율이 낮게 나와 원인을 파야 할 때
조황·공지 관련 이벤트page_view 만으로 판단이 안 될 때
선박ID·업체ID·권한·요금제다척 선주 전용 기능을 만들 때
화면 폭(320/344/360) 세그먼트폭 관련 이탈이 의심될 때
첫 예약 수신선주앱 액션이 아니라 클라이언트에서 측정 불가 → 서버에서 Measurement Protocol 로 보내야 함 (백엔드 협의 필요)
푸시 발송·오픈 성과푸시 성과를 GA에서 봐야 할 때. RN 셸에 Firebase SDK 추가 + 앱 스토어 배포가 필요합니다. 그전까지는 딥링크 UTM으로 유입만 봅니다
앱 설치·삭제·스토어 획득위와 동일 (SDK 필요)

부록. 용어 정리

관련 문서