본문 바로가기

Capacitor에서 Google Fit을 Health Connect로 마이그레이션하기

2026년 Google Fit API 종료 전에 Capacitor 앱을 Google Fit에서 Health Connect로 마이그레이션하세요: 데이터 타입 매핑, 권한, 쿼리, Play 스토어 심사.

Capacitor 피트니스 앱을 Google Fit에서 Health Connect로 마이그레이션하기

Google Fit에서 Health Connect로 마이그레이션한다는 것은 Capacitor 앱 내의 모든 Fit API 호출을 Android에서는 Health Connect로, iOS까지 지원한다면 iOS에서는 HealthKit으로 교체해야 함을 의미합니다. Google은 2024년 5월 1일부터 새로운 Fit 가입을 중단했으며, Fit API 지원은 2026년 말까지만 유지됩니다. 이 가이드에서는 Fit 데이터 타입과 호출 방식을 Health Connect에 매핑하고, code를 통한 교체 방법을 안내하며, @capgo/capacitor-health건강 관련 권한 요청 시 필요한 Play Console 심사 과정까지 다룹니다.

Google Fit 지원 종료 일정

날짜 무슨 일이 있었나
2024년 5월 1일 Google Fit API 신규 개발자 가입 불가
2024년 ~ 2026년 기존 Fit 연동은 유지되나, Google은 개발자에게 Health Connect 사용을 권장함
2026 REST API를 포함한 Fit API 지원 종료 예정
2026년 말 지원 종료. Google은 정확한 종료일을 발표하지 않았습니다.

Google의 마이그레이션 FAQ에 따르면, 기존 Fit REST API와 동일한 구조의 대안은 없습니다. 온디바이스 앱은 Health Connect로, 클라우드 통합은 계정 기반의 Google Health API로 이동합니다. 만약 어디선가 정확한 종료일을 보셨다면, 계획을 세우기 전에 반드시 Google 공식 FAQ를 통해 다시 확인하세요.

Health Connect로 전환 시 변경 사항

Google Fit Health Connect
데이터 저장 위치 Google 계정 (클라우드) 디바이스 내부
인증 fitness 스코프를 포함한 OAuth 2.0, Google Sign-In 데이터 유형별 Android 런타임 권한
설정 Cloud 프로젝트, OAuth 클라이언트, SHA-1 지문 Manifest 권한, 개인정보 처리방침 화면
사용 가능 여부 Play services가 설치된 모든 Android 기기 Android 14+ 내장, 이전 버전은 Google Play 앱 사용
기록 전체 계정 기록 기본적으로 최근 30일, 이전 데이터는 READ_HEALTH_DATA_HISTORY
웹/서버 액세스 REST API 없음 (클라우드용 Google Health API 사용)
iOS 지원되지 않음 지원되지 않음, HealthKit을 사용하세요
스토어 심사 민감한 스코프에 대한 OAuth 검증 Play Console Health Connect 선언

가장 큰 제품 변화는 기기 중심 모델입니다. 한 휴대폰의 Health Connect 데이터는 다른 휴대폰에서 보이지 않습니다. 앱에서 기기 간 기록을 표시한다면 측정값을 자체 백엔드로 동기화하세요.

Fit 데이터 타입을 Health Connect로 매핑

Google Fit 데이터 타입 Health Connect 레코드 @capgo/capacitor-health 타입
com.google.step_count.delta StepsRecord steps
com.google.distance.delta DistanceRecord distance
com.google.calories.expended TotalCaloriesBurnedRecord / ActiveCaloriesBurnedRecord totalCalories / calories
com.google.calories.bmr BasalMetabolicRateRecord basalCalories
com.google.heart_rate.bpm HeartRateRecord heartRate
com.google.weight WeightRecord weight
com.google.height HeightRecord height
com.google.body.fat.percentage BodyFatRecord bodyFat
com.google.sleep.segment SleepSessionRecord 단계 포함 sleep
com.google.oxygen_saturation OxygenSaturationRecord oxygenSaturation
com.google.blood_pressure BloodPressureRecord bloodPressure
com.google.blood_glucose BloodGlucoseRecord bloodGlucose
com.google.body.temperature BodyTemperatureRecord bodyTemperature
com.google.hydration HydrationRecord dietaryWater
com.google.nutrition NutritionRecord dietaryEnergyConsumed (에너지 전용)
com.google.activity.segment 및 세션 API ExerciseSessionRecord workouts (다음을 통해 읽음 queryWorkouts)

직접 대응되는 항목이 없는 Fit 타입

  • 심박수 점수(Heart Points) (com.google.heart_minutes) 및 활동 시간(Move Minutes) (com.google.active_minutes)는 Google Fit의 점수였습니다. Health Connect는 이러한 점수가 아닌 원시 데이터를 저장합니다. 심박수와 운동 세션을 기반으로 직접 지표를 다시 계산해야 합니다.
  • 활동 샘플 초 단위 활동 유형은 세그먼트가 포함된 운동 세션으로 대체됩니다.
  • 위치 샘플 운동 중 위치 데이터는 ExerciseRoute Health Connect 데이터로 전환됩니다. 이는 별도의 권한이 필요하며 플러그인에서 직접 제공되지 않습니다.
  • 리듬, 속도, 그리고 강도 는 Health Connect (StepsCadenceRecord, SpeedRecord, PowerRecord)에 존재하지만 플러그인 타입에는 포함되어 있지 않습니다. 이 기능들이 필요하다면, 간단한 커스텀 native method를 만드는 것이 가장 빠릅니다.

code 작성 전 감사 단계: 호출하는 모든 DataType 및 모든 API (History, Recording, Sessions, Sensors, Config, REST)를 나열하고, 각각 매핑, 재계산 또는 제외 여부를 표시하세요.

1단계: Google Fit 제거

Android 프로젝트와 JavaScript에서 Fit 통합 코드를 삭제하세요:

  • 제거 com.google.android.gms:play-services-fitness 또한, Fit 용도로만 사용되었다면, play-services-auth 과 build.gradle.
  • Google Cloud에서 Fit OAuth 클라이언트를 제거하고 동의 화면에서 fitness scope를 삭제하세요.
  • 기존에 사용하던 커뮤니티 Google Fit Capacitor 플러그인을 삭제한 후, 다음 명령어를 실행하세요: bunx cap sync.

새 버전이 배포될 때까지 기존 Fit code를 브랜치에 유지하세요. 그래야 사용자가 요청할 경우 과거 데이터를 내보낼 수 있습니다.

2단계: health 플러그인 설치

bun add @capgo/capacitor-health
bunx cap sync

@capgo/capacitor-health Capacitor 8을 지원하며, Android에서는 Health Connect를, iOS에서는 HealthKit을 사용합니다. Android에서는 minSdk 26.

Android 설정

이 플러그인은 지원되는 유형에 대해 Health Connect 읽기 및 쓰기 권한을 manifest에 병합하며, 또한 <queries> Health Connect 패키지 항목과 권한 근거(rationale) 액티비티를 추가합니다. 다음 작업이 필요합니다:

  1. 개인정보 처리방침을 제공하세요. Health Connect는 권한 시트에서 이를 엽니다. 다음 중 하나를 수행하세요. android/app/src/main/assets/public/privacypolicy.html, 또는 에 URL을 설정하세요. android/app/src/main/res/values/strings.xml:
<string name="health_connect_privacy_policy_url">https://example.com/privacy</string>
  1. 권한 최소화. Google Play는 선언된 모든 Health Connect 권한을 검토합니다. 걸음 수와 심박수만 읽는다면, 나머지는 로 제거하세요. tools:node="remove":
<uses-permission
    android:name="android.permission.health.WRITE_BLOOD_GLUCOSE"
    tools:node="remove" />
  1. 필요한 경우 기록 접근 권한을 추가하세요. 사용자가 허용하지 않으면 Health Connect는 최근 약 30일간의 데이터만 읽을 수 있습니다. READ_HEALTH_DATA_HISTORY:
<uses-permission android:name="android.permission.health.READ_HEALTH_DATA_HISTORY" />

iOS 설정

Xcode에서 HealthKit capability를 활성화하고 다음 항목에 usage strings를 추가하세요. Info.plist:

<key>NSHealthShareUsageDescription</key>
<string>Show your steps and workouts in the app.</string>
<key>NSHealthUpdateUsageDescription</key>
<string>Save the workouts you record in the app.</string>

3단계: 사용 가능 여부 확인

Google Fit은 Play services가 있는 곳이라면 어디서든 작동했습니다. 하지만 Health Connect는 Android 13 이하 버전에서 누락되었거나 업데이트가 필요할 수 있습니다.

import { Health } from '@capgo/capacitor-health';

export async function ensureHealthAvailable() {
  const result = await Health.isAvailable();
  if (result.available) return true;

  // On Android, send the user to install or update Health Connect
  if (result.platform === 'android') {
    await Health.openHealthConnectSettings();
  }
  console.warn('Health store unavailable:', result.reason);
  return false;
}

리다이렉트하기 전에 짧은 설명 화면을 보여주세요. Health Connect를 처음 접하는 사용자는 Play Store가 갑자기 열리면 당황할 수 있습니다.

4단계: OAuth를 권한으로 대체

기존 Fit 흐름은 Google Sign-In, fitness scope 요청, API 호출 순이었습니다. 새로운 흐름은 단일 권한 시트 방식입니다:

const status = await Health.requestAuthorization({
  read: ['steps', 'distance', 'calories', 'heartRate', 'sleep', 'workouts'],
  write: ['weight'],
  requestHistoryAccess: true, // Android only
});

if (status.readDenied.length > 0) {
  // explain what will not work and offer openHealthConnectSettings()
}
if (status.historyAccessAvailable === false) {
  // provider too old: only the last 30 days are readable
}

권한은 데이터 유형별로 부여되며 사용자는 원하는 항목만 선택할 수 있습니다. 다음을 사용하세요. checkAuthorization 사용자가 언제든 Health Connect 설정에서 액세스 권한을 취소할 수 있으므로, 앱을 시작할 때마다 동일한 옵션을 사용해야 합니다. iOS의 경우, HealthKit은 개인정보 보호를 위해 읽기 거부 상태를 숨기므로 빈 결과가 '데이터 없음'인지 '액세스 권한 없음'인지 구분해야 합니다.

5단계: History API 읽기 교체

Fit readData raw samples 호출 방식이 다음과 같이 변경됩니다: readSamples:

const end = new Date();
const start = new Date(end.getTime() - 24 * 60 * 60 * 1000);

const { samples } = await Health.readSamples({
  dataType: 'heartRate',
  startDate: start.toISOString(),
  endDate: end.toISOString(),
  limit: 500,
  ascending: true,
});

for (const s of samples) {
  console.log(s.startDate, s.value, s.unit, s.sourceName, s.deviceType);
}

sourceName 또한, Android에서는 deviceType (watch, phone, chestStrap등의 방식으로 Fit의 데이터 소스 객체를 대체합니다. 두 데이터가 모두 존재할 경우, 폰 데이터보다 워치 데이터를 우선하도록 설정하세요.

6단계: 버킷화된 읽기와 집계 읽기 교체

Fit의 bucketByTime 및 aggregate 로 변경됩니다 queryAggregated:

const { samples: daily } = await Health.queryAggregated({
  dataType: 'steps',
  startDate: new Date(Date.now() - 7 * 86_400_000).toISOString(),
  endDate: new Date().toISOString(),
  bucket: 'day',          // 'hour' | 'day' | 'week' | 'month'
  aggregation: 'sum',
});

const { samples: hr } = await Health.queryAggregated({
  dataType: 'heartRate',
  bucket: 'hour',
  aggregation: ['min', 'average', 'max'],
  startDate: new Date(Date.now() - 86_400_000).toISOString(),
  endDate: new Date().toISOString(),
});
// hr[i].values.min, hr[i].values.average, hr[i].values.max

원시 샘플을 합산하는 대신 항상 걸음 수를 집계하세요. Health Connect는 집계 과정에서 여러 앱의 겹치는 데이터를 중복 제거하며, 워치와 휴대폰이 모두 걸음 수를 기록하면 원시 합계는 종종 이중 계산됩니다.

7단계: Sessions API 교체

Fit 세션은 운동 세션에 매핑됩니다:

const { workouts, anchor } = await Health.queryWorkouts({
  workoutType: 'running',
  startDate: new Date(Date.now() - 30 * 86_400_000).toISOString(),
  endDate: new Date().toISOString(),
  limit: 50,
});

for (const w of workouts) {
  console.log(w.workoutType, w.duration, w.totalDistance, w.totalEnergyBurned);
}
// pass `anchor` back to fetch the next page

요청 workouts 에서 read 권한을 먼저 요청하세요. 이 플러그인은 워크아웃을 읽을 수는 있지만 운동 세션을 직접 쓰지는 않습니다. 따라서 앱이 워크아웃을 기록한다면, 기반이 되는 샘플(거리, 칼로리, 심박수)을 기록하고 세션 자체는 백엔드에 유지하거나, 다음을 위한 네이티브 메서드를 추가하세요: ExerciseSessionRecord.

8단계: insert 작업 교체

Fit의 insertData 로 변경됩니다 saveSample:

await Health.saveSample({
  dataType: 'weight',
  value: 72.4, // kilograms
  startDate: new Date().toISOString(),
});

await Health.saveSample({
  dataType: 'bloodPressure',
  value: 120,
  systolic: 120,
  diastolic: 80,
  startDate: new Date().toISOString(),
});

값은 각 타입의 기본 단위(kg, m, kcal, bpm)를 사용해야 합니다. 해당 metadata 옵션은 Health Connect에서 무시됩니다.

9단계: Google Play 심사 통과

건강 권한은 추가 심사가 필요합니다:

  1. Play Console에서 다음을 여세요: 앱 콘텐츠 및 다음을 완료하세요: 건강 앱 선언문과 Health Connect 권한 양식을 작성하세요. 요청하는 모든 권한에 대해 타당한 근거를 제시해야 합니다.
  2. Play Console에 연결된 개인정보 처리방침과 Health Connect 시트에 표시되는 방침이 건강 데이터 사용 방식을 명확히 설명하고 있는지 확인하세요.
  3. 다음 파일을 업데이트하세요: 데이터 보안 양식: 건강 및 피트니스 데이터 — 수집 여부, 공유 여부.
  4. 정당화한 권한만 선언한 빌드를 제출하세요. 추가로 선언한 권한이 가장 흔한 거절 사유입니다.

검토가 일반 업데이트보다 오래 걸릴 수 있으니 대비하세요. 마이그레이션은 다른 기능과 섞지 말고 별도 릴리스로 배포하세요.

10단계: 사용자 기대치 전환

  • 사용자에게 이제 기록이 Health Connect에서 제공되며, 기록 접근 권한을 허용하기 전까지는 이전 데이터가 30일로 제한될 수 있음을 알리세요.
  • 앱이 Google Fit을 클라우드 동기화 용도로 사용했다면, 이제 해당 역할을 백엔드로 이전해야 합니다.
  • “Connect Google Fit” 버튼을 제거하고, Android에서는 “Connect Health Connect”, iOS에서는 “Connect Apple Health”로 이름을 변경하세요.

문제 해결

isAvailable() Android 13에서 false 반환: Health Connect가 설치되지 않았거나 버전이 낮습니다. 호출하세요 openHealthConnectSettings().

권한 요청 시트가 나타나지 않음: 병합된 manifest에 권한이 선언되지 않았거나, 다음으로 제거했습니다: tools:node="remove". 확인하세요 android/app/build/intermediates/merged_manifests.

읽기 데이터는 최근 30일치만 반환됩니다: 요청 requestHistoryAccess: true 그리고 선언하세요 READ_HEALTH_DATA_HISTORY.

걸음 수 합계가 Google Fit보다 높음: raw sample을 합산했습니다. 다음을 사용하세요: queryAggregated.

iOS에서 결과가 비어 있음: 데이터가 없거나 읽기 권한이 거부된 경우입니다. HealthKit은 어느 쪽인지 알려주지 않습니다.

Play Console에서 업데이트를 거부함: 선언되지 않았거나 근거가 부족한 Health Connect 권한을 제거하고, 명확한 사유와 함께 다시 제출하세요.

단계별로 마이그레이션 배포하기

The native part (plugin, manifest, HealthKit capability) needs a store release. After that, queries, UI and data mapping are JavaScript, which you can iterate on with Capgo Live Update 사용하기 사용자가 새 플로우를 테스트하는 동안이죠. 실시간 센서 데이터도 읽는다면, 다음 가이드를 참고하세요: Capacitor로 심박수 모니터 만들기, 그리고 health 플러그인 문서 에서 모든 데이터 타입을 다룹니다.

Capacitor 앱용 Live updates

웹 레이어 버그가 라이브 상태라면, 앱 스토어 승인을 며칠씩 기다리지 말고 Capgo를 통해 수정 사항을 배포하세요. 네이티브 변경 사항은 정상 리뷰 절차를 그대로 따르는 반면, 사용자는 백그라운드에서 업데이트를 받습니다.

블로그 최신 글

Capgo는 정말 프로페셔널한 모바일 앱을 만드는 데 필요한 최고의 인사이트를 제공합니다.