Compare two +new Date strings - javascript

I'm trying to compare two different +new Date, but sometimes it gives different results.
So this is how I'm doing it:
The first user sends a request to Firebase(server) and sets value
time: +new Date like this
firebase.userRef.set({
time: +new Date
})
Then the second user sends a similar request to Firebase and sets value like above. Then second user finds user 1 in query and checks who sent the request first. Like so:
firebase.usersRef.child(user_uid).once("value",function(snapshot){
firebase.usersRef.child(current_uid).once("value",function(childSnapshot) {
if(snapshot.val().time > childSnapshot.val().time){
//current user requested first
} else {
//user found requested first
}
});
});
But, sometimes both users gets the wrong answer. So the users think that current user requested first.

A better way of setting the timestamp would be using ServerValues:
userRef.set({
time: firebase.database.ServerValue.TIMESTAMP
})
Using server values would be better since the value is fetched once it hits Firebase's server and would make your comparisons accurate.

Related

MongoDB Stored my date with the wrong time

I recently tried to assign a new date in MongoDB, but I have a problem with that, it stored the date I give but it's not correct
userSchema.methods.createPasswordResetToken = async function () {
this.passwordResetToken = crypto.randomBytes(20).toString('hex')
this.passwordResetExpires = moment().format(this.createAt)
await this.save()
console.log(moment().format(this.createAt)) // 2021-12-21T19:01:54+02:00
console.log(this.passwordResetExpires) // 2021-12-21T17:01:54.000Z
return { token: this.passwordResetToken, userId: this._id }
}
mongoDb remove 2 hours when storing it
and when I try to catch the type of two values
I got
console.log(moment().format(this.createAt)) // string
console.log(this.passwordResetExpires) // object
:
user Schema
...
passwordResetToken: String,
passwordResetExpires: Date
...
From the docs:
MongoDB stores times in UTC by default, and will convert any local time representations into this form. Applications that must operate or report on some unmodified local time value may store the time zone alongside the UTC timestamp, and compute the original local time in their application logic.
It seems your server just sits in GMT timezone ( utc +2, you could also see it from your date value // 2021-12-21T19:01:54+02:00 ). I would usually offer some hacky way to get around the issue but this is actually a best practice. Hence I recommend you do your date calculations in UTC and not in machine time.
note your other date is in UTC (2021-12-21T17:01:54.000Z), make sure your comparing apples to apples.

Get changes based on uploaded time from firebase

I have initialized a real time database using firebase, I am detecting live changes to the databse using
const ref = firebase.database().ref("test");
ref.on('value', function(dataSnapshot){
console.log(dataSnapshot.val())
});
But this returns me value in ascending order. Whereas I want it to return based on time. I tried using time in: 00:00 (IST) format but if a data is marked 11:59 (am) and another 01:02 (pm) this will return me the second message first.
What will be the best way to fix this?
example data is =>
in my databse =>
It is not clear what you mean by time in ascending order
None of your example data mention time. They are just usernames and text.
If you want to order times correctly, best to use ISO date format
This stores 1:02 pm as 13:02, which will sort after 11:59. Its sorting characteristics are ideal.
Use an international time standard to store your times
An international time standard, UTC, has great advantages over national times. It is not subject to change with location, political decisions, or season. You can always interconvert with the user's local time, at the time of entry or display.
Example
const dateString = (new Date()).toISOString();
console.log(dateString)
// Result:
// 2021-06-22T14:40:37.985Z
// If you want to use them as Firebase keys, they must not contain a ".", so you might clean it up like this:
const cleanDateString = (new Date()).toISOString().replace(".","-")
console.log(cleanDateString)
// Result:
// 2021-06-22T14:47:44-445Z
Even better, use a Firebase PushID
The above date-and-time system will work if you are using it to sort the remarks made by a single person, but will not be good as a message identifier if a single space is shared by all people, since 2 people will eventually make a message at the same millisecond, and will get the same message ID.
To deal with that it is better practice to use a Firebase Push ID.
An explanation is given here: In Firebase when using push() How do I get the unique ID and store in my database
Or from Firebase itself, here:
https://firebase.google.com/docs/database/admin/save-data

Sequelize returning dates with wrong time

The database and node are set as -02:00 timezone.
When I save a register, using sequelize, it saves the register with the right date and time in its date fields. For example, if I save a register with the field moment set as '2017-01-15T23:59:59-0200' and look in the database via MySQL Workbench I will see 2017-01-16 00:00:00 in the respective column.
I can even correctly find registers and filter by date and time.
But the value returned by a find operation in the field is '2017-01-16T01:59:59.000Z', meaning it was added two hours to the answer.
How could I retrive the correct date and time from MySQL using Sequelize?
Solved by overhiding String.toJSON:
Date.prototype.toJSON = function(){ return this.toLocaleString(); }

Best way to get rid of old messages/posts in a collection?

I know this website prefers answers over discussions but I am quite lost on this.
What would be a sufficient enough way to get rid of old messages that are stored in a collection? As they are messages, there will be a large amount of them.
What I have so far are either deleting messages using
if (Messages.find().count() > 100) {
Messages.remove({
_id: Messages.findOne({}, { sort: { createdAt: 1 } })._id
});
}
and I have also tried using expire.
Is there any other/more efficient way to do this?
Depending on how you define the age to expiry, there are two ways you can go about this.
The first one would be to use "TTL indexes" that automatically prune some collections based on time. For instance, you might have a logs table to log all the application events and you only want to keep the logs for the last hour. To implement this, add a date field to your logs document. This will indicate the age of the document. MongoDB will use this field to determine if your document is expired and needs to be removed:
db.log_events.insert({
"name": "another log entry"
"createdAt": new Date()
})
Now add a TTL index to your collection on this field. In the example below I used an expireAfterSeconds value of 3600 which will annihilate logs after every hour:
db.log_events.createIndex({ "createdAt": 1 }, { expireAfterSeconds: 3600 })
So for your case you would need to define an appropriate expiry time in seconds. For more details refer to the MongoDB documentation on expiration of data using TTL indexes.
The second approach involves manually removing the documents based on a date range query. For the example above given the same collection, to remove documents older that an hour you need to create a date that represents an hour ago relative to the current timestamp and use that date as the query in the remove method of the collection:
var now = new Date(),
hourAgo = new Date(now.getTime() - (60 * 60 * 1000));
db.log_events.remove({"createdAt": { "$lte": hourAgo }})
The above will delete log documents older than an hour.

Time sensitive data in Node.js

I'm building an application in Node.js and MongoDB, and the application has something of time-valid data, meaning if some piece of data was inserted into the database.
I'd like to remove it from the database (via code) after three days (or any amount of days/time spread).
Currently, my solution is to have some sort of member in my Schema that checks when it was actually posted and subsequently removes it when the current time is past 3 days from the insertion, but I'm having trouble in figuring out a good way to write it in code.
Are there any standard ways to accomplish something like this?
There are two basic ways to accomplish this with a TTL index. A TTL index will let you define a special type of index on a BSON Date field that will automatically delete documents based on age. First, you will need to have a BSON Date field in your documents. If you don't have one, this won't work. http://docs.mongodb.org/manual/reference/bson-types/#document-bson-type-date
Then you can either delete all documents after they reach a certain age, or set expiration dates for each document as you insert them.
For the first case, assuming you wanted to delete documents after 1 hour you would create this index:
db.mycollection.ensureIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )
assuming you had a createdAt field that was a date type. MongoDB will take care of deleting all documents in the collection once they reach 3600 seconds (or 1 hour) old.
For the second case, you will create an index with expireAfterSeconds set to 0 on a different field:
db.mycollection.ensureIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )
If you then insert a document with an expireAt field set to a date mongoDB will delete that document at that date and time:
db.mycollection.insert( {
"expireAt": new Date('June 6, 2014 13:52:00'),
"mydata": "data"
} )
You can read more detail about how to use TTL indexes here:
http://docs.mongodb.org/manual/tutorial/expire-data/

Categories

Resources