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

使用R调用Firestore Patch写入数据时JSON格式报错求助

解决Firestore REST API导入JSON数据的400错误(R语言)

核心错误原因

  1. 单文档PATCH接口格式要求严格:你成功的示例用了fields嵌套结构,这是Firestore REST API接受的原生格式——所有字段必须包裹在fields下,且每个值要明确指定类型(如stringValue、integerValue)。而你提交的users是顶层字段,完全不符合接口规范,因此报错"Unknown name 'users'"。
  2. 数组结构未遵循Firestore规范:即使要把数组作为某个文档的字段,也需要用arrayValue+mapValue的嵌套结构,不能直接使用普通JSON数组。
  3. 批量导入的误解:如果你的目标是创建多个独立的用户文档(每个用户对应集合中的一个文档),单个PATCH请求无法完成,需要对每个用户单独发送POST/PUT请求。

解决方案分两种情况

情况1:将users数组作为单个文档的字段

需要把数组转换成Firestore要求的arrayValue格式,示例JSON如下:

{
  "fields": {
    "users": {
      "arrayValue": {
        "values": [
          {
            "mapValue": {
              "fields": {
                "id": {"stringValue": "1"},
                "firstName": {"stringValue": "Kristin"},
                "lastName": {"stringValue": "Smith"},
                "occupation": {"stringValue": "Teacher"},
                "reviewCount": {"integerValue": "6"},
                "reviewScore": {"integerValue": "5"}
              }
            }
          },
          {
            "mapValue": {
              "fields": {
                "id": {"stringValue": "2"},
                "firstName": {"stringValue": "Olivia"},
                "lastName": {"stringValue": "Parker"},
                "occupation": {"stringValue": "Teacher"},
                "reviewCount": {"integerValue": "11"},
                "reviewScore": {"integerValue": "5"}
              }
            }
          }
        ]
      }
    }
  }
}

在R中可以用工具包自动转换格式:

library(httr)
library(purrr)
library(jsonlite)

# 读取原始JSON数据
raw_data <- fromJSON("your_file.json")$users

# 定义格式转换函数
convert_to_firestore <- function(user) {
  fields <- map(user, function(val) {
    if (grepl("^\\d+$", val)) {
      list(integerValue = val)
    } else {
      list(stringValue = val)
    }
  })
  list(mapValue = list(fields = fields))
}

# 生成符合要求的请求体
firestore_body <- list(
  fields = list(
    users = list(
      arrayValue = list(
        values = map(raw_data, convert_to_firestore)
      )
    )
  )
)

# 调用你的写数据函数
write.db(db_endpoint, firestore_body, auth_token)

情况2:批量创建多个独立的用户文档

此时需要针对集合发送POST(自动生成文档ID)或PUT(指定文档ID为用户的id)请求,示例R代码:

library(httr)
library(purrr)
library(jsonlite)

batch_write_users <- function(collection_endpoint, users_data, auth_token) {
  results <- map(users_data, function(user) {
    # 转换单个用户数据为Firestore格式
    user_fields <- map(user, function(val) {
      if (grepl("^\\d+$", val)) {
        list(integerValue = val)
      } else {
        list(stringValue = val)
      }
    })
    body <- list(fields = user_fields)
    
    # 若要指定文档ID为user$id,使用PUT请求
    # endpoint <- paste0(collection_endpoint, "/", user$id)
    # r <- PUT(endpoint, add_headers(...), body = body, encode = "json")
    
    # 自动生成文档ID,使用POST请求
    r <- POST(collection_endpoint,
              add_headers("Content-Type" = "application/json",
                          "Authorization" = paste("Bearer", auth_token)),
              body = body, encode = "json")
    return(r)
  })
  return(results)
}

# 使用示例
users_data <- fromJSON("your_file.json")$users
collection_endpoint <- "https://firestore.googleapis.com/v1/projects/[你的项目ID]/databases/(default)/documents/users"
batch_write_users(collection_endpoint, users_data, auth_token)

额外注意点

  • 你原始JSON中第一个用户的reviewScore字段后多了一个逗号,会导致JSON解析错误,需要删除。
  • 确保接口地址格式正确:单文档PATCH的地址是/documents/[集合名]/[文档ID],集合POST的地址是/documents/[集合名]。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 01:00:57