DateP

구독 갱신 로직 완성

Solo.dev 2025. 4. 27. 16:54
2025-04-27 에러 해결 및 추가 문제 정리

2025-04-27 에러 해결 및 추가 문제 정리

문제 1: handleStartPurchase에서 Firebase update 에러

  • 에러: ❌ handleStartPurchase error: Error: update failed: values argument contains undefined in property 'subscriptions..transactionId'
  • 원인:
    • subscriptionDatatransactionId 또는 purchaseTokenundefined로 포함.
    • 조건부 추가 로직에서 값 누락.
  • 해결: handleStartPurchase 수정: subscriptionDataany 타입으로 선언, undefined 값 제거.

const subscriptionData: any = {
    plan,
    remainingUses: result.data.remainingUses,
    limit: usageLimits[plan],
    purchaseDate: result.data.purchaseDate || new Date().toISOString(),
};
if (Platform.OS === 'ios' && result.data.transactionId) {
    subscriptionData.transactionId = result.data.transactionId;
}
if (Platform.OS === 'android' && result.data.purchaseToken) {
    subscriptionData.purchaseToken = result.data.purchaseToken;
}
await update(subscriptionRef, subscriptionData);
        
  • 결과: Firebase update 에러 해결.

문제 2: 동일한 Firebase update 에러 (다른 위치)

  • 에러: values argument contains undefined in property 'subscriptions..transactionId' (로그 없이 발생).
  • 원인:
    • checkSubscriptionStatus 또는 useFeature에서 transactionId/purchaseTokenundefined로 전달.
  • 해결: startPurchase.ts, SubscriptionProvider.tsx에서 subscriptionData 조건부 처리 강화, Partial 사용.
  • 결과: 다른 위치 에러 해결.

문제 3: API 요청 실패 (basic, premium)

  • 에러: ❌ API 요청 실패: Failed to parse error response.
  • 원인:
    • 서버 리소스 부족 (256MiB).
    • 잘못된 JSON 응답으로 파싱 실패.
  • 해결: Google Cloud Run 메모리 256MiB → 512MiB로 증설, API 재배포.
  • 결과: API 요청 정상화.

문제 4: Android에서 Firebase 데이터 삭제 후 잘못된 플랜 복구

  • 에러: Firebase 데이터 삭제 후 Android에서 premium 대신 basic 플랜으로 복구.
  • 원인:
    • checkSubscriptionStatus가 캐시된 구매 데이터를 잘못 처리.
    • purchaseToken 기반 플랜 검증 미흡.
  • 해결 방안:
    • checkSubscriptionStatus 수정: productId로 플랜 동적 확인.
    • 캐시 초기화: AsyncStorage에서 selectedPlan, purchaseToken 제거.
    • 서버 검증: Google Play API로 purchaseToken 확인.

for (const purchase of purchases) {
    let plan: 'basic' | 'premium' = 'basic';
    if (purchase.productId.includes('premium')) {
        plan = 'premium';
    } else if (purchase.productId.includes('basic')) {
        plan = 'basic';
    }
    const subscriptionData = {
        plan,
        remainingUses: snapshot.exists() ? snapshot.val().remainingUses : usageLimits[plan],
        limit: usageLimits[plan],
        purchaseDate: purchase.transactionDate
            ? new Date(purchase.transactionDate).toISOString()
            : new Date().toISOString(),
        purchaseToken: purchaseToken,
    };
    if (!snapshot.exists()) {
        await set(subscriptionRef, subscriptionData);
    }
}
        
  • 결과: 갱신 로직 완료. 실제 갱신 여부 테스트 필요.

문제 4 관련 추가 테스트

  • 테스트 1: Android 앱에서 프리미엄 구독 구매 후 Firebase 데이터 삭제.
  • 테스트 2: 앱 재실행 후 구독 상태 확인. 예상 결과: 프리미엄 플랜으로 복구되어야 함.
  • 테스트 3: 베이직 구독 구매 후 동일한 Firebase 데이터 삭제 및 앱 재실행. 예상 결과: 베이직 플랜으로 복구되어야 함.
  • 테스트 4: purchaseToken 기반 서버 검증 로직이 추가된 경우, 데이터 삭제 후에도 서버를 통해 정확한 플랜으로 복구되는지 확인.

최종 상태

  • 문제 1~3: 해결 완료.
  • 문제 4: 갱신 로직 완료, 실제 갱신 및 복구 로직 테스트 필요.

추가 제안

  • 로그 강화: fetchPlaces, checkSubscriptionStatus에 상태 코드, purchaseToken 로깅.
  • 모니터링: Google Cloud Run 메트릭 설정.
  • 테스트: Android/iOS 구매, 복원, API 호출 테스트.
  • 에러 핸들링: fetch 타임아웃(10초),