使用 Firestore REST API 更新文档字段

1 python google-cloud-firestore

我已经搜索了很长时间,但我不知道如何使用 Firestore REST API 更新文档中的字段。我查看了其他问题,但它们没有帮助我,因为我遇到了不同的错误:

{'error': {'code': 400, 'message': '请求包含无效参数。', 'status': 'INVALID_ARGUMENT', 'details': [{'@type': 'type.googleapis.com /google.rpc.BadRequest', 'fieldViolations': [{'field': 'oil', 'description': "扩展 'fields' 参数时出错。找不到路径 'oil' 的匹配字段。"}]}]} }

尽管我知道文档中存在“石油”字段,但我还是收到此错误。我正在用 Python 写这个。

我的请求正文(字段是文档中的字段,值是将该字段设置为的值,两个字符串都是从用户输入接收的):

{
    "fields": {
        field: {
            "integerValue": value
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的请求(authorizationToken 来自不同的请求,dir 也是来自用户输入的控制目录的字符串):

requests.patch("https://firestore.googleapis.com/v1beta1/projects/aethia-resource-management/databases/(default)/documents/" + dir + "?updateMask.fieldPaths=" + field, data = body, headers = {"Authorization": "Bearer " + authorizationToken}).json()
Run Code Online (Sandbox Code Playgroud)

Wae*_*mas 5

根据官方文档(1、23 GitHub和一篇不错的文章,对于提供的示例,您应该使用以下内容:

\n\n

requests.patch(" https://firestore.googleapis.com/v1beta1/projects {projectId}/databases/{databaseId}/documents/{document_path}?updateMask.fieldPaths=field")

\n\n

您的请求正文应该是:

\n\n
{\n    "fields": {\n        "field": {\n            "integerValue": Value\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

另请记住,如果您想要更新多个字段和值,则应分别指定每个字段和值。\n示例:

\n\n
https://firestore.googleapis.com/v1beta1/projects/{projectId}/databases/{databaseId}/documents/{document_path}?updateMask.fieldPaths=[Field1]&updateMask.fieldPaths=[Field2]\n
Run Code Online (Sandbox Code Playgroud)\n\n

请求正文将是:

\n\n
{\n  "fields": {\n    "field": {\n      "integerValue": Value\n    },\n    "Field2": {\n      "stringValue": "Value2"\n    }\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编辑:

\n\n

这是我测试过的一种方法,它允许您更新文档的某些字段而不影响其余字段。

\n\n

此示例代码在集合 users 下创建一个包含 4 个字段的文档,然后尝试更新 4 个字段中的 3 个(这使得未提及的字段不受影响)

\n\n
from google.cloud import firestore\n\ndb = firestore.Client()\n\n#Creating a sample new Document \xe2\x80\x9caturing\xe2\x80\x9d under collection \xe2\x80\x9cusers\xe2\x80\x9d\ndoc_ref = db.collection(u\'users\').document(u\'aturing\')\ndoc_ref.set({\n    u\'first\': u\'Alan\',\n    u\'middle\': u\'Mathison\',\n    u\'last\': u\'Turing\',\n    u\'born\': 1912\n})\n\n\n#updating 3 out of 4 fields (so the last should remain unaffected)\n\ndoc_ref = db.collection(u\'users\').document(u\'aturing\')\ndoc_ref.update({\n    u\'first\': u\'Alan\',\n    u\'middle\': u\'Mathison\',\n    u\'born\': 2000\n})\n\n#printing the content of all docs under users\nusers_ref = db.collection(u\'users\')\ndocs = users_ref.stream()\n\nfor doc in docs:\n    print(u\'{} => {}\'.format(doc.id, doc.to_dict()))\n
Run Code Online (Sandbox Code Playgroud)\n\n

编辑:2019 年 10 月 12 日

\n\n

使用 REST API 进行修补

\n\n

我已经重现了您的问题,看来您没有正确地将请求正文转换为 json 格式。

\n\n

您需要使用json.dumps()将请求正文转换为有效的 json 格式。

\n\n

一个工作示例如下:

\n\n
import requests\nimport json\n\nendpoint = "https://firestore.googleapis.com/v1/projects/[PROJECT_ID]/databases/(default)/documents/[COLLECTION]/[DOCUMENT_ID]?currentDocument.exists=true&updateMask.fieldPaths=[FIELD_1]"\n\nbody = {\n    "fields" : {\n        "[FIELD_1]" : {\n            "stringValue" : "random new value"\n        }\n    }\n}\n\ndata = json.dumps(body)\n\nheaders = {"Authorization": "Bearer [AUTH_TOKEN]"}\nprint(requests.patch(endpoint, data=data,  headers=headers).json())\n
Run Code Online (Sandbox Code Playgroud)\n