I have two tables named in users and card_info in my Postgres database. I have created an endpoint for registering new users and I have given a field called dateCreated as shown in the code below.
Register.js
const handleRegister=(req,res,db,bcrypt,saltRounds)=>{
const {name,phno,dob,email,username,password,aadharCard}=req.body;
if(!name || !email|| !phno || !dob || !username || !password || !aadharCard){
return res.status(400).json('Wrong Form Submission');
}
const hash=bcrypt.hashSync(password,saltRounds);
const accNo=Math.floor(2E9+Math.random()*1E9);
const dateCreated=new Date().toJSON().slice(0,10);
db('users')
.insert({
username:username,
name:name,
email:email,
password:hash,
dob:dob,
phno:phno,
aadhar:aadharCard,
acc_no:accNo,
created_date:dateCreated
})
.returning('*')
.then(users=>{
res.json(users[0]);
})
.catch(err=>res.status(400).json("Unable to register"));
}
module.exports={
handleRegister:handleRegister
}
In the card endpoint, I am selecting the user's created year whose id is sent as a request. I then store these values into the card_info table using calculated values. The expiration date is supposed to be 4 years more than the created_year. The id of the table users is a foreign key of the table card_info
Card.js
const genCard=(req,res,db)=>{
const {id,cardType} =req.body;
db.select('created_date').from('users').where("id","=",id)
.then(data=>{
const createdDate=data[0].created_date.toString();
db('card_info')
.insert({
card_number:Math.floor(Math.random()*1E17),
owner_id:id,
expiration_date: createdDate.replace(parseInt(createdDate),parseInt(createdDate)+4),
cvv:Math.floor(Math.random()*1E3),
card_type:cardType
})
.returning('*')
.then(users=>{
console.log(res.json(users[0]));
})
.catch(err=>res.json(err.message))
})
.catch(err=>res.json(err));
}
module.exports={
genCard
}
This is the error that I recieve: "insert into "card_info" ("card_number", "card_type", "cvv", "expiration_date", "owner_id") values ($1, $2, $3, $4, $5) returning * - time zone "gmt+0300" not recognized".
I have tried various date formatting methods but nothing seems to work. Please let me know if someone has a solution to this.
I would avoid all the attempts to manipuate strings that represent dates–it only results in tears and often doesn't consider edge cases. Rather manipulate the date directly. I would recommend Luxon that provides a battled-tested wrapper around Date and has convenience functions that make dealing with dates easier.
// convert to DateTime object
const createdDate = DateTime.fromJSDate(data[0].created_date);
// add 3 months
const futureDate = createdDate.plus({months: 3});
// insert a date object
db('card_info').insert({
card_number:Math.floor(Math.random()*1E17),
...
created: futureDate, // or futureDate.toJSDate()
})
Demo:
const {
DateTime
} = luxon;
// convert a saved date from the DB to DateTime
const dt = DateTime.fromJSDate(new Date());
// add 3 months
const futureDate = dt.plus({
months: 3
});
console.info(futureDate.toFormat('yyyy-MM-dd'), futureDate.toJSDate());
<script src="https://cdn.jsdelivr.net/npm/luxon#2.0.2/build/global/luxon.min.js"></script>
Related
I am working on a project where there are 2 databases (firestore) at same level.
One having user's profile and other has list of schedules.
Profile Db - user's email (stored as an array in the Db) , name, age.
Dates Db - user's email, time and date of schedule.
The function below matches user's email from the profile db with every email given in dates db and gives the list of dates having the same email.
DESIRED OUTPUT
startDateArr pushes the date records from dates Db so that the last date can be filtered and user can be informed of the last schedule.
ISSUE
I am unable to find the last date that is stored of the array.
let startDateArr = [];
db.collection('dates').onSnapshot((querySnapshot) => {
querySnapshot.forEach((doc) => {
db.collection('profiles').get().then((querySnapshot) => {
querySnapshot.forEach((profileDoc) => {
if (profileDoc.data().userEmail[profileDoc.data().userEmail.length - 1] === doc.data().userEmail) {
let finalDate = `${ doc.data().startDate[ doc.data().startDate.length - 1 ] }
${ doc.data().startMonth[ doc.data().startMonth.length - 1 ] }`
startDateArr.push(finalDate);
}
})
})
})
})
exports.resetDailyFinalKills = functions.pubsub
.schedule("*/5 * * * *")
.timeZone("Europe/Berlin")
.onRun(async (context) => {
const players = firestore.collection("players");
const goodtimes = await players
.where("registerDate", "<=", Date.now()-84600)
.get();
goodtimes.docs.forEach((snapshot) => {
const uuid = snapshot.data().uuid;
const url = `https://api.hypixel.net/player?key=x&uuid=${uuid}`;
const settings = {method: "Get"};
fetch(url, settings)
.then((res) => res.json())
.then((data) => {
const finals = data.player.stats.Bedwars.final_kills_bedwars;
const date = snapshot.data().registerDate;
snapshot.ref.update({todayFinalKills: finals});
snapshot.ref.update({registerDate: firebase.firestore
.Timestamp.fromDate(new Date(date+84600))});
console.log("got in");
console.log(finals);
});
// snapshot.ref.update({final_kills: 0});
});
return null;
});
So I have this function, first problem is
snapshot.ref.update({registerDate: firebase.firestore
.Timestamp.fromDate(new Date(date+84600))});
I'm trying to add a new timestamp to the registerDate field but it's not working? Second .where("registerDate", "<=", Date.now()-84600) here I'm trying to look for dates older than 24 hours but this also isn't working because I guess date's arent simply stored as numbers but I'm not sure how I would do what I want to here?
Timestamps are not stored as numbers. A query that uses a number for a filter will never match a timestamp, like you are doing here:
const goodtimes = await players
.where("registerDate", "<=", Date.now()-84600)
.get();
That query will only match documents where registerDate is a number within the requested range.
If you want to match document fields with a timestamp, you have to use a Timestamp object in the query filter A Date will work as well.
const goodtimes = await players
.where("registerDate", "<=", new Date(Date.now()-84600))
.get();
I have define a method on mongoose model as follows -
PatientSchema.methods.getAge = function(){
let ageDifMs = (Date.now() - this.dateOfBirth.getTime());
let ageDate = new Date(ageDifMs);
let age = Math.abs(ageDate.getUTCFullYear() - 1970);
return age;
}
It is working fine when I retrieve a single instance of that related model. Now my question when I retrieve multiple instance as follows -
const patientList = await Patient.find({})
How can I added new key-value pair in JS object where value is generated using method define in model. I can do it using loop but I want to know if there is any optimized way?
UPDATE -
As mentioned by #Milad Raeisi, I use virtuals as follows-
PatientSchema.virtual('age').get(function () {
let temp = new Date(this.dateOfBirth)
let ageDifMs = (Date.now() - temp.getTime());
let ageDate = new Date(ageDifMs);
return Math.abs(ageDate.getUTCFullYear() - 1970);
})
Also set mongoose.set('toJSON', { virtuals: true });
Again it is work perfectly for a single instance but returning null for multiple instance.
I am using code as below to get patient list -
const patientList = await Patient.find({})
.sort({name:1})
.limit(limit)
.skip(skipIndex)
.select(['name', 'gender', 'age'])
.exec();
If you really want to have an efficient way, you can do it in an aggregation query or you can store age in some cache and read age from there but normally you can use mongoose virtuals and calculate age in a virtual field.
check this link
Edit:
There is no need to get age from mongoose, because it's a virtual field and not exists on db, and also you need to get dateOfBirth in select in order to mongoose be able to calculate age in virtual field.
try this
const patientList = await Patient.find({})
.sort({name:1})
.limit(limit)
.skip(skipIndex)
.select(['name', 'gender', 'dateOfBirth'])
.exec();
Looking for assistance in replicating the following mssql operation in sequelize. We have a table with a valid_from and valid_to columns and I need to get todays current date and only return the records that are fall based on that.
I am looking to utilize the .findByPK(), or .findAll() methods in sequelize
SELECT * FROM [table] WHERE GETUTCDATE() BETWEEN f.valid_from AND f.valid_to
I have found the following posts and items with no luck. As they seem to specify two di9ffernt dates between the same column. I need to compare the current UTCDATE between two different columns
Sequelize Query to find all records that falls in between date range
Sequelize query - compare dates in two columns
I was able to simulate but would still like to know if anyone knows how to do the same thing using the between operator
const now = new Date();
return await models.Form.findAll({
where: {
valid_from: {
[Op.lte]: Sequelize.cast(now, 'DATETIMEOFFSET')
},
[Op.and]: {
validTo: {
[Op.gte]: Sequelize.cast(now, 'DATETIMEOFFSET')
}
}
}
});
You can write this query using sequelize.where() to generate the WHERE statement for the BETWEEN operation. For the current timestamp you need to call GETUTCDATE() which we can do via sequelize.fn().
const forms = await models.Form.findAll({
where: {
// create where condition for GETUTCDATE()
sequelize.where(sequelize.fn('GETUTCDATE'), {
// BETWEEN valid_from AND validTo
[Op.between]: [
sequelize.col('valid_from'),
sequelize.col('validTo')
],
}),
},
});
This will generate SQL like:
SELECT * FROM `form`
WHERE GETUTCDATE() BETWEEN `valid_from` AND `validTo`
note that you have underscored valid_from and camelCase validTo in your example.
I have an app with two types of users - managers and employees. Also my app has groups. I have the following structure of the firebase database:
groups (collection) -> group (document)
Each group contains two collections managers and employees. Each document in both of the collections contains a field birthday. I want to send two types of notifications:
One to the employee to tell him happy birthday.
One to the manager to tell him that his employee/manager has a birthday today.
What I did:
exports.scheduledBirthday = functions.pubsub.schedule('0 8 * * *').onRun((context) => {
return admin.firestore().doc(`groups/{groupUid}/{usersCollection}/{user}`).get().then(userDoc => {
const userData = userData.data();
const birthday = userData.birthday;
const userFullName = userData.full_name
const birthdayDate = pasrseBirthday(birthday);
const currentDate = new Date();
if (currentDate.getDay() === birthdayDate.getDay() && currentDate.getMonth() === birthdayDate.getMonth()) {
console.log("Creating a birthday notification for: " + userFullName);
let tokens = userData.tokens;
const payload = {
data: {
notification_type: "USER_BIRTHDAY",
user_type: usersCollection,
title: "Happy birthday " + userFullName + "!"
}
};
return admin.messaging().sendToDevice(tokens, payload);
}
return null;
});
});
The code does as following: Set a scheduled crontab to 08:00 each day. It checks if the user's birthday is today. If it is, it will send a "Happy birthday" notification to that user (by executing the Android Java code).
As I mentioned before, I would like to send a notification to the manager if some employee or manager in his group has a birthday today. If there are some users with a birthday, it should send only one push notification (instead of sending for each one). In order to do it I thought of keeping an array variable usersBirthdays and push userData if the user has a birthday. In the last iterator of the loop I made, check if usersBirthdays is empty and if it's not, iterate over the managers and send the push notification. But I have some technical difficulties:
Is it the best way to do it? If not, how should I do it instead?
How can I know if we are in our last iteration of the firebase loop?
How should I iterate over the managers and send each one a push notifcation?