How to insert server timestamp in Firestore document using REST? - rest

I want to insert a document using a REST call to Firestore createDocument method. One of the fields is a timestamp field that should be set on the server. With Android SDK it's as simple as annotating a Date field with #ServerTimestamp and keeping it null — now how do I do it in REST?
{
"fields": {
"timezoneId": {
"stringValue": "Europe\/London"
},
"city": {
"stringValue": "London"
},
"timestamp": {
"timestampValue": "???"
}
}
}
I tried using null, 0, empty string, timestamp — everything fails with an error requiring the standard RFC3339 format (e.g. 2018-01-31T13:50:30.325631Z). Is there any placeholder value I can use, or any way to obtain that timestamp?

The Android SDK doesn't execute a createDocument request when creating the document. Instead it uses the write request to issue an update and a transform request at the same time. If you are wanting to only use createDocument, then the answer is no.
Your payload would look something like this:
{
"writes": [
{
"update": {
"name": "projects/{projectId}/databases/{databaseId}/documents/{document_path}",
"fields": {
"timezoneId": {
"stringValue": "Europe\/London"
},
"city": {
"stringValue": "London"
}
}
},
// ensure the document doesn't exist
"currentDocument": {
"exists": false
}
},
{
"transform": {
"document": "projects/{projectId}/databases/{databaseId}/documents/{document_path}",
"fieldTransforms": [
{
"fieldPath": "timestamp",
"setToServerValue": "REQUEST_TIME"
}
]
}
}
]
}
The only downside to adding documents this way is you would need to generate the Document ID yourself (the SDK's generate them). I hope this helps.

Related

How to update date field to a specific date format value in mongoDB compass?

My MongoDB compass document looks like this
{
"_id": "123456789",
"code": "x123",
"title": "cool",
"createdDate":2022-07-06T08:04:52.156+00:00
"expiryDate":2023-12-31T00:00:00.000+00:00
}
I tried to create a mongo DB script in my pipeline to update the "expirydate" field to a specific date value "9999-12-31T00:00:00.000Z" format. My update script looks like this as I am trying to update it via my pipeline. The createdDate field took the current date correctly.
{
"command": "updateOne",
"datasource_name": "Austrailia",
"collection_name": "Sydney",
"query": {
"code": "x123"
},
"options": {
"upsert": true,
},
"update": {
"$currentDate": {
"createdDate": {
"$type": "date"
}
},
"$set": {
"title": "hot",
"expiryDate": {
"$date": "9999-12-31T00:00:00.000"
}
}
}
}
The script is failing as it is throwing errors -
{MongoError: Unknown modifier: expiryDate. Expected a valid modifier}
The dollar ($) prefixed field \'$date\' in \'expiryDate.$date\' is not valid for storage.
What would be the correct query syntax to update the date field "expiryDate" to the value specified above in the same format here?

GA4 (Google Analytics) sessions based on UTM params

I am trying to fetch sessions from GA4 which are relevant to specific UTM params.
In GA3 we were able to use segments (sessions::condition::ga:source==X;ga:medium==Y) but I can not find a way to do this on GA4.
POST https://analyticsdata.googleapis.com/v1beta/#{property}:runReport`
Payload like this:
body = {
"metrics": [
{
"name": "sessions::condition::ga:source==X;ga:medium==Y"
}
],
"dimensions": [
{
"name": "date"
}
],
"dateRanges": [
{
"startDate": '2022-01-01',
"endDate": '2022-01-30',
"name": "current_year"
}
]
}
Returns: Field sessions::condition::ga:source==X;ga:medium==Y is not a valid metric.. Is there a way to do this via new API?
Should I use dimension filter to achieve that? I need to query on both source&medium but it is not clear how do I do this?
"dimensionFilter": {
"filter": {
"fieldName": "firstUserMedium",
"stringFilter": {
"value": "Y"
}
}
}
A dimension filter on sessionSource & sessionMedium returns sessions that have those specific utm_source & utm_medium values. See the dimensions & metrics page for a description of these and other dimensions & metrics.
The needed dimension filter is similar to the following. See Dimension Filters in Creating a Report for more info.
"dimensionFilter": {
"andGroup": {
"expressions": [
{
"filter": {
"fieldName": "sessionSource",
"stringFilter": {
"value": "X"
}
}
},
{
"filter": {
"fieldName": "sessionMedium",
"stringFilter": {
"value": "Y"
}
}
}
]
}
},
Segments are not yet available today in the GA4 Data API.
I think you should check the dimensions and metrcis list for GA4 they dont start with ga
POST https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport
{
"dateRanges": [{ "startDate": "2020-09-01", "endDate": "2020-09-15" }],
"dimensions": [{ "name": "country" }],
"metrics": [{ "name": "activeUsers" }]
}
Also at this time i don't think it supports segments.

Github GrapQL API returns only the last StatusContext for each context

I'm cross-posting the question from here.
I’m interested in knowing whether it’s possible to fetch all the statuses for all the contexts for a given reference using the GQL API.
The query that I’m currently doing is the following:
{
repository(owner: "owner", name: "name") {
pullRequests(headRefName: "head-ref", last: 1) {
nodes {
id
commits(first: 10) {
nodes {
commit {
oid
status {
contexts {
context
createdAt
id
description
state
}
}
}
}
}
}
}
}
}
This query returns a single status for each status context, and those are the last ones for each:
{
"data": {
"repository": {
"pullRequests": {
"nodes": [
{
"id": "some-id",
"commits": {
"nodes": [
{
"commit": {
"oid": "some-oid",
"status": {
"contexts": [
{
"context": "context-1",
"createdAt": "2021-07-06T21:28:26Z",
"id": "***",
"description": "Your tests passed!",
"state": "SUCCESS"
},
{
"context": "context-2",
"createdAt": "2021-07-06T21:25:26Z",
"id": "***",
"description": "Your tests passed!",
"state": "SUCCESS"
},
]
}
}
}
]
}
}
]
}
}
}
}
On the other hand, if I use the REST API with this query:
curl -i -u se7entyse7en:$(cat token) https://api.github.com/repos/owner/name/commits/some-oid/statuses
where some-oid is the corresponding retrieved with the GQL API, the output contains ALL the statuses. In particular, I can see all the statuses of context-1 and context-2 that happened before those that are returned by the GQL API.
It seems a limitation of the GQL schema given that StatusContext is a node instead of being a list of nodes. Basically, I expect StatusContext to be of type [Status!]! where Status represents a single status for the given context.
Am I missing something? Is this something expected to be changed in the future? Is the REST API the only option?
Thanks.
I opened a support ticket and this is the expected behavior indeed, there are no plans for changing it. The only solution is to use the REST API.
The link to the community forum is this one.

MongoDB Stitch GraphQL Custom Mutation Resolver returning null

GraphQL is a newer feature for MongoDB Stitch, and I know it is in beta, so thank you for your help in advance. I am excited about using GraphQL directly in Stitch so I am hoping that maybe I just overlooked something.
The documentation for the return Payload displays the use of bsonType, but when actually entering the JSON Schema for the payload type it asks for you to use "type" instead of "bsonType". It still works using "bsonType" to me which is odd as long as at least one of the properties uses "type".
Below is the function:
const mongodb = context.services.get("mongodb-atlas");
const collection = mongodb.db("<database>").collection("<collection>");
const query = { _id: BSON.ObjectId(input.id) }
const update = {
"$push": {
"notes": {
"createdBy": context.user.id,
"createdAt": new Date,
"text": input.text
}
}
};
const options = { returnNewDocument: true }
collection.findOneAndUpdate(query, update, options).then(updatedDocument => {
if(updatedDocument) {
console.log(`Successfully updated document: ${updatedDocument}.`)
} else {
console.log("No document matches the provided query.")
}
return {
_id: updatedDocument._id,
notes: updatedDocument.notes
}
})
.catch(err => console.error(`Failed to find and update document: ${err}`))
}
Here is the Input Type in the customer resolver:
"type": "object",
"title": "AddNoteToLeadInput",
"required": [
"id",
"text"
],
"properties": {
"id": {
"type": "string"
},
"text": {
"type": "string"
}
}
}
Below is the Payload Type:
{
"type": "object",
"title": "AddNoteToLeadPayload",
"properties": {
"_id": {
"type": "objectId"
},
"notes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"createdAt": {
"type": "string"
},
"createdBy": {
"type": "string"
},
"text": {
"type": "string"
}
}
}
}
}
}
When entering the wrong "type" the error states:
Expected valid values are:[array boolean integer number null object string]
When entering the wrong "bsonType" the error states:
Expected valid values are:[string object array objectId boolean bool null regex date timestamp int long decimal double number binData]
I've tried every combination I can think of including changing all "bsonType" to "type". I also tried changing the _id to a string when using "type" or objectId when "bsonType". No matter what combination I try when I use the mutation it does what it is supposed to and adds the note into the lead, but the return payload always displays null. I need it to return the _id and note so that it will update the InMemoryCache in Apollo on the front end.
I noticed that you might be missing a return before your call to collection.findOneAndUpdate()
I tried this function (similar to yours) and got GraphiQL to return values (with String for all the input and payload types)
exports = function(input){
const mongodb = context.services.get("mongodb-atlas");
const collection = mongodb.db("todo").collection("dreams");
const query = { _id: input.id }
const update = {
"$push": {
"notes": {
"createdBy": context.user.id,
"createdAt": "6/10/10/10",
"text": input.text
}
}
};
const options = { returnNewDocument: true }
return collection.findOneAndUpdate(query, update, options).then(updatedDocument => {
if(updatedDocument) {
console.log(`Successfully updated document: ${updatedDocument}.`)
} else {
console.log("No document matches the provided query.")
}
return {
_id: updatedDocument._id,
notes: updatedDocument.notes
}
})
.catch(err => console.error(`Failed to find and update document: ${err}`))
}
Hi Bernard – There is an unfortunate bug in the custom resolver form UI at the moment which doesn't allow you to only use bsonType in the input/payload types – we are working on addressing this. In actually you should be able to use either type/bsonType or a mix of the two as long as they agree with your data. I think that the payload type definition you want is likely:
{
"type": "object",
"title": "AddNoteToLeadPayload",
"properties": {
"_id": {
"bsonType": "objectId"
},
"notes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"createdAt": {
"bsonType": "date"
},
"createdBy": {
"type": "string"
},
"text": {
"type": "string"
}
}
}
}
}
}
If that doesn't work, it might be helpful to give us a sample of the data that you would like returned.

Elasticsearch - Incoming birthdays

I'm new with elasticsearch and I'm stuck with a query.
I want to get the next (now+3d) birthdays among my users. It looks simple but it's not because i have only the birthdate of my users.
How I can compare only months and day directly in the query when I only have a birthdate (Eg: 1984-04-15 or 2015-04-15 sometimes) ?
My field mapping:
"birthdate": {
"format": "dateOptionalTime",
"type": "date"
}
My actual query that doesn't work at all:
{
"query": {
"range": {
"birthdate": {
"format": "dd-MM",
"gte": "now",
"lte": "now+3d"
}
}
}
}
I saw this post Elasticsearch filtering by part of date but I'm not a big fan of the solution, and I would prefer instead of a wilcard a "now+3d"
Maybe I can do do something with a script ?
"Format" field was added in 1.5.0 version of elasticsearch. If your
version is below 1.5.0 format will not work. We had a same problem where we had to send an email on user's birthday and we were using version 1.4.4. So we created a separate dob field where we stored date in "dd-MM" format.
We changed the mapping of date field:
PUT /user
{
"mappings": {
"user": {
"properties": {
"dob": {
"type": "date",
"format": "dd-MM"
}
}
}
}
}
Then you can search:
GET /user/_search
{
"query": {
"filtered": {
"filter": {
"range": {
"date": {
"from": "01-01",
"to": "01-01",
"include_upper" : true
}
}
}
}
}
}