【问题标题】:Using the Firestore REST API to Update a Document Field使用 Firestore REST API 更新文档字段
【发布时间】:2020-03-23 08:42:47
【问题描述】:

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

{'error': {'code': 400, 'message': 'Request contains an invalid argument.', 'status': 'INVALID_ARGUMENT', 'details': [{'@type': 'type. googleapis.com/google.rpc.BadRequest', 'fieldViolations': [{'field': 'oil', 'description': "错​​误扩展'fields'参数。找不到路径'oil'的匹配字段。"}] }]}}

即使我知道文档中存在“石油”字段,我也会收到此错误。我是用 Python 写的。

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

{
    "fields": {
        field: {
            "integerValue": value
        }
    }
}

我的请求(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()

【问题讨论】:

    标签: python google-cloud-firestore


    【解决方案1】:

    根据官方文档(123)、GitHubnice article,对于您提供的示例,您应该使用以下内容:

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

    您的请求正文应为:

    {
        "fields": {
            "field": {
                "integerValue": Value
            }
        }
    }
    

    另外请记住,如果您想更新多个字段和值,您应该分别指定每一个。 示例:

    https://firestore.googleapis.com/v1beta1/projects/{projectId}/databases/{databaseId}/documents/{document_path}?updateMask.fieldPaths=[Field1]&updateMask.fieldPaths=[Field2]
    

    请求正文是:

    {
      "fields": {
        "field": {
          "integerValue": Value
        },
        "Field2": {
          "stringValue": "Value2"
        }
      }
    }
    

    编辑:

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

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

    from google.cloud import firestore
    
    db = firestore.Client()
    
    #Creating a sample new Document “aturing” under collection “users”
    doc_ref = db.collection(u'users').document(u'aturing')
    doc_ref.set({
        u'first': u'Alan',
        u'middle': u'Mathison',
        u'last': u'Turing',
        u'born': 1912
    })
    
    
    #updating 3 out of 4 fields (so the last should remain unaffected)
    
    doc_ref = db.collection(u'users').document(u'aturing')
    doc_ref.update({
        u'first': u'Alan',
        u'middle': u'Mathison',
        u'born': 2000
    })
    
    #printing the content of all docs under users
    users_ref = db.collection(u'users')
    docs = users_ref.stream()
    
    for doc in docs:
        print(u'{} => {}'.format(doc.id, doc.to_dict()))
    

    编辑:2019 年 10 月 12 日

    使用 REST API 进行修补

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

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

    一个工作示例如下:

    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())
    

    【讨论】:

    • 这不是我遇到的问题,因为某种原因它告诉我一个 字段不存在,即使我知道它存在。
    • 我已经编辑了我的答案,提供了一种我测试过的新方法。 (请注意,我在标签中使用了 python)
    • 我需要使用 REST API。我无法使用客户端。这是因为我需要能够从一个不允许我安装外部包但允许我发送 HTTP 请求的平台访问我的数据库。
    • 您能提供给我们您拥有的数据模型吗?以及您要更新哪些字段?除了任何其他有用的信息。还要检查此 [1] 并确保您没有遗漏该过程中的任何内容。确保您也不要忘记指定集合/集合组。 [1]:cloud.google.com/firestore/docs/reference/rest
    • 您在我的帖子中拥有您需要的所有信息。你不应该需要其他任何东西,我也没有其他东西可以给予。无论如何,我会再次解释一下:我不知道这是 Firestore 的问题还是我的问题,但是当我尝试输入我的文档字段的名称(“油”)时,即使我 100% 确定它存在,它给了我帖子中显示的错误。我正在使用 REST API 发送 PATCH 请求,以使用端点更新文档字段来更新文档。我不能将客户端 SDK 用作我所使用的平台,仅支持 HTTP 请求。
    【解决方案2】:

    我发现官方文档没有多大用处,因为没有提到示例。这是您的 Firestore 数据库的 API 端点

    补丁https://firestore.googleapis.com/v1beta1/projects/{YOUR_PROJECT_ID}/databases/(default)/documents/{COLLECTION_NAME}/{DOCUMENT_NAME}

    以下代码是您的 API 请求的正文

     {
      "fields": {
        "first_name": {
          "stringValue":"Kurt"
        },
        "name": {
          "stringValue":"Cobain"
        },
        "band": {
          "stringValue":"Nirvana"
        }
      }
    }
    

    成功更新数据库后应该得到的响应应该是这样的

    {
        "name": "projects/{YOUR_PROJECT_ID}/databases/(default)/documents/{COLLECTION_ID/{DOC_ID}",
        {
      "fields": {
        "first_name": {
          "stringValue":"Kurt"
        },
        "name": {
          "stringValue":"Cobain"
        },
        "band": {
          "stringValue":"Nirvana"
        }
      }
       "createTime": "{CREATE_TIME}",
        "updateTime": "{UPDATE_TIME}"
    
    

    请注意,执行上述操作将导致创建一个新文档,这意味着之前存在但未在“字段”正文中提及的任何字段都将被删除。为了保留字段,您必须添加

    ?updateMask.fieldPaths={FIELD_NAME}  --> to the end of your API call (for each individual field that you want to preserve).
    
    For example:
    
    PATCH https://firestore.googleapis.com/v1beta1/projects/{YOUR_PROJECT_ID}/databases/(default)/documents/{COLLECTION_NAME}/{DOCUMENT_NAME}?updateMask.fieldPaths=name&updateMask.fieldPaths=band&updateMask.fieldPaths=age. --> and so on
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-26
      • 2021-09-15
      • 1970-01-01
      • 2018-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多