Handling a time-stamp in Firebase - javascript

In firebase realtime database, something seemingly basic does not work.
Here is the JS code:
let myDBRef = firebase.database().ref('MyCollection');
newItem = myDBRef.push(),
startTime = firebase.database.ServerValue.TIMESTAMP,
endTime = startTime + 24*3600*1000
newItem.set({
someField:'myFieldValue',
startTime:startTime,
endTime:endTime
});
I expect something like the following in the DB as a result:
-MXb9s2-3mX3XZL_azRv
endTime: 1601691254295
someField: "myFieldValue"
startTime: 1601604854295
But I get this instead:
-MXb9s2-3mX3XZL_azRv
endTime: "[object Object]86400000"
someField: "myFieldValue"
startTime: 1601604854295
What am I doing wrong and how do I need to change the JS code to get the result I expect?

The firebase.database.ServerValue.TIMESTAMP is not the current server-side timestamp, but a marker value that gets translated to the actual server-side timestamp when written to the database.
That means that you can't store calculated values like you do now in a single step. You have two options:
Store the duration instead of the endTime. So:
let myDBRef = firebase.database().ref('MyCollection');
newItem = myDBRef.push(),
startTime = firebase.database.ServerValue.TIMESTAMP,
duration = 24*3600*1000
newItem.set({
someField:'myFieldValue',
startTime:startTime,
duration:duration
});
Store the startTime first, and then calculate the endTime either in the client or in a Cloud Function, that then updates the database. This'd be something like:
let myDBRef = firebase.database().ref('MyCollection');
newItem = myDBRef.push(),
startTime = firebase.database.ServerValue.TIMESTAMP,
duration = 24*3600*1000
newItem.set({
someField:'myFieldValue',
startTime:startTime,
}).then(() => {
newItem.child("startTime").once("value").then((snapshot) => {
newItem.update({ endTime: snapshot.val() + duration });
})
})

Related

Not getting results from cloud functions by .where()

I am using this code to get data from a collection by comparing
/* eslint-disable */
const functions = require("firebase-functions");
const admin = require('firebase-admin');
admin.initializeApp();
const database = admin.firestore();
exports.checkForPending = functions.pubsub.schedule('* * * * *').onRun(async (context)
=> {
var currentTime = admin.firestore.Timestamp.now();
var total; //getting time from firebase server
var firebase_time = admin.firestore.Timestamp.now(); // {'_seconds': 123456,
_nanoseconds: 123000000}
// Convert map of nanoseconds and seconds to milliseconds
var firebase_seconds_to_milliseconds = firebase_time._seconds * 1000; // 123456000
var firebase_nanoseconds_to_milliseconds = Math.round(firebase_time._nanoseconds /
1000000) //123
var milliseconds = firebase_seconds_to_milliseconds +
firebase_nanoseconds_to_milliseconds;
var firebase_month = firebase_time.toDate().getMonth();
var unix_to_date_before_buffer = new Date(milliseconds);
var unix_to_date_after_buffer = new Date(milliseconds);
// var unix_to_date = new Date(total);
unix_to_date_before_buffer.setSeconds(0); //coverted from 6:38:23 to 6:38:00
unix_to_date_after_buffer.setSeconds(0);
unix_to_date_after_buffer.setMinutes(unix_to_date_after_buffer.getMinutes() + 1);//coverted from 6:38:23 to 6:39:00
//Want to edit month in this timestamp;
const query =
database.collection("users").doc('IELTS').collection('IELTS').where("next", '>=', unix_to_date_before_buffer).where("next", '<=', unix_to_date_after_buffer); // comparing here
const snapshot = await query.get();
snapshot.forEach(doc => {
console.log(doc.id, '=>', doc.data().name),
queryTest2 = database.collection('rest');
queryTest2.add(
{
'executed': true,
'name': doc.data().name
}
)
});
return null;
});
The am not getting any results in the console. I am wondering why?
I didn't see any new collection 'rest' formed.
The time in the collection of parameter 'next' was 6:38:24 in the collection in the example.
What I am trying to build -
I am making an app for an institute. I am registering users and making a collection which looks like -
collection
(here 'date' is the date of registration and 'next' is the time when The pay will automatically change to 0 because of the starting of next month.)
Now I am running a cloud function that is checking every day if 'next' is equal to the current time of server, then I want to execute something (add a user to a new collection called 'pending'.) and update 'next' to the next month. which should look like this -
edited-paramter

How to check if a day has passed in Firebase?

I have saved this timestamp in a Firestore document:
last_check_mmr: 14 dicembre 2021 15:39:01 UTC+1
How can I check if a day has passed from that date using Javascript?
Since you use a Cloud Function it is quite easy by using Dayjs, the "minimalist JavaScript library that parses, validates, manipulates, and displays dates".
Something like the following, using the diff() method, should do the trick:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const dayjs = require('dayjs');
// Let's imagine you use a scheduled Cloud Funciton
exports.scheduledFunction = functions.pubsub.schedule('...').onRun(async (context) => {
// Get the value of the timestamp, e.g. by fetching a Firestore document
const docRef = ...;
const snap = await docRef.get();
const last_check_mmr = snap.get('last_check_mmr');
const date = dayjs(last_check_mmr.toDate());
const now = dayjs();
console.log(date.diff(now, 'd'));
// If you get a value of 0, it means it is less than a day, if you get -1 or less it is more than a day
if (date.diff(now, 'd') < 0) {
// more than a day
}
return null;
});

ReactJS useState not updating momentJS prop

I am coding a CRM app and there's a asnyc function for gettingTrackers and it working well. There's another function called calculateStartTime and this function suppose to calculate momentJS variable and set it but this is not updating.
useEffect(() => {
async function gettingTrackers() {
await getTrackers(null, null);
}
gettingTrackers();
calculateStartTime();
}, []);
const [startTime, setStartTime] = useState(moment().format("YYYY-MM-DD"));
const [endTime, setEndTime] = useState(moment().format("YYYY-MM-DD"));
const calculateStartTime = () => {
const dateOfMay = moment("2020-05-01");
const now = moment();
let timeTheStart = null;
let timeTheEnd = null;
if (now.add(-32, "d").diff(dateOfMay) <= 0) {
timeTheStart = dateOfMay.format("YYYY-MM-DD")
timeTheEnd = moment().add(-2, "d").format("YYYY-MM-DD");
} else {
timeTheStart = moment().add(-32, "d").format("YYYY-MM-DD");
timeTheEnd = moment().add(-2, "d").format("YYYY-MM-DD");
}
console.log("calculating...")
console.log("start time > ", timeTheStart)
console.log("end time > ", timeTheEnd);
setStartTime(moment(timeTheStart).format("YYYY-MM-DD"))
setEndTime(moment(timeTheEnd).format("YYYY-MM-DD"))
// these 2 logs prints initial value, not updated value.
console.log(startTime);
console.log(endTime)
}
The problem is that I have to send startTime and endTime to another ReactJS component, and it sends first initial today value every time. When I call calculateStartTime it logs
calculating...
start time > 2020-06-07
end time > 2020-07-07
But when I click to button for another component, I print these variables and its output;
2020-07-09
2020-07-09
as initial values. I log them with using startTime and endTime as I described in useState
What I am missing on this problem? Is there any memory-leak to not-working?
Edit:
const goToResultButton = (event, data) => {
event.preventDefault();
console.log("start time > ", startTime)
console.log("end time > ", endTime)
}
Thanks in advance!
With the below code block, you are setting the state and immediately you are trying to access the updated value, but state updates done in async fashion. You will get the latest value in the next re-render.
...
setStartTime(moment(timeTheStart).format("YYYY-MM-DD"))
setEndTime(moment(timeTheEnd).format("YYYY-MM-DD"))
// these 2 logs prints initial value, not updated value.
console.log(startTime);
console.log(endTime)
...
You can use a useEffect to log or do something with latest values of startTime and endTime.
useEffect(() => {
console.log("startTime", startTime);
console.log("endTime", endTime);
}, [startTime, endTime]);

new Date().getTime() showing NaN in JavaScript

I am trying to save the current time inside a temporary object inside the timestamp key using new Date.getTime() and push it into an array which is inside a globally accessible variable, GLOBAL_VAR.
But after I make the temporary variable and print its value it shows the timestamp is NaN I don't know why I can't get it inside the object (the console.log() and the result is shown below)
Also,
handleOrderMessage function is called when a socket.io event is received I don't know if that will affect the new Date.getTime() function, showing output:
console.log("TEMP OBJECT IS", tempObject)
/*
{
id: "-909e-11ea-9ede-066a42ffe1ae",
​price: "0.1",
​quantity: "0.1",
​side: "buy",
​timestamp: NaN
}
*/
function handleOrderMessage(msg) {
let d = new Date();
console.log(d.getTime());
if (msg['status'] === "PLACED") {
//for buy
if (msg['orderSide'] === "Buy") {
let tempObject = {
side: "buy",
id: msg["OrderID"],
timestamp: d.getTime(),
quantity: parseFloat(msg["Quantity"].toFixed(4)).toString(),
price: parseFloat(msg["Price"].toFixed(4)).toString()
}
//pushing to the global orders with price from msg as key
if (tempObject.price in GLOBAL_VAR.bidOrdersPricesAsKey) {
GLOBAL_VAR.bidOrdersPricesAsKey[tempObject.price].push(tempObject);
} else {
GLOBAL_VAR.bidOrdersPricesAsKey[tempObject.price] = [tempObject]
}
console.log("GLOBAL VAR BUY ORDERS PRICES ASK KEY", GLOBAL_VAR.bidOrdersPricesAsKey)
console.log("TEMP OBJECT IS", tempObject)
}
}
Following seems to be working fine, not sure why you're getting NaN. Please provide full working code to troubleshoot the issue.
doit();
function doit() {
let d = new Date();
let tempObject = {
side: "buy",
timestamp: d.getTime()
};
console.log(tempObject);
}

removing cookies using javascript is not done immediatly

I am currently working with a javascript that is supposed to remove some unwanted cookies, but for some reason aren't they removed when told to?..
only after certain amount of times trying to remove them, they seem to be removed.. some sort of delayed effect?
here is the code:
const name = 'test_u';
const name1 = 'test_te_s';
function eraseCookie(name) {
document.cookie = name+'=; Max-Age=-99999999;';
}
function removeCookies(cookieA, cookieB) {
setInterval(function() {
if (document.cookie.includes(cookieA) || document.cookie.includes(cookieB))
{
eraseCookie(cookieA);
eraseCookie(cookieB);
var date = new Date();
var timestamp = date.getTime();
console.log(timestamp)
}
},10000);
}
removeCookies(name, name1);
example from console log output:
1555420706478
1555420716477
1555420726487
1555420736487
1555420746497
1555420756487
It runs 6 times before its removed? but why though?
why aren't they removed immediately?
Because you have setInterval which means that that code will be run after some time that you provide, and keep repeating it by that interval. So just remove that setInterval:
function removeCookies(cookieA, cookieB) {
if (document.cookie.includes(cookieA) || document.cookie.includes(cookieB)) {
eraseCookie(cookieA);
eraseCookie(cookieB);
var date = new Date();
var timestamp = date.getTime();
console.log(timestamp)
}
}
And if you want to keep repeating it try this one:
removeCookies(name, name1);
setInterval(() => {
removeCookies(name, name1);
}, 10000);
or
function removeCookies(cookieA, cookieB) {
if (document.cookie.includes(cookieA) || document.cookie.includes(cookieB)) {
eraseCookie(cookieA);
eraseCookie(cookieB);
var date = new Date();
var timestamp = date.getTime();
console.log(timestamp)
}
setInterval(() => {
removeCookies()
}, 10000);
}
removeCookies(name, name1);
so it will first call removeCookies, and then it will keep repeating.

Categories