How to get string and Date object from TIMESTAMP in Firebase Functions? - node.js

I got timestamp in Firebase Functions with
admin.database.ServerValue.TIMESTAMP
However, when I pass it as a string, it becomes [object object]
I saved it in Firebase Realtime database and when I checked it from console I saw 1505298866520 which I think it is milliseconds since UNIX epoch.
Do you know how can I get string from it or how can I do time calculations with it? Or what type of object TIMESTAMP returns?

The firebase.database.ServerValue.TIMESTAMP or admin.database.ServerValue.TIMESTAMP hold the following object {.sv: "timestamp"}. This is a specific firebase-database object. That tells the server it should use the server's UNIX-time when an object is added to the database.
That is the reason you can not use it as a date object in javascript.
If you use admin.database.ServerValue.TIMESTAMP on the server via cloud functions it should represent the same as new Date().getTime()

Related

how to store date in the firebase with type 'timestamp' instead of 'map' from reactjs

From react application i'm getting date from a datepicker. i'm trying to save it on
firebase. It's saving properly in the database but not TYPE as 'timestamp', instead it's saving like 'map'. I'm sending data to firebase function created by us. from that function we are saving data to collection. any suggestion please.
const d = new Date("27-5-2021")
firebase.firestore.Timestamp.fromDate(d)
(OR)
firebase.firestore.Timestamp.fromMillis(d.getTime())
I think you will need to do something like this to save it as timestamp on firebase.
firebase.firestore.Timestamp.fromDate(date).toDate());

Dayjs to JS Date for Mongo

I need to parse a user supplied date in NodeJS. I found answers stating that using built in Date constructor/parse method is not reliable and I should use some library like Moment. I was confused that there are Moment and MomentJS libraries and found that there is a tiny library DaysJS having the same interface. Parsing works fine but I cannot find a way how to get the JS Date object that I need to pass to Mongo. Is there any aother way than extract the unix milliseconds and pass it to Date constructor?
When I pass daysjs instance to Mongo NodeJS driver, it fails:
const day = dayjs('2020-01-02', 'YYYY-MM-DD');
2020-06-07 10:42:33:093 [error]: Request failedThe dollar ($) prefixed field '$L' in 'info.date.$L' is not valid for storage.
This seems to work:
let publishDate = new Date(1000 * dayjs().unix());
Is it the correct way of daysjs with Mongo?
The error you got is because you tried to pass a DayJS object to mongodb, which it doesn't support.
You can pass a javascript Date object to mongodb. In order to convert a DayJS object to plain javascript Date object you can use .toDate() on the DayJS object
dayjs('2020-01-02', 'YYYY-MM-DD').toDate()

mongodb change stream resume from timestamp

In mongodb docs https://docs.mongodb.com/manual/changeStreams/
there is a quote:
The oplog must have enough history to locate the operation associated with the token or the timestamp, if the timestamp is in the past.
So it seems that it is possible to resume and get all the events that where added to oplog from a certain time.
There is a param, seems that it has to accomplish what I need
watch([],{startAtOperationTime: ...})
https://github.com/mongodb/specifications/blob/master/source/change-streams/change-streams.rst#startatoperationtime
Param is Timestamp, I don't get how to translate a particular date to correct timestamp.
startAtOperationTime is a new parameter for changestreams introduced in MongoDB 4.0 and newer driver versions. It allows you to ensure that you're not missing any writes just in case the stream was interrupted, and you don't have access to the resume token.
One caveat of using startAtOperationTime is that your app needs to be prepared to accept that it may see a write event twice when resuming the changestream, since you're resuming from an arbitrary point in time.
In node, this can be done by constructing a Timestamp object and passing it into watch():
async function run() {
const con = await MongoClient.connect(uri, {useNewUrlParser: true})
const ts = new Timestamp(1, 1560812065)
con.db('test').collection('test').watch([], {startAtOperationTime: ts})
.on('change', console.log)
}
The Timestamp object itself is created with the form of:
new Timestamp(ordinal, unix_epoch_in_seconds)
A detailed explanation can be found in BSON Timestamp.
In node, you can get the current epoch (in milliseconds) using e.g.:
(new Date).getTime()
bearing in mind that this needs to be converted to seconds for creating the Timestamp object needed for startAtOperationTime.

Wrong time format fetched

I am using Node for fetching data from MySQL. In database, i got record like : 2013-08-13 15:44:53 . But when Node fetches from Database , it assigns value like 2013-08-19T07:54:33.000Z.
I just need to get time format as in MySQL table. Btw ( My column format is DateTime in MySQL)
In Node :
connection.query(post, function(error, results, fields) {
userSocket.emit('history :', {
'dataMode': 'history',
msg: results,
});
});
When retrieving it from the database you most likely get a Date object which is exactly what you should work with (strings are only good to display dates, but working on a string representation of a date is nothing you want to do).
If you need a certain string representation, create it based on the data stored in the Date object - or even better, get some library that adds a proper strftime-like method to its prototype.
The best choice for such a library is moment.js which allows you to do this to get the string format you want:
moment('2013-08-19T07:54:33.000Z').format('YYYY-MM-DD hh:mm:ss')
// output (in my case on a system using UTC+2 as its local timezone):
// "2013-08-19 09:54:33"
However, when sending it through a socket (which requires a string representation) it's a good idea to use the default one since you can pass it to the new Date(..) constructor on the client side and get a proper Date object again.

Redis in Node.js: how to read Node Buffers

Must be missing something here, but I'm using Node_redis as Node.js client for Redis.
I'm testing Redis' Lrange command which per that doc returns a 'multi-bulk reply'.
From the node_redis docs this gets exposed as a 'JavaScript Array of node Buffers' in Node.
That's all pretty and all, but what are node buffers and more importantly, how do I read them in Node.js? I just want to transform them to an array of string (json) and from there to an array of object literals.
For ref, grabbing the first element of the array buffer[0] and printing it (trying all kinds of things:
console.log(multibulk[i]) -> [object Object]
console.log(multibulk[i].toString("binary")) -> [object Object]
etc.
thanks.
EDIT:
I verified the data is actually there in Redis (and is not stored as the String [object Object] as I began to expect). In Java when using JRedis' lrange command I get a List < String >. The first result of that list gives me the correct String as expected.
Just to close this:
as part of a kind of locking-mechanism I made sure a key was written to in Node. Stupidly I did this by inserting an object literal without stringifying it. This caused all later inserts in the list to fail.

Resources