You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Fit REST API授权失败求助&健康历史数据写入需求

解决Google Fit OAuth授权错误及数据写入指导

一、OAuth授权错误(错误400: invalid_request)修复方案

1. 修正OAuth客户端配置

  • 确保在Google Cloud控制台创建的是桌面应用类型的OAuth客户端ID。本地脚本属于桌面应用场景,若之前创建的是Web/移动应用类型,需重新创建桌面客户端,系统会自动生成适配的重定向URI(如urn:ietf:wg:oauth:2.0:oob或http://localhost)。
  • 脚本中redirect_uri需使用单个URI字符串,而非列表。修改代码:
    # 原代码:redirect_uri = redirect_uris
    redirect_uri = redirect_uris[0]  # 取列表第一个元素
    

2. 缩小权限范围

替换宽泛的https://www.googleapis.com/auth/fitness范围,根据实际需求使用具体权限:

  • 写入活动数据(如步数):https://www.googleapis.com/auth/fitness.activity.write
  • 写入心率数据:https://www.googleapis.com/auth/fitness.heart_rate.write
  • 其他数据类型对应权限可参考Google Fit官方权限说明

3. 添加测试用户(未验证应用)

未通过Google OAuth验证的应用只能对测试用户开放授权:

  1. 进入Google Cloud控制台 → API和服务 → OAuth同意屏幕
  2. 在“测试用户”板块添加你自己的Google账号
  3. 使用该测试账号进行授权操作

4. 修正API请求URL

脚本中最后两个GET请求存在路径错误,修正为:

# 获取步数衍生数据源详情
r = google.get('https://www.googleapis.com/fitness/v1/users/me/dataSources/derived:com.google.step_count.delta:com.google.android.gms:merge_step_deltas')
# 获取当前用户所有数据源
r = google.get('https://www.googleapis.com/fitness/v1/users/me/dataSources')

二、Google Fit REST API写入数据步骤

1. 匹配数据类型与数据源

首先确认Apple Health数据对应的Google Fit数据类型,比如:

  • 步数:com.google.step_count.delta
  • 体重:com.google.weight
  • 心率:com.google.heart_rate.bpm

对于常见数据类型,可直接使用Google提供的衍生数据源(如步数的derived:com.google.step_count.delta:com.google.android.gms:merge_step_deltas),无需自定义数据源。

2. 构造符合要求的请求体

Google Fit写入数据使用users/me/dataset:patch接口,请求体需包含:

  • dataSourceId:目标数据源ID
  • point:数据点数组,每个数据点需包含:
    • startTimeNanos:数据起始时间(纳秒级字符串)
    • endTimeNanos:数据结束时间(纳秒级字符串)
    • value:数据值(根据类型选择intVal/floatVal/stringVal等)

3. pandas DataFrame转Google Fit数据示例

假设你的DataFrame包含date(日期)和step_count(当日步数)两列,转换并写入的代码示例:

import pandas as pd

# 示例DataFrame
df = pd.DataFrame({
    'date': ['2024-01-01', '2024-01-02'],
    'step_count': [8500, 9200]
})

# 配置参数
data_source_id = "derived:com.google.step_count.delta:com.google.android.gms:merge_step_deltas"

# 构造数据点
data_points = []
for _, row in df.iterrows():
    # 转换日期为纳秒时间戳
    start_ts = pd.Timestamp(row['date']).timestamp() * 1e9
    end_ts = start_ts + 86400 * 1e9  # 当日结束时间(+1天的秒数转纳秒)
    
    data_points.append({
        "startTimeNanos": str(int(start_ts)),
        "endTimeNanos": str(int(end_ts)),
        "value": [{"intVal": int(row['step_count'])}]
    })

# 构造数据集ID(格式:起始纳秒-结束纳秒)
start_nanos = str(int(pd.Timestamp(df['date'].min()).timestamp() * 1e9))
end_nanos = str(int(pd.Timestamp(df['date'].max()).timestamp() * 1e9 + 86400 * 1e9))
dataset_id = f"{start_nanos}-{end_nanos}"

# 发送写入请求
response = google.patch(
    url=f"https://www.googleapis.com/fitness/v1/users/me/datasets/{dataset_id}",
    json={"dataSourceId": data_source_id, "point": data_points}
)

# 检查响应
if response.status_code == 200:
    print("数据写入成功")
else:
    print(f"写入失败:{response.json()}")

4. 注意事项

  • 拆分数据写入:避免一次性写入过大时间范围的数据,建议按天或按周拆分请求,避免触发API限流。
  • 去重处理:若数据已存在于Google Fit,重复写入会覆盖原有数据,建议先查询已有数据再决定是否写入。
  • 配额限制:Google Fit API有每日请求配额,若数据量较大,需添加请求间隔(如time.sleep(1))。

内容的提问来源于stack exchange,提问作者SiSchi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 13:51:30