Querying and comparing Firestore serverTimestamp - javascript

I'm fairly new to Firebase/Firestore and I'm querying some stored data for analysis via Cloud Function.
I can't figure out how to compare timestamp within a query.
Each document has a field set using admin.firestore.FieldValue.serverTimestamp().
My initial query against the collection works, using ref.where("timestamp", ">=", startTime) where startTime is a Date object.
However, when I iterate through a snapshot - using doc.data().timestamp. Logging this value I get something like 2018-05-10T22:51:37.236Z which is not comparable.
Can I transform the doc.data().timestamp in a way that I can compare against a unix timestamp or Date object?

Related

Firestore query after adding composite index still return nothing

I have already created react app and I'm using firebase firestore.
So at the start of using I didn't have any problems, until I found that I need to create a query like that:
db.collection('schedule')
.where('working_day', '>=', new Date())
.where('master', '==', masterId)
.orderBy('working_day', 'desc')
.get();
I have a collection called schedule and this schedule collection has list of documents. Each document has structure:
working_day: timestamp;
start_hour: number;
end_hour: number;
master: string;
When I called this query - I didn't see any result (request is gone, but no results at all). Someone suggest me to add composite indexing and It must solve this problem
I did it using firestore indexing tab and now I have this indexing:
Collection ID Fields indexed Query scope Status
schedule working_day Descending master Descending Collection Enabled
It has been successfully applied - but still my request without any result.
Also I know that firestore could notice me that I need to apply this indexing and provide me the link - but I don't see this link. Where I should find this? Or maybe I do something wrong?
Break my head for the 2 days and didn't find why I have this issue
It looks like working.day is stored in your firestore database as a timestamp but your query condition is comparing against a javascript date object which could be causing an issue. Try replacing the date object with a firebase timestamp like the code below.
db.collection('schedule')
.where('working_day', '>=', new firebase.firestore.Timestamp.now())
.where('master', '==', masterId)
.orderBy('working_day', 'desc')
.get();

How to pass a JS date object to cloud function for storing it on Firestore

When I write a Date object to my Firestore, all works correctly and I can see a date in the DB stored with the type "timestamp". If I try to pass a Date object to a cloud function, I don't know why but it is an empty object when I store it from the cloud function to the firestore DB.
firebase.functions().httpsCallable("myFunction")({date: new Date()}) <---- // this doesn't work
So, I have decided to convert the Date object to a firestore timestamp in the client side before sending it to the cloud function. As follows:
date = firebase.firestore.Timestamp.fromDate(date);
firebase.functions().httpsCallable("myFunction")({date})
Then, if I get it in the cloud function and store it on my firestore, I see an object with the fields "seconds" and "nanoseconds", but not a timestamp (I mean it is not stored with the type Timestamp)... So when I get this date I cannot apply the method .toDate()
Is there any good way to store the date in this situation as a timestamp and not as an object?
The input and output of callable functions deal entirely with JSON, so they are limited to expressing only those types that are allowed in JSON: string, number, boolean, null, object, array. Date and Timestamp are not among those types. What the Firebase SDK will do is try to serialize custom objects as JSON, which is not working the way you want - the seconds and nanos fields of the Timestamp are being split up during serialization.
If you have a Date to send from the client, you should just send it as a number. Instead of passing a Date object, pass the single number inside it (milliseconds since unix epoch):
const number = date.getTime()
On the receiving side, in Cloud Functions, take the number and convert it back to a Date:
const date = new Date(number)
Then you can write the Date object to a Firestore document field.

Difference between timestamps value while creating and querying the Sequelize model

I'm having issues with the timestamps on the Sequelize models. When creating a new record via the model, the createdAt timestamp contains milliseconds, but when I query the database using findOne(), it doesn't contain milliseconds. The createdAt column in the database is of type timestamp.
Value while creating model: 2018-12-04T07:18:14.075Z
Value while retrieving model via query: 2018-12-04T07:18:14.000Z
Anyone know what to do? Why is this even inconsistent?
I'm using Sequelize 4.41.2.

Firebase Firestory query where stored timestamp is in the past

I need to delete all Documents which have a timestamp (stored in a field) prior to today.
The timestamp is created in the Firestore GUI. The following query doesnt return any docs.
collectionRef
.where('timestampFieldName', '<', Date.now())
.get()
What exactly is a timestamp, created in the GUI and how to compare it with any date?
Whenever passing a date to Firestore, you should pass in an actual Date object. Date.now() returns a timestamp, which is just a number and not a Date object itself. To get the actual Date for the same value, use new Date(). So:
collectionRef
.where('timestampFieldName', '<', new Date())
.get()

Creating and comparing dates inside CosmosDB stored procedures

There is limited guidance for CosmosDB stored procedures and their handling of new Date() and the comparison of dates.
The following code is a CosmosDB stored procedure to 'freeze' the writing of documents after a given time. The property currentDoc.FreezeDate is in ISO-8601 format, e.g. '2017-11-15T13:34:04Z'.
Note: this is an example of the situation I'm trying to understand. It is not production code.
function tryUpdate(newDoc) {
__.queryDocuments(
__.getSelfLink(),
{ /* query to fetch the document */ },
(error, results) => {
var currentDoc = results[0]; // doc from the database
// fail if the document is still locked
if (new Date(currentDoc.FreezeDate) < new Date()) {
getContext().getResponse().setBody({ success: false });
return;
}
// else update the document
/* snip */
}
);
}
My question is: within CosmosDB stored procedures, is new Date() affected by timezones, especially given that the database may be in a different region than the invoking code? Is the date comparison code here valid in all situations?
As far as I can see, CosmosDB is storing DateTime values without the corresponding Timezone, aka. not as DateTimeOffset. This means it should not matter where the code is executed, since it is always normalized to something like this:
"2014-09-15T23:14:25.7251173Z"
Javascript Date object are timestamps - they merely contain a number of milliseconds since the epoch. There is no timezone info in a Date object. Which calendar date (day, minutes, seconds) this timestamp represents is a matter of the interpretation (one of to...String methods).
(taken from Parse date without timezone javascript)
In other words, no matter where you are in the world, new Date() will always have the same value internally.
If you want to remove uncertainty in exchange for readability, I would recommend only storing the seconds or milliseconds since the epoch (Unix Time). This is also what is used internally by date (new Date().value - milliseconds). Incidentally, the internal cosmos document field _ts is also a timestamp in epoch format.
Be aware that the value of new Date() might by off the 'correct global time` by a couple of minutes - I don't know if Azure/Cosmos guarantees a certain deviation window.

Categories

Resources