Cloud Firestore REST API - Add server timestamp - firebase

I'm using an Arduino with an ESP8266-01 module to upload a value to a Cloud Firestore database using the createDocument API with the following payload:
{
"fields": {
"distance": {
"integerValue": "555"
}
}
}
I do a POST-request to a route like this:
https://firestore.googleapis.com/v1beta1/projects/<MY_PROJECT>/databases/(default)/documents/<SOME_COLLECTION>?key=MY_VERY_SECRET_KEY
That all works, but I would like to add the server timestamp as well. I've found a few answers here on stackoverflow, but I have not been able to make any of them work.
How can I add the server timestamp to the created document? What I want is for the following to be created:
{
"fields": {
"distance": {
"integerValue": "555"
},
"timestamp" : {
"DATETIME": SERVER_TIMESTAMP
}
}
}
Any help appreciated.

What I ended up doing in the end was the following:
A POST request to a route like this:
https://firestore.googleapis.com/v1beta1/projects/<MY_PROJECT>/databases/(default)/documents:commit?&key=<MY_VERY_SECRET_KEY>
With the following payload:
{
"writes": [
{
"update": {
"name": "projects/<MY_PROJECT>/databases/(default)/documents/<COLLECTION_ID>/<DOCUMENT_ID>",
"fields": {
"distance": {
"integerValue": "555"
}
}
}
},
{
"transform": {
"document": "projects/<MY_PROJECT>/databases/(default)/documents/<COLLECTION_ID>/<DOCUMENT_ID>",
"fieldTransforms": [
{
"fieldPath": "servertime",
"setToServerValue": "REQUEST_TIME"
}
]
}
}
]
}
Where I generate a new DOCUMENT_ID (e.g. a GUID) instead of having cloud firestore generate one for me.

Related

Firestore structured query search by document id

I'm trying to query a firestore collection by document id but not using firestore CLI but rather a structured query (because I'm using Zapier to automate some workflows). Is there a way to search by documented as the field? So far I've tried the below code and variations where I replace name with "documentId()", "documentId" and nothing seems to work. When I use name I get the following error:
"error":
"code": 400,
"message": "key filter value must be a Key",
"status": "INVALID_ARGUMENT"
"where": {
"fieldFilter": {
"field": {
"fieldPath": "__name__"
},
"op": "EQUAL",
"value": {
"stringValue": "THE ID I WANT TO LOOK FOR"
}
}
}
If you want to get a document by id using __name__, change the value type to referenceValue and provide the full path to the document instead of just the id for the query.
"where": {
"fieldFilter": {
"field": {
"fieldPath": "__name__"
},
"op": "EQUAL",
"value": {
"referenceValue": "projects/project_id/databases/database_id/documents/your_collection/doc_id"
}
}
}
Assuming that you want to get a specific document using a document id. You may want to refer to the code below:
axios.get(`https://firestore.googleapis.com/v1/projects/<Project-ID>/databases/(default)/documents/<Collection-Name>/<Document-ID>`)
.then(res => {
console.log(res);
})
.catch(error => {
console.log(error);
});
The code above will get a specific document that you want. If you want to get a document ID with a specific value of its field, then this line here: "fieldPath": "__name__" should be a fieldName not a document id. "fieldPath": "<FieldName>". and also, make sure the method you're using is POST. See code sample below for reference:
axios.post(`https://firestore.googleapis.com/v1/projects/<Project-ID>/databases/(default)/documents:runQuery`,
{
"structuredQuery": {
"from": [{
"collectionId": "<Collection-Name>"
}],
"where": {
"fieldFilter": {
"field": {
"fieldPath": "<FieldName>"
},
"op": "EQUAL",
"value": {
stringValue: "<FieldValue>"
}
}
}
}
}).then(res => {
console.log(res)
})
.catch(error => {
console.log(error)
})
All the codes above are for reference only which I used axios for fetching the data from Firestore.
For more information, checkout this documentation.

How to retrieve firebase documents missing a field using runQuery and the IN operator?

This is my http POST requst body...
{
"structuredQuery": {
"select": {
"fields": [
{
"fieldPath": "name"
},
{
"fieldPath": "taxId"
},
{
"fieldPath": "mailingAddress"
}
]
},
"from": [
{
"collectionId": "orgs"
}
],
"where": {
"fieldFilter": {
"field": {
"fieldPath": "orgId"
},
"op": "IN",
"value": {
"arrayValue": {
"values": [
{
"stringValue": ""
},
{
"nullValue": null
}
]
}
}
}
}
}
It fails to return orgs where the orgId field is completely missing from the document. It correctly includes orgs where the orgId field is present and equal to empty string. This is accessing a Cloud Firestore db.
Due to the way Firestore indexes data, it is not possible to query for documents for which a certain field "is completely missing from the document": the field needs to exist in order for the Firestore index to take it into account. More details on the indexing mechanism in the following official video.
You may store an empty value in this field, as you mention in your question.

Support of Variables for Native Mongo Queries in Metabase

I want to add a variable to the given MongoDB query in Metabase. I know that it is supported after https://github.com/metabase/metabase/issues/3653 I have given my query below which is not working with the variable.
My query is:
[
{
"$project": {
"lastCommGenTS": "$lastCommGenTS",
"lastUpdated": "$lastUpdated",
"regNo": "$regNo",
"derivedStatus": "$derivedStatus"
}
},
{
"$match": {
"$expr": {
"$and": [
{
"$eq": [
"$regNo",{{regNo}}
]
}
]
}
}
},
{
"$project": {
"_id": "$_id",
"regNo": "$regNo",
"derivedStatus": "$derivedStatus",
"lastcommtimeIST": {
"$dateToString": {
"format": "%Y-%m-%d %H:%M:%S",
"date": {
"$toDate": "$lastCommGenTS"
},
"timezone": "+05:30"
}
},
"lastupdatedIST": {
"$dateToString": {
"format": "%Y-%m-%d %H:%M:%S",
"date": {
"$toDate": "$lastUpdated"
},
"timezone": "+05:30"
}
},
"lag_in_minutes": {
"$divide": [
{
"$subtract": [
"$lastUpdated",
"$lastCommGenTS"
]
},
60000
]
}
}
}
]
I am getting this error here:
Unexpected character ('{' (code 123)): was expecting double-quote to start field name at [Source: java.io.StringReader#6bab96b; line: 17, column: 26]
Please help me.
Many thanks in advance :)
In my case, I could not get variables to work for native Mongo Queries because I was using an older version of metabase which did not support the same. The support for variables and field filters in native Mongo queries was added after this version of release - https://github.com/metabase/metabase/releases/tag/v0.34.0

How should a "write" request be structured for Firestore REST API (v1beta1)?

Based on the Google Discovery document, and RPC reference, it appears that the :write resource should be available for Firestore database interactions, but performing such a request to my (POST https://firestore.googleapis.com/v1beta1/projects/[my project]/databases/(default)/documents:write) results in:
[
{
"error": {
"code": 400,
"message": "Invalid value (Object), ",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"description": "Invalid value (Object), "
}
]
}
]
}
}
]
Is this possible? A related SO answer alludes to this being available as a means of field transforms, the same reason I require this, but I cannot construct valid a JSON body to succeed in the request. Currently, variations on the following don't work as expected when trying a minimum successful response:
{
"writes": [
{
"update": {
"name": "projects/{projectId}/databases/[my project]/documents/exampleId",
"fields": {
"example": {
"integerValue": 100
},
"timestamp": {
"nullValue": null
}
},
"transform": {
"document": "projects/[my project]]/databases/(default)/documents/examples/exampleId",
"fieldTransforms": [
{
"fieldPath": "timestamp",
"setToServerValue": "REQUEST_TIME"
}
]
}
}
}
]
}
First of all, note that you should use the v1 version of the REST API, not the betas.
To create a document, you would use the createDocument method, while to update a document you would use the patch one.
For the document creation you should therefore make a POST HTTP Request to the following URL
https://firestore.googleapis.com/v1/projects/<your-project-id>/databases/(default)/documents/<the-desired-collection>
with the following Request body:
{
fields: {
example: {
integerValue: 100
}
}
}
You need to use documents:commit instead of documents:write
also the name field should be in this format:
"name": "projects/projectID/databases/(default)/documents/collectionName/DocumentId"
See this post.

Request probleme with Google Cloud Datastore and Filter

I'm currently doing some tests on google datastore, but I'm having a problem with my queries.
If I believe in the documentation https://cloud.google.com/datastore/docs/concepts/queries we can realize a filter on several columns with the instruction EQUALS.
But when testing, I get an error from the API.
While searching on Datastore's github, I found this reference: https://github.com/GoogleCloudPlatform/google-cloud-dotnet/issues/304 which corresponds to my problem, except that for my case the query to the look good.
Here is the request sent:
{
{
"kind": [{
"name": "talk.message"
}],
"filter": {
"compositeFilter": {
"op": "AND",
"filters": [{
"propertyFilter": {
"property": {
"name": "Conversation"
},
"op": "EQUAL",
"value": {
"stringValue": "2f16c14f6939464ea687d316438ad4cb"
}
}
},
{
"propertyFilter": {
"property": {
"name": "CreatedOn"
},
"op": "LESS_THAN_OR_EQUAL",
"value": {
"timestampValue": "2019-03-15T10:43:31.474166300Z"
}
}
},
{
"propertyFilter": {
"property": {
"name": "CreatedOn"
},
"op": "GREATER_THAN_OR_EQUAL",
"value": {
"timestampValue": "2019-03-14T10:43:31.474175100Z"
}
}
}
]
}
}
}
}
And here is the answer from the API:
{Grpc.Core.RpcException: Status(
StatusCode=FailedPrecondition,
Detail="no matching index found. recommended index is:
- kind: talk.message
properties:
- name: Conversation
- name: CreatedOn"
)
According to the documentation, this should be good... but it's not !
What am I missing ?
Your query includes both an EQUALS (on Conversation) and a non-EQUALS filter (on CreatedOn), therefore you need a composite index to fulfil the query. So your query is valid, but it needs a composite index to be able to run the query.

Resources