Storing timestamp as Timestamp object in Firestore - firebase

Feels weird to ask a question that's been asked and answered before, but I did search before posting.
So I want to store a timestamp in Firestore but its either being stored as String or Map, but not as the Timestamp object.
new Date() is stored as a String
Timestamp.fromDate(new Date()) or simply Timestamp.now() is stored as a Map (seconds and nanoseconds)
I'm importing the method like so:
const { Timestamp } = require("firebase/firestore");
Probably worth mention, this is a cloud function that I'm testing locally via node filename.js
What am I doing wrong?

Looking at the documentation on the Timestamp class, a Timestamp stores the date in a second or nanosecond format. Just like you noted, this is why you are not seeing a true Date object stored in the firebase.
In my general experience, I usually use dates stored as string or timestamp representations in a database. The service getting those date values must convert the fetched data into a data type the service can use. Below are a couple of examples for fetching and storing date data:
// To store a timestamp using the Timestamp class:
const date = new Date();
const timestamp = firebase.firestore.Timestamp.fromDate(date); // 1676660310262
// store timestamp in database as Timestamp (results in Map)
// Once timestamp is extracted:
const fetchedTimestamp = 1676660310262
const fetchedDate = new Date(timestamp) // 'Fri, 17 Feb 2023 18:58:30 GMT'
// To store a string date, use a UTC string to maintain timezone:
const date = new Date(); // Fri Feb 17 2023 11:58:30 GMT-0700 (Mountain Standard Time)
const utcDate = date.toUTCString(); // 'Fri, 17 Feb 2023 18:58:30 GMT'
// store utcDate as a string
// Once date is extracted:
const fetchedUTCString = 'Fri, 17 Feb 2023 18:58:30 GMT';
const fetchedDate = new Date(fetchedUTCString) // Fri Feb 17 2023 11:58:30 GMT-0700 (Mountain Standard Time)
My recommendation would be to store dates in a Timestamp or string representation. Then in the service reading/writing that data, you should parse the data into a Date object on read and from a Date object to the string/timestamp on a write.

Firestore does not store JavaScript Date objects. See Supported data types. It appears they store in sub-millisecond resolution high resolution time like window.performance.now(). You should be able to pass a JavaScript Date object as a value though with firebase.firestore.Timestamp.fromDate(new Date());
Date and time: Chronological: When stored in Cloud Firestore, precise
only to microseconds; any additional precision is rounded down.

Related

Firebase User Last sign-in date returns today's date

I want to display the user's last sign-in date in Kotlin but it always returns today's day.
val user :FirebaseUser = FirebaseAuth().getInstance().currentUser!!
val timeStamp : Timestamp = Timestamp(user.metadata?.lastSignInTimestamp!!)
val date = Date(timeStamp.time)
Toast.make(this, date.toString() ,Toast.LENGTH_SHORT).show()
I want to display the user's last sign-in date in Kotlin
To display the user's last sign-in date in a Kotlin "style", please use the following lines of code:
FirebaseAuth.getInstance().currentUser?.metadata?.apply {
val lastSignInDate = Date(lastSignInTimestamp)
Toast.makeText(this, lastSignInDate.toString() ,Toast.LENGTH_SHORT).show()
}
The result will be a Toast message containing the String representation of the "lastSignInDate" object, which is an object of type Date. Let's suppose the user has signed in last time yesterday, the message might look similar to this:
Wed Mar 31 11:20:10 GMT+03:00 2021
If needed, you can also format the Date in a more readable way, as explained in the answer from the following post:
convert epoch time to date

Why is moment.js date is 50 years ahead?

Using moment to format a date retrieved from a firestore timestamp. However the date is off by at least a day, and at most, a few months. and the year is off by 50 no matter what.
Here is the firestore timestamp
EDIT: Here is whats logged from lastMsg.seconds:
1581372232
I retrieve the time in seconds in a FlatList's renderItem:
renderItem={({ item, index }) => {
return (
<Components.InboxItem
title={item.withName}
subtitle={item.lastMsg.seconds}
img={item.withImg}
/>
);
And finally inside the component I use moment like so:
const date = moment()
.utc()
.startOf('year')
.seconds(props.subtitle)
.format('MMMM DD YYYY');
While ive tried multiple format configurations, the one that gets it closest to accurate is with .startOf("year"). Even then, date is being displayed as "February 09, 2070". If .startOf() is changed to "month", "day", or "hour", the date gets changed to sometime in march. How can this be fixed to display the date as in firestore?
Looking at the https://firebase.google.com/docs/reference/js/firebase.firestore.Timestamp we can either get JS Date object or use the toMillis method to get milliseconds.
Now the simple moment.js api for converting timestamp to moment object is given here https://momentjs.com/docs/#/parsing/unix-timestamp-milliseconds/
moment(Number);
Now you can apply format on the moment object like below:
moment(Number).format(String);
Your issue with wrong date is may be due to the use of utc and seconds together and not passing timestamp to moment()
Use moment.unix():
const props = {
subtitle: 1581372232
};
const date = moment
.unix(props.subtitle)
.format('MMMM DD YYYY');
console.log(date);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
because item.lastMsg.seconds is
The number of seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z

Is there any option to read the total project execution time through groovy

Currently I like to calculate the total time taken for my soap ui automation project using groovy. I tried the following approach but it doesn't work:
Date startTime= new Date()
Date EndTime= new Date()
But i unable to compare the dates since it is taking the data types as string "Sat May 18 23:54:29 IST 2019" and I am unable to find the difference.
In groovy you can use the TimeCategory utility to subtract your dates, and get a TimeDuration object representing the difference. From this object you can inspect all sort of structured time/duration information.
Also, if you have a date in a String representation you can parse it into a Date using Date.parse passing as a parameter the format of the string and the string representation itself.
The following is a working demo of all this:
import groovy.time.*
def startTimeString = "Sat May 18 00:00:00 IST 2019"
def startTime = Date.parse("E MMM dd H:m:s z yyyy", startTimeString)
def endTime = new Date()
use (TimeCategory) {
TimeDuration duration = endTime - startTime
println "[${startTimeString}] was [${duration}] ago"
}
Complete code on GitHub
Hope this helps.

moment toISOstring without modifying date

I have a date like "Thu Sep 01 2016 00:00:00 GMT+0530 (IST)" which I need to send to server as ISO-8601 utc time. I tried like :
moment(mydate).toISOString()
moment.utc(mydate).toISOString()
moment(mydate).utcOffset("+00:00").toISOString()
but I am getting the result like
2016-08-31T18:30:00.000Z
which is 1day behind my intended time. So what can I do to make moment ignore my local timezone and see it as UTC?
Edit:
The expected output is
2016-09-01T18:30:00.000Z
And no, the initial input isn't a string rather a javascript "new Date()" value.
Reason this happens:
This happens because .toISOString() returns a timestamp in UTC, even if the moment in question is in local mode. This is done to provide consistency with the specification for native JavaScript Date .toISOString()
Solution:
Use the same function and pass true value to it. This will prevent UTC Conversion.
moment(date).toISOString(true)
const date = new Date("2020-12-17T03:24:00");
const dateISOStringUTC = moment(date).toISOString();
const dateISOString = moment(date).toISOString(true);
console.log("Converted to UTC:" + dateISOStringUTC)
console.log("Actual Date value:" + dateISOString)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
I take the same problem today and find the solution.
Here is the solution: moment(date,moment.ISO_8601)
var date = new Date();
console.log("Original Date");
console.log(date);
console.log("After Moment Format");
console.log(moment(date,moment.ISO_8601));
Test Execution:
Moment Documentation: MomentJs

error in date items, daylight Saving

Summer dates in an input control which are before 1981 are recalculated (I think with daylight saving time).
e.g.
e.g. I enter 27.8.1960 - after a save I got 26.8.1960, (after the next save 25.8.1960 and so on)
but 27.8.2010 - after a save it stayed the same: 27.8.2010
"Winter dates": 27.4.1960 - after a save it stayed the same: 27.4.1960
looks like an ugly bug. how can I supress this "calculation"?
(date format is Europeen, I live in Germany. 27.8.1960 is August 27, 1960)
thanks for any help, Uwe
<xp:inputText value="#{Auftrag.MF_GebDatum}" id="mF_GebDatum1" style="width:255px">
<xp:this.converter>
<xp:convertDateTime type="date"></xp:convertDateTime>
</xp:this.converter>
</xp:inputText>
The problem you are fighting with is that Domino stores a datetime value with the daylight saving information which does not exists for the dates you are entering. The information for the timezone to use comes from the current user locale and / or the server.
Your date is stored in a field with the timezone it was entered (+2h GMT)
26.08.1960 00:00:00 CEDT
Domino interprets the stored value as it is, without adjusting it
var ndt:NotesDateTime = session.createDateTime("26.08.1960 00:00:00 CEDT");
ndt.getGMTTime()
returns the correct datetime value, adjusted by 2 hours for GMT
25.08.60 22:00:00 GMT
While converted back to Java, it is interpreted "correctly" that there was never a daylight saving time in 1960, that's why it will be adjusted only by 1 hour:
var ndt:NotesDateTime = session.createDateTime("26.08.1960 00:00:00 CEDT");
ndt.toJavaDate().toLocaleString()
will result in "25.08.1960 23:00:00" if you are in the CEDT timezone.
Currently the only idea I have for an easy workaround is to kill the Timezone information in the DateTime field. To do this you can use this SSJS script:
<xp:this.querySaveDocument>
<![CDATA[#{javascript:
var doc:NotesDocument = document1.getDocument( true );
var items:java.util.Vector = doc.getItems();
var item:NotesItem;
var ndt:NotesDateTime;
var dt:java.util.Date;
for( var i=0; i<items.size(); i++){
item = items.get(i);
if( item.getType() === 1024 ){
ndt = item.getValueDateTimeArray().get(0);
ndt = session.createDateTime( ndt.getDateOnly());
item.setDateTimeValue( ndt );
ndt.recycle();
}
item.recycle();
}
}]]>
</xp:this.querySaveDocument>

Resources