Google Health API 是一种从头开始构建的新 API,可让开发者查询 Fitbit 用户数据。这不仅仅是一次更新,更是一项战略举措,旨在确保您的应用安全可靠,并为未来健康技术的进步做好准备。该 API 支持用于注册应用的新控制台、Google OAuth 2.0 支持、新数据类型、新端点架构和新响应格式。
本指南旨在帮助开发者将其现有的 Fitbit Web API 应用迁移到新的 Google Health API。
为什么应该进行迁移?
使用 Google Health API 的好处包括:
- 增强安全性:符合 Google 的安全最佳实践,与 Google 的安全性、隐私权和身份标准保持一致。
- 一致性:消除了数据格式、时区、计量单位和错误处理方面的旧版不一致性,从而提供更直观的开发者体验。
- 可伸缩性和未来适用性:旨在实现可伸缩性,以满足未来的需求,并支持 gRPC 等现代协议。
应用注册
所有 Google Health API 应用都必须使用 Google Cloud 控制台进行注册,该控制台是用于管理所有 Google 应用的中央枢纽。
如需了解如何注册应用,请按照使用入门中的步骤操作。以下是注册应用时您会发现的一些区别。
| Fitbit Web API | Google Health API | |
| 公开链接 | https://dev.fitbit.com/apps | https://console.cloud.google.com |
| 添加新应用 | 按 Register a new app |
|
| 基本信息 | 需要填写的字段:
|
需要填写的字段:
|
| 应用类型 | 开发者必须选择:
|
|
| 客户 ID | 在保存应用设置时注册 | 单独注册 |
| 访问类型 | 读写权限在应用级进行控制 | 读写权限在范围级别进行控制 |
| 其他网址 |
|
|
OAuth 实现
Google 健康数据 API 应用仅支持 Google OAuth2 客户端库。客户端库支持多种主流框架,可简化 OAuth 2.0 的实现。Google OAuth2 库与开源 OAuth2 库之间的区别如下:
| Fitbit Web API | Google Health API | |
| OAuth2 库支持 | 开源 | Google OAuth2 客户端库 |
| 功能 | 在不同平台之间不一致 | 在各个平台上保持一致 |
| 授权网址 | https://www.fitbit.com/oauth2/authorize | https://accounts.google.com/o/oauth2/v2/auth |
| 令牌网址 | https://api.fitbit.com/oauth2/token | https://oauth2.googleapis.com/token |
| 访问令牌生命周期 | 8 小时 | 1 小时 |
| 访问令牌大小 | 1024 个字节 | 2048 字节 |
| 刷新令牌 | 使用授权代码授权流程时会生成刷新令牌。每个用户只能生成 1 个刷新令牌。令牌永不过期,但只能使用一次。 | 如需生成刷新令牌,授权字符串必须包含查询参数“access_type=offline”。可以为单个用户创建多个刷新令牌。刷新令牌可以基于时间。如果这些令牌在 6 个月内未使用、用户授予了基于时间的访问权限,或者应用处于“测试”模式,则这些令牌将过期。如需了解详情,请参阅刷新令牌过期。 |
| 令牌响应 | JSON 响应包含:
|
JSON 响应包含:
如需获取用户 ID,请使用 users.getIdentity 端点。 |
用户重新身份验证(强制重新征求用户同意)
Fitbit 用户必须重新同意您的新集成,因为您的应用使用的是不同的 OAuth 库。访问令牌和刷新令牌无法转移到 Google Health API 并正常运行。
范围
您必须更新授权请求,以使用 Google Health API 范围。 这些范围定义了您的应用是否支持读取或写入操作。请勿使用应用不需要的范围。如果应用的设计发生变化,您随时可以添加更多范围。
Google Health API 范围是一个 HTTP 网址,以 https://www.googleapis.com/auth/googlehealth.{scope} 开头。例如,https://www.googleapis.com/auth/googlehealth.activity_and_fitness。
范围映射
以下是 Fitbit Web API 范围与 Google Health API 范围的对应关系:
| Fitbit Web API 范围 | Google Health API 范围 |
|---|---|
| 活动 | .activity_and_fitness .activity_and_fitness.readonly |
| cardio_fitness | .activity_and_fitness .activity_and_fitness.readonly |
| 心率 | .health_metrics_and_measurements .health_metrics_and_measurements.readonly |
| 地理位置 | .location.readonly |
| 营养 | .nutrition .nutrition.readonly |
| oxygen_saturation | .health_metrics_and_measurements .health_metrics_and_measurements.readonly |
| 个人资料 | .profile .profile.readonly |
| respiratory_rate | .health_metrics_and_measurements .health_metrics_and_measurements.readonly |
| 设置 | .settings .settings.readonly |
| sleep | .sleep .sleep.readonly |
| 温度 | .health_metrics_and_measurements .health_metrics_and_measurements.readonly |
| 重量 | .health_metrics_and_measurements .health_metrics_and_measurements.readonly |
数据类型
下表列出了 Google Health API 数据类型及其与 Fitbit Web API 的对应关系。
| Fitbit Web API 数据类型 | Google Health API 数据类型 端点 ID |
|---|---|
| 活跃区间分钟数 | 活跃区间分钟数active-zone-minutes
|
| 包含用户活动级别的变化 | 活动级别activity-level
|
| 海拔 | 海拔altitude
|
| 体脂 | 体脂率body-fat
|
处于每个心率区间的时长:caloriesOut |
各心率区间的卡路里消耗量calories-in-heart-rate-zone
|
| HRV 摘要 | 每日心率变异性daily-heart-rate-variability
|
| 血氧饱和度总结 | 每日血氧饱和度daily-oxygen-saturation
|
| 静息心率 | 每日静息心率daily-resting-heart-rate
|
| 体表温度 | 每日睡眠温度推导daily-sleep-temperature-derivations
|
| 距离 | 距离distance
|
| 已录制的活动 | 锻炼exercise
|
| 楼层数 | 爬楼层数floors
|
| 心率 | 心率heart-rate
|
| HRV 当日 | 心率变异性heart-rate-variability
|
| 血氧饱和度 (SpO2) 当日 | 血氧饱和度图标 oxygen-saturation
|
| 用户跑步时的最大摄氧量值 | 跑步最大摄氧量run-vo2-max
|
| 活动时间序列(分钟)- 久坐 | 久坐时段sedentary-period
|
| 睡眠 | 睡眠图标 sleep
|
| 步骤 | 步骤steps
|
活动 caloriesOut |
总卡路里数total-calories
|
| 最大摄氧量值 | 最大摄氧量vo2-max
|
| 重量 | 权重weight
|
端点
REST 端点针对所有数据类型采用一致的语法。
- 服务端点:基础 HTTP 网址更改为 https://health.googleapis.com。
- 端点语法:Google Health API 支持有限数量的端点,这些端点可用于大多数受支持的数据类型。这为所有数据类型提供了一致的语法,并使端点更易于使用。
- 用户标识符:应在端点语法中指定用户 ID 或 me。使用 me 时,系统会根据访问令牌推断用户 ID。
示例:以下是使用 Google Health API 调用的 GET Profile 端点的示例
GET https://health.googleapis.com/v4/users/me/profile
端点映射
如需查看可用数据类型及其支持的 API 方法的列表,请参阅数据类型可用性表格。
| Fitbit Web API 端点类型 | Google Health API |
| GET(日志 | 摘要 | 日摘要),用于请求单天数据 | windowSize = 1 天的 dailyRollup 方法 |
| GET(日内),用于请求精细数据 | list 方法 |
| 按日期或时间间隔获取(时间序列) | 包含日期范围的 rollUp 或 dailyRollUp 方法 |
| GET(日志列表) | list 方法 |
| 创建和更新日志 | patch 方法 |
| 删除日志 | batchDelete 方法 |
| 获取个人资料 | users.getProfile 返回用户的特定信息
users.getSettings 返回用户的单位和时区 |
| 更新个人资料 | users.updateProfile 修改用户的特定信息
users.updateSettings 修改用户的单位和时区 |
| 获取用户 ID | users.getIdentity 会返回用户的 Fitbit 旧版用户 ID 和 Google 用户 ID。 |
迁移用户
从 Fitbit Web API 迁移到 Google Health API 不仅仅是一项技术更新。由于更改了 OAuth 库,您的用户必须重新同意新的集成。访问令牌和刷新令牌无法转移到 Google Health API 并正常运行。为帮助您在迁移期间留住用户,我们提供了一些技术和战略建议,以确保迁移成功。
双库策略
由于 Fitbit Web API 和 Google Health API 使用不同的 OAuth2 库,您必须管理一个“过渡”期,在此期间,您的代码库中同时存在这两个库。
并行授权管理
- 封装客户端:为“健康服务”创建抽象层或接口。这样一来,应用的其余部分就可以请求数据,而无需知道哪个库(Fitbit OAuth 与 Google OAuth)对特定用户处于有效状态。
- 数据库架构更新:更新用户表以添加
oauth_type标志。例如,使用fitbit表示 Fitbit OAuth,使用google表示 Google OAuth。- 新用户:默认使用 Google Health API 和 Google OAuth 库。将
oauth_type设为google。 - 现有用户:在完成重新征得同意流程之前,继续使用 Fitbit Web API。将
oauth_type设为fitbit。
- 新用户:默认使用 Google Health API 和 Google OAuth 库。将
“逐步”重新征求同意流程
请勿强制用户退出,而应采用增量授权方法:
- 检测 Fitbit 开源令牌:当 Fitbit Web API 用户打开应用时,触发“服务更新”通知。
- 启动 Google OAuth 流程:当用户点击“更新”时,启动 Google OAuth2 库流程。
- 替换和撤消:成功收到 Google OAuth 令牌后,将其保存到用户个人资料中,将
oauth_type从fitbit更新为google,并(如果可能)以程序化方式撤消旧的fitbit令牌,以保持用户安全个人资料的整洁。
最大限度地提高用户留存率
重新征得同意是客户流失的“危险地带”。为防止用户放弃使用应用,请遵循以下用户体验最佳实践:
“价值优先”的沟通方式
不要以“我们更新了 API”开头。首先介绍由 Google 支持的新系统的优势:
- 增强型安全:提及 Google 业界领先的账号保护功能和双重身份验证。
- 可靠性:同步速度更快,数据连接更稳定。
- 功能门控:温和地告知用户,新功能和数据类型需要更新。
智能定时
- 不要中断高价值任务:切勿在用户锻炼或记录饮食时触发权限请求页面。
- “智能推送”阶段:在前 30 天内,使用可关闭的横幅。
- “硬性截止”阶段:在发出警告数周后,才强制要求重新征得用户同意,同时与 Fitbit Web API 的正式弃用截止日期保持一致。
迁移流程比较
通过清晰的视觉区分来区分旧流程和新流程,有助于开发者了解逻辑分支的位置。
| 功能 | Fitbit Web API(旧版) | Google Health API (Google-Identity) |
| 身份验证库 | 标准开放源代码 | Google Identity Services (GIS) / Google Auth |
| 用户账号 | Fitbit 旧版凭据 | Google 账号 |
| 令牌类型 | Fitbit 专用访问权限 / 刷新 | Google 颁发的访问令牌/刷新令牌 |
| 范围管理 | 广泛的权限 | 精细 / 增量权限 |
处理账号迁移的细微差别
根据 Fitbit 的文档,将账号迁移到 Google 的用户通常不会立即失去第三方连接,但更改 API 版本是开发者端的要求。
- 检查令牌有效性:使用后台工作器检查 Fitbit 令牌是否因“未经授权”错误而失败。这可能表示用户已迁移其账号,但您的应用尚未跟上。
- 正常失败:如果 Fitbit OAuth 调用失败,请将用户重定向到专门使用新的 Google OAuth 流程的自定义“重新关联 Fitbit”页面。
代码示例
如需从旧版 Fitbit Web API 迁移到 Google Health API,您需要从常规 OAuth2 库迁移到 Google Auth 库。以下是架构建议和使用 JavaScript 编写的伪代码实现,用于处理这种“双库”状态。
1. “中间件开关”
由于您无法一次性迁移所有用户,因此后端需要根据数据库中存储的用户当前 apiVersion 来确定要使用的库。
实现
const { OAuth2Client } = require('google-auth-library');
const FitbitV1Strategy = require('fitbit-oauth2-library').Strategy;
// 1. Initialize the Google Health API Client
const GHAClient = new OAuth2Client(
process.env.GOOGLE_CLIENT_ID,
process.env.GOOGLE_CLIENT_SECRET,
process.env.REDIRECT_URI
);
// 2. Create a Unified Fetcher
async function fetchSteps(user) {
if (user.apiVersion === 4) {
// ---- GOOGLE OAUTH LIBRARY LOGIC ----
GHAClient.setCredentials({ refresh_token: user.refreshToken });
const url = 'GET https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints';
const res = await GHAClient.request({ url });
return res.data;
} else {
// ---- FITBIT WEB API LEGACY LOGIC ----
// Use your existing Fitbit open-source library logic here
return callLegacyV1Api(user.accessToken);
}
}
2. 迁移用户体验流程
如需最大限度地提高留存率,请使用“中断并升级”模式。这样可确保用户在与应用互动之前不会被迫重新登录。
重定向逻辑
当 Fitbit Web API 用户使用特定功能时,触发迁移:
app.get('/dashboard', async (req, res) => {
const user = await db.users.find(req.user.id);
if (user.apiVersion === 1) {
// Render a "soft" migration page explaining the Google transition
return res.render('migrate-to-google', {
title: "Keep your data syncing",
message: "Fitbit is moving to Google accounts. Re-connect now to stay updated."
});
}
const data = await fetchSteps(user);
res.render('dashboard', { data });
});
3. 关键技术过渡
编写 JavaScript 迁移脚本时,请牢记以下几点差异:
| 功能 | Fitbit Web API(旧版) | Google Health API (Google-Identity) |
| 令牌端点 | https://api.fitbit.com/oauth2/token | https://oauth2.googleapis.com/token |
| 身份验证库 | 标准开放源代码 | Google 身份验证 |
| 范围 | 活动 | https://www.googleapis.com/auth/googlehealth.activity_and_fitness |
| 用户 ID | /oauth2/token 响应中返回的 Fitbit 编码 ID | 从 users.getIdentity 端点返回的用户 ID |
4. 留存核对清单
- 会话持久性:在成功验证 Google Health API access_token 并将其保存到数据库之前,请勿清除用户的旧 Fitbit Web API 会话。
- 自动撤消:Google Health API 迁移完成后,请使用 POST 请求向旧版 Fitbit 撤消端点发送请求:https://api.fitbit.com/oauth2/revoke。这样可确保用户不会在 Fitbit 设置中看到“重复”的应用权限。
- 错误处理:如果 Fitbit 调用返回 401 未经授权,则自动重定向到 Google OAuth 流程,而不是显示出错提示。