使用R调用Firestore Patch写入数据时JSON格式报错求助
解决Firestore REST API导入JSON数据的400错误(R语言)
核心错误原因
- 单文档PATCH接口格式要求严格:你成功的示例用了
fields嵌套结构,这是Firestore REST API接受的原生格式——所有字段必须包裹在fields下,且每个值要明确指定类型(如stringValue、integerValue)。而你提交的users是顶层字段,完全不符合接口规范,因此报错"Unknown name 'users'"。 - 数组结构未遵循Firestore规范:即使要把数组作为某个文档的字段,也需要用
arrayValue+mapValue的嵌套结构,不能直接使用普通JSON数组。 - 批量导入的误解:如果你的目标是创建多个独立的用户文档(每个用户对应集合中的一个文档),单个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
相关产品推荐
相关产品推荐

