Firestore REST API use with appGyver Composer Pro

1.6k Views Asked by At

I´m trying the new appGyver Composer Pro with Google Firebase (without success). AppGyver uses REST API to get data on the database, but I can´t get it to work. The database is very simple and has only two documents, so I´m using SoapUI and Postman to try differen uri´s to identify how to set Composer Pro:

So, using GET https://firestore.googleapis.com/v1/projects/{project}/databases/(default)/documents/{collection}/

This is the result of the request:

{"documents": [
      {
      "name": "projects/{project}/databases/(default)/documents/{collection}/{id}",
      "fields":       {
         "Nombre": {"stringValue": "Cerros"},
         "Resolucion": {"mapValue": {"fields":          {
            "Numero": {"stringValue": "22"},
            "Entidad": {"stringValue": "Curaduria"},
            "FechaResolucion": {"timestampValue": "2020-04-09T05:00:00Z"}
         }}}
      },
      "createTime": "2020-04-10T13:11:35.364097Z",
      "updateTime": "2020-04-10T13:11:35.364097Z"
   },
      {
      "name": "projects/{project}/databases/(default)/documents/{collection}/{id}",
      "fields":       {
         "Nombre": {"stringValue": "Urbanizacion Guayacanes"},
         "Resolucion": {"mapValue": {"fields":          {
            "Numero": {"stringValue": "14"},
            "Entidad": {"stringValue": "Municipio de Chinchina"},
            "FechaResolucion": {"timestampValue": "2013-11-13T05:00:00Z"}
         }}}
      },
      "createTime": "2020-04-09T14:29:09.633853Z",
      "updateTime": "2020-04-09T14:29:09.633853Z"
   }
]}

But if I use https://firestore.googleapis.com/v1/projects/{project}/databases/(default)/documents/{collection}/?Nombre=Cerros

I get

{"error": {
   "code": 400,
   "message": "Invalid JSON payload received. Unknown name \"Nombre\": Cannot bind query parameter. Field 'Nombre' could not be found in request message.",
   "status": "INVALID_ARGUMENT",
   "details": [   {
      "@type": "type.googleapis.com/google.rpc.BadRequest",
      "fieldViolations": [{"description": "Invalid JSON payload received. Unknown name \"Nombre\": Cannot bind query parameter. Field 'Nombre' could not be found in request message."}]
   }]
}}

I get almost the same message (only the name of the field changes) using any of the following instead of ?Nombre=Cerros:

  • ?"Nombre"="Cerros"
  • ?"documents.Nombre"="Cerros"
  • ?"documents.fields.Nombre"="Cerros"

Or using before ? any of the following:

  • :runQuery
  • search

What am I doing wrong? I would really appreciate any help

Eduardo

P.D. I tried on the REST API Explorer:

curl --request POST \
  'https://firestore.googleapis.com/v1/projects/permisos-23395/databases/(default)/documents/Inmueble/:runQuery' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{"structuredQuery":{"select":{"fields":[{"fieldPath":"Nombre"},{"fieldPath":"matInm"}]},"from":[{"collectionId":"Inmueble","allDescendants":false}],"where":{"fieldFilter":{"field":{"fieldPath":"Nombre"},"op":"EQUAL","value":{"stringValue":"Cerros"}}}}}' \
  --compressed

And got

{
  "error": {
    "code": 400,
    "message": "Invalid JSON payload received. Unknown name \"structuredQuery\" at 'document': Cannot find field.",
    "status": "INVALID_ARGUMENT",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.BadRequest",
        "fieldViolations": [
          {
            "field": "document",
            "description": "Invalid JSON payload received. Unknown name \"structuredQuery\" at 'document': Cannot find field."
          }
        ]
      }
    ]
  }
}
2

There are 2 best solutions below

0
On BEST ANSWER

Thanks Happy-Monad. I followed your lead and got it to work:

There needs to be an Index by {collection} {query field}, created in addition to the default ones.

Never got it to work with the API EXPLORER, because it needs the collection id on the parent path, but :runQuery does not work if its in there.

:runQuery is requested with a POST call (not GET): https://firebase.google.com/docs/firestore/reference/rest#rest-resource:-v1.projects.databases.documents

The curl call that worked is as follows:

curl --request POST \
  'https://firestore.googleapis.com/v1/projects/{database}/databases/(default)/documents:runQuery' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{"structuredQuery":{"select":{"fields":[{"fieldPath":"Nombre"},{"fieldPath":"nicInm"}]},"from":[{"collectionId":"{collection}","allDescendants":true}],"where":{"fieldFilter":{"field":{"fieldPath":"Nombre"},"op":"EQUAL","value":{"stringValue":"Cerros"}}}}}' \
  --compressed

It returns (JSON):

array [1]
0 {2}
document {4}
name : projects/{database}/databases/(default)/documents/{collection}/{document id}
fields {2}
nicInm {1}
stringValue : 17-00-01-0001
nameInm {1}
stringValue : Cerros
createTime : 2020-04-14T15:22:53.782673Z
updateTime : 2020-04-14T15:22:53.782673Z
readTime : 2020-04-14T16:04:55.392601Z
2
On

The endpoint you're using is meant for listing the documents of a collection, not for retrieving it's contents.

When you call https://firestore.googleapis.com/v1/projects/{project}/databases/(default)/documents/{collection}/ you're calling the method projects.databases.documents.list which as you saw returns a list of the documents belonging to that collection.

Afterwards you're trying to retrieve the document matching the restriction "Nombre=Cierros" using query parameters while pointing to the list endpoint, which is not a valid request.

If you actually want to retrieve the documents you would need to use one of the following:

  • To request for a single document you need to use the method projects.databases.documents.get with a get request to the endpoint https://firestore.googleapis.com/v1/projects/{project_id}/databases/{database_id}/documents/{document_path}. Where document path would be of the form {collection}/{documentId}.
  • To query documents based on a filter you need to use the method projects.databases.documents.runQuery supplying a request body in the format described in the documentation.