I have a database and I want to sort all posts by their score (an integer), I thought it would be super easy because I'm currently doing orderByChild('created') and it works perfectly, but for some reason orderByChild('score') doesn't work.
Here is my database structure:
score is an integer that can be negative, positive or 0.
The JavaScript I'm using:
this.subscription = this.database.database.ref('/posts/'+this.userData.location)
.orderByChild('score')
.startAt(new Date().getTime() - (24 * 3600 * 1000)) //last 24 hrs
.limitToFirst(10);
this.subscription.on('child_added', (snapshot) => {
this.postFeed.push(snapshot.val())
console.log(this.postFeed)
});
The weird thing is, the console.log isn't even firing so it's not even getting to that stage for some reason, but if I change .orderByChild('score') to .orderByChild('created') it works exactly as expected...
Any ideas what I'm doing wrong? Thank you!
I believe it might be something to do with this line
.startAt(new Date().getTime() - (24 * 3600 * 1000))
This will create a startAt query which would currently be 1519944842592
This means that it's trying to start at that specific number. So it's not looking for -1, it's starting the query at 1519944842592.
You would need to incorporate a createdAt object within your schema and query that first.
The reason your .orderByChild('created') works is because it's a date object which is before the startAt query so that's why it works correctly :)
Related
Is it possible to somehow do it with startAt() and endAt()?
db.ref('/items')
.orderByChild('createdAt')
.endAt(new Date().getTime() + 180 * 60 * 1000) // Updated
.on('value', () => {/* ... */})
Edit:
What I'm trying to achieve is getting all the items that are currently in the database and listening for the newly added items from the last n hours.
Using a static number like endAt(1669743560642), lets say user is there for a few minutes, the number 1669743560642 will not be updated to the new time that has gone by, it's important to somehow that value gets somehow updated in real time.
So from (user's/server time) up to n hours.
Exports from Realtime Database:
{
"items": {
"-NI3TAUjGNRlAUQ3Yc8K": {
"createdBy": "5gQ5cfGN15WCSa9RZVvAYXhKTyc2",
"createdAt": 1669743560642
},
"-NI3i-jMEyx_inQCaALr": {
"createdBy": "lc4BcHOls7cBuTVmbNo9LmtDdlf2",
"createdAt": 1669747710748
},
"-NI8-Jb_Qvd8gA3nG9cv": {
"createdBy": "5gQ5cfGN15WCSa9RZVvAYXhKTyc2",
"createdAt": 1669819620439
}
}
}
It sounds like you want to get nodes with a createdAt value of N hours ago or newer. For that I see two problems in your code:
Since Firebase Realtime Database always orders the value in ascending order, that's a startAt operation, not an endAt operation.
Since you want N hours in the past, you need to subtract from the current timestamp, not add to it.
So something like this:
db.ref('/items')
.orderByChild('createdAt')
.startAt(Date.now() - 8 * 60 * 60 * 1000) // 8 hours ago
.on('value', () => {/* ... */})
There is no way to make that startAt value dynamic though. Once you create a query, it is immutable. So if you want the window of data to move, you'll have create another query for that.
In most cases where I need this, I actually end up post-filtering the nodes in my application code. So I create the query with the startAt value as above, and then add additional logic to expire items locally too. When you have a limit on the query too, that won't work or be harder, so I try to avoid needing that combination.
I'm trying to query stats for the hour which as the time 5 hours ago.
When I run this code, I see in the logs that the local time is 6 so I expect pastHour to be 1, but it says 3.
Why?
var HOURS_BACK = 5;
function main() {
var past = new Date(new Date().getTime() - HOURS_BACK * 3600 * 1000);
var pastHour = past.getHours();
var pastDateStr = getDateStringInTimeZone(past, 'yyyy-MM-dd');
query = "SELECT customer.id, metrics.impressions, segments.hour FROM customer WHERE metrics.impressions = 0 AND segments.hour = " + pastHour + " AND segments.date = '" + pastDateStr + "'";
Logger.log("query " + query);
}
edit — I'll leave the content below, but I now think that the mystery of the OP is not explainable by what's posted in the question.
It's important to keep in mind how Date values work. Internally, a Date is always a UTC-relative timestamp. That is, if (hypothetically) you and somebody across the world from you simultaneously called new Date().getTime(), you'd both get the same timestamp. (Obviously not really possible, but imagine you live in a cartoon world.)
However, the Date APIs like .getHours() work in your local time. The difference between local time and universal time causes lots of people confusion all the time, and things only get worse when your date/time values are subsequently involved in database operations, where the same problems may crop up once again.
I am trying to sort entries in my firebase by the most recent entry showing up as the first entry. I keep running into the issue that the most recent entry shows up last.
I am trying to sort by time as well as this is how it is set up in my databases:
I am also doing this in my code
completed.child(user.uid).orderByValue("time")
I was wondering where I was going wrong
This is how it shows up in my app:
There are quite a few problems with your code, so I'll try to address them in turn.
To order by a child property, use orderByChild
You're calling orderByValue("time"), but if you check the documentation you'll note that orderByValue() takes no parameters. If you want to order on the value of a child property, you should call orderByChild("time").
Use a time format that allows sorting them
Your current time format is not suited for sorting it. The problem is that your lexicographical sort order doesn't match with the chronological sort order you want. More simply put, this is the sort order you'll get (but not want):
"6:26AM"
"6:26PM"
"6:27AM"
To get the result you want, use a string format that allows the sorting. For example, use 24 hour/military notation with 0-padding:
"06:26"
"06:27"
"18:26"
You could also store a numerical value, for example: the number of minutes since midnight:
(( 6 * 60) + 26) = 386
(( 6 * 60) + 27) = 387
((18 * 60) + 26) = 1106
Firebase always returns in ascending order
Firebase always returns results in ascending order. I'll recommend reading a few relevant questions, but you have two options here:
Reverse the results client-side. This is often the simplest, as you're usually dealing with relatively a small result set.
Store an inverted value in the database for sorting.
This last one is typically easiest if you use a numerical value, like the number of minutes since midnight that we used above. If we store -1 * this value, we can then sort on that to get the results in reverse.
-1 * (( 6 * 60) + 26) = -386
-1 * (( 6 * 60) + 27) = -387
-1 * ((18 * 60) + 26) = -1106
I'm using localstorage to track domain visits and their timestamp.
Here's how I'm setting it:
localStorage.setItem(`${domain[0]}`, JSON.stringify(Date.now()));
What code would I use to delete all rows with a timestamp that's older than 30 days so users don't end up with too much extra data that probably won't be used?
I've seen a lot of examples about deleting individual rows based on the key. But I can't find anything related to bulk deleting based upon the values.
Enumerate all key/value pairs explicitly:
const cutOff = Date.now() - 30 * 24 * 3600 * 1000;
Object.entries(localStorage).forEach(([k, v]) => {
const time = JSON.parse(v);
if (time < cutOff) {
delete localStorage[k];
}
});
I made a similar question few hours ago, but I think I asked a wrong question there. This is more exact one.
im using cURL on PHP and i want to use a site, but everytime i change my site, the browser posts a value x to server, and if you dont, you can't go to the site.
you can see that the x value changes all the time from the picture, its a FireFox Live HTTP headers addon, it shows what pages i visit with browser
i looked the source code and found out what is the x value, and it comes from javascript. can i get the value with cURL or some other way from the server?
date = new Date();
ms = (date.getHours() * 24 * 60 * 1000) + (date.getMinutes() * 60 * 1000) + (date.getSeconds() * 1000) + date.getMilliseconds();
so the main problem is that the x value changes all the time and it has to be exactly "right" value , even milliseconds must be correct. i tried finding the value myself with javascript and then putting it to php, but still does not work
The reason is simple, you mixed between $_POST and $_GET
Check your PHP make sure is refer/using $_GET['x']
All that javascript is doing is calculating the current time in milliseconds on the client and sending it to the server. You can calculate such a time in php trivially with $ms = time() * 1000;