Im trying to create a new document in firestore using a cloud function. However i am unable to save the date as a timestamp rather, it's saved as a string currently.
How it is right now
What i need to achieve
Snippet of my cloud function
await admin.firestore()
.doc('/buyerProfile/'+response.buyerId)
.collection('notifications')
.add({
'type':'New response',
'responseId':response.responseId,
'requestId':response.requestId,
'date': Date(Date.now()),
'compressedImgUrl':response.compressedImgUrl,
'description':response.description,
'requestPaidFor':request.data().isPaidFor
}).then(()=>console.log('Notification created'));
You can use to get timestamp new Date().getTime();
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now#return_value
just do it like this:
let today = new Date();
let timestamDate = Date.parse(today) / 1000;
and your date will be converted to timestamp
You don't have new keyword before Date constructor which will indeed return a string. If you want a Date object try this:
date: new Date() // Date object of current time
If you want to store the timestamp as number then pass Date.now()
You can check the same in a browser console:
You can also use serverTimestamp() method instead:
date: admin.firestore.FieldValue.serverTimestamp()
This worked for my case, i had to import Timestamp from firebase admin
const { timeStamp, time } = require("console");
...
'date': timeStamp.now(),
Firestore stores date/time values in its own Timestamp format.
There are two options:
If you want to capture the client-side time, use Timestamp.now(), so:
'date': Firestore.Timestamp.now(),
If you want to capture the server-side time, use:
'date': admin.firestore.FieldValue.serverTimestamp(),
import { serverTimestamp } from 'firebase/firestore';
and replace: <'date': Date(Date.now())>
with <'date': serverTimestamp()>
this should solve your problem
Related
I am trying to get all the documents with a dateStart timestamp field that is less than 24 hours in the future using a collectionGroup query. However, it would not be ideal to get all documents and test it for each document, as the documents can accumulate over time.
I have tried to do the following, but it gives an error:
const currentDate = moment();
const snap = db.collectionGroup('appointments').where(moment.duration(currentDate.diff(moment(new Date('dateStart')))).asHours() < 25).get()
.then(function(querySnapshot){
querySnapshot.forEach(function(doc){
console.log(doc.id);
});
});
The error I am getting is the following:
Error: Value for argument "fieldPath" is not a valid field path. Paths can only be specified as strings or via a FieldPath object.
I am not sure if it is even possible to add logic like this in the where clause of the query, or if I am just doing this the wrong way. I am currently using the moment library, but this isn't mandatory for the solution. I do think it is the easiest way to get the difference between date objects.
Does anyone have an idea to get this done without looping through all the documents in the collection?
You are doing something very wired.
The where function should be:
.where('dateStart', '<', next24HoursDate)
So try something like this:
const next24HoursDate = moment(new Date()).add(24, 'hours');
const snap = db.collectionGroup('appointments')
.where('dateStart', '<', next24HoursDate)
.get()
.then( function(querySnapshot) {
querySnapshot.forEach( function(doc) {
console.log(doc.id);
});
});
I have a use case where I have to retrieve a users record from the database via his date of birth.
The thing is that we have stored the date of birth of the user as datetime object which makes it very difficult to retrieve the users data, as we can not provide the exact date with timestamp.
I tried looking for a functions support in typeorm using which I can just compare the provided date with only the date part of the birth date in database but did not find any reference anywhere.
Don't convert your column to a string. Here's how to do it with a date/datetime/timestamp.
import { startOfDay, endOfDay } from 'date-fns';
import { Between, Equal } from "typeorm";
//...
let findArgs = {
where:{
date: Between(startOfDay(webInputArgs.date).toISOString(), endOfDay(webInputArgs.date).toISOString()),
userId: Equal(ctx.req.session.userId)
}
};
return entity.find(findArgs) as any;
You can use the query builder and the postgresql DATE_TRUNC() function:
const usersBornToday = await getManager()
.createQueryBuilder(User, "user")
.where(`DATE_TRUNC('day', "birthdatetime") = :date`, {date: '2021-03-27'})
.getMany()
Found the solution, We can actually use the LIKE operator, the only prerequisite is that we would have to convert the date to string,
something like
date_of_birth::text LIKE '2011-01-%'
If the DB type is MySQL, the CONVERT function will achieve the same approach used by #Vijender, which is to convert timestamp to text as below:
let date = '2022-01-25'; //yyyy-mm-dd, for Regex validation - /\d{4}\-\d{2}\-\d{2}/
date = `${date}%`;
queryResult.where('CONVERT(date_of_birth, char) LIKE :date', { date });
Todo:only show today stock list
const start = moment().startOf('day').toDate();
const end = moment().endOf('day').toDate();
const query=getManger()
.createQueryBuilder(stocks, 'stocks')
.andWhere('stocks.createdAt BETWEEN :start AND :end', { start, end })
I have a backend written on top of node.js, I'm using TypeORM as the ORM and Azure SQL Database to store my data. When I call the ORM's create() and save() functions, I'm passing in the correct date and time as can be seen below. But when I query the inserted data in the server, the timezone has shifted from -03:00 to +00:00. It maybe a normal behavior, since I'm new working with dates though.
This is the code where I call the create() in:
class CreateAppointmentsService {
public async execute({ provider, date }: RequestDTO): Promise<Appointment> {
const appointmentsRepository = getCustomRepository(AppointmentsRepository);
const roundDate = startOfHour(date);
const foundAppointment = await appointmentsRepository.findByDate(roundDate);
if (foundAppointment) {
throw Error('This date and time already has a booking.');
}
const appointment = appointmentsRepository.create({
provider,
date: roundDate,
});
await appointmentsRepository.save(appointment);
return appointment;
}
}
This is my debug information, showing date and time in expected timezone.
This is the data in the database. The field type is datetimeoffset and the server time is set to UTC (+00:00).
Thanks in advance! =)
[EDIT]: Explaining better: the time I posted to the database is rounded to 20:00 -03:00 (America/Sao_Paulo/Brasilia). If you look the column "created_at", the time is updated to UTC, but the column "data" only got the timezone set to +00:00, the time remais 20:00.
Found the problem! I forgot to set the "date" column to datetimeoffset in the typeORM model =(.
How it was:
#Column()
date: Date;
Changed to:
#Column('datetimeoffset')
date: Date;
Now it work wonders! The correct timezone is being set alongside the time. Cheers!
Let's say i am storing some timestamps in my MongoDB, each timestamp indicates a time when some certain function should be run.
I am not sure what should be the correct approach to this since I am new in backend developing.
Mongo data structure goes like this(this is just an example):
{id: 115155, userId: 152115, timestamp: 13-09-2019:15:30:00}
and on this certain time I want to trigger a function:
someFunction(eventId, userId){ ...something here }
You need to change the format of timestamp you get from mongodb into something like this - "13 Sept 2019 18:39:40" or "2019-01-01 00:00:00". Then you need to parse the timestamp you get from mongodb using this Date.parse()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse
Once that is done you need to get difference between timestamp and current time and use that difference in a setTimeout() function, which takes 2 parameters - function to be run and time in milliseconds
let timediff = new Date() - Date.parse("2019-09-13 18:54:50");
setTimeout(function() {
console.log("Called when current time = mongodb timestamp");
}, timediff);
I have a postgreSQL table like this:
table.string('id');
table.string('name');
table.specificType('data', 'JSONB');
table.timestamp('runDate');
table.boolean('done').default(false);
I wonder what is the safe way to insert date time inside the database.
This is what I do:
await _i_.knex("jobs")
.transacting(ctx ? ctx.transaction : null)
.insert({
id: job.id,
name: job.name,
data: job.data,
id: job.id,
runDate: job.runDate,
done: false
});
When I want to query my table, I use:
return await _i_.knex('jobs')
.transacting(ctx ? ctx.transaction : null)
.whereRaw('"runDate" < NOW()')
.andWhere('done', false)
.returning("*")
.update({
done: true
});
So I can have issue with the timezone if my nodeJS server doesn't have the save timezone than my PostgreSQL.
How do you manage that?
By default knex creates timestamp with time zone (timestamptz) type for .timestamp() columns for PostgreSQL. So, your date and time are stored with timezone. For inserting timestamp values I like to use moment package.
const moment = require('moment');
const dateStr = moment().utc().format();
console.log(dateStr); // => Date in format 'YYYY-MM-DDTHH:mm:ssZ'
knex.insert({ runDate: dateStr })
How about using the DB time on insert: ...runDate: knex.raw("NOW()")...
Then the storage and retrieval dates will be synchronized to the same timezone.
BUT if the job.runDate needs millisecond accuracy, or the record has been held for a significant amount of time before storage, then this would not be appropriate.