将 POST 正文发送到 Firestore REST API 时出现问题

Wom*_*rat 5 google-apps-script python-requests firebase axios google-cloud-firestore

我想使用 REST API 在 Firestore 中创建一个新文档。

这里使用 Axios 发送带有某些字段的 POST 请求是非常好的示例:
https://www.jeansnyman.com/posts/google-firestore-rest-api-examples/

axios.post(
"https://firestore.googleapis.com/v1/projects/<PROJECTIDHERE>/databases/(default)/documents/<COLLECTIONNAME>", 
    { 
        fields: { 
            title: { stringValue: this.title }, 
            category: { stringValue: this.category }, 
            post: { stringValue: this.post }, 
            summary: { stringValue: this.description }, 
            published: { booleanValue: this.published }, 
            created: { timestampValue: new Date() }, 
            modified: { timestampValue: new Date() } 
        } 
    }
    ).then(res => { console.log("Post created") })
Run Code Online (Sandbox Code Playgroud)

这里有一个使用 Python 请求的示例:
使用 Firestore REST API 更新文档字段
(这是一个 PATCH 请求,但字段格式与 POST 请求中的相同)

import requests
import json

endpoint = "https://firestore.googleapis.com/v1/projects/[PROJECT_ID]/databases/(default)/documents/[COLLECTION]/[DOCUMENT_ID]?currentDocument.exists=true&updateMask.fieldPaths=[FIELD_1]"

body = {
    "fields" : {
        "[FIELD_1]" : {
            "stringValue" : "random new value"
        }
    }
}

data = json.dumps(body)

headers = {"Authorization": "Bearer [AUTH_TOKEN]"}
print(requests.patch(endpoint, data=data,  headers=headers).json())
Run Code Online (Sandbox Code Playgroud)

我正在使用 Google Apps 脚本 UrlFetchApp.fetch 发送我的请求。我可以毫无问题地使用 GET 请求。例如,要获取集合中的所有文档(在 Google Apps 脚本中):

function firestore_get_documents(){
  var options = {
    headers: { 'Authorization': 'Bearer ' +  ScriptApp.getOAuthToken() },
    method:'GET'
  }
  var response = UrlFetchApp.fetch('https://firestore.googleapis.com/v1/projects/<PROJECTIDHERE>/databases/(default)/documents/myCollection', options);
  var parsed = JSON.parse(response.getContentText());
  return parsed;
}
Run Code Online (Sandbox Code Playgroud)

这很好用。将“方法”更改为“POST”会按预期在 myCollection 中创建一个新文档。然后我尝试添加带有一些字段(或仅一个字段)的 POST 正文:

function firestore_create_new_document(){
  
  var options = {
    headers: { 'Authorization': 'Bearer ' +  ScriptApp.getOAuthToken() },
    method:'POST',
    payload: {fields: { title: { stringValue: 'newTitle' } } }, // If you comment out this line, it works as expected
    muteHttpExceptions:true
  }
  var response = UrlFetchApp.fetch('https://firestore.googleapis.com/v1/projects/<PROJECTIDHERE>/databases/(default)/documents/myCollection', options);
  var contentText = response.getContentText();
  var parsed = JSON.parse(response.getContentText());
  return parsed;
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

code: 400 message: "Request contains an invalid argument."
status: "INVALID_ARGUMENT"
details[0][@type]: "type.googleapis.com/google.rpc.BadRequest"
details[0][fieldViolations][0][field]: "{title={stringValue=newTitle}}"
details[0][fieldViolations][0][description]: "Error expanding 'fields' parameter. Cannot find matching fields for path '{title={stringValue=newTitle}}'."
Run Code Online (Sandbox Code Playgroud)

文档可在此处获取: https:
//firebase.google.com/docs/firestore/reference/rest/v1/projects.databases.documents/createDocument https://firebase.google.com/docs/firestore/reference/rest/ v1/projects.databases.documents#文档

  1. 问题可能是我的“字段”对象的格式 - 我已经尝试了文档和示例中的几种不同格式
  2. 问题可能是这些字段还不存在?我想我应该能够创建一个包含新字段的新文档
  3. 问题可能出在 UrlFetchApp.fetch 发送 JSON 正文的方式上。我尝试过使用payload = JSON.stringify(payload_object),但这也不起作用。

我认为 UrlFetchApp 所做的事情与 Axios 或 Python 请求略有不同 - 正文的发送方式不同,并且没有按预期进行解析。

Tan*_*ike 6

下面的修改怎么样?

从:

var options = {
  headers: { 'Authorization': 'Bearer ' +  ScriptApp.getOAuthToken() },
  method:'POST',
  payload: {fields: { title: { stringValue: 'newTitle' } } }, // If you comment out this line, it works as expected
  muteHttpExceptions:true
}
Run Code Online (Sandbox Code Playgroud)

到:

var options = {
  headers: { 'Authorization': 'Bearer ' +  ScriptApp.getOAuthToken() },
  method:'POST',
  payload: JSON.stringify({fields: { title: { stringValue: 'newTitle' } } }),
  contentType: "application/json",
  muteHttpExceptions:true
}
Run Code Online (Sandbox Code Playgroud)
  • 当我测试上述修改后的请求时,我可以确认它有效。但如果出现其他错误,请告诉我。

参考:

  • @Mateo Randwolf 感谢您一直以来的支持。 (2认同)