I was trying to use firebase database for a price filter feature, where prices are entered as Childs in a node, I figured they would automatically be entered by ascending numeric orders, but it seems like that is not always the case.
For example as you see on the photo, 55 comes before 450, and 55,000 comes before 450,000, but somehow 5,500,000,000 comes after 45,000,000,000 even though it is a lower numeric value, is there a reason for this behavior?
Pls explain, Thank YOu.
Keys in the Firebase Realtime Database are stored as strings. And in string comparison 2 comes after 11, no matter how unintuitive that may be.
Since keys are stored as strings and you can't change that, the only solution is to change the format in which you store them. For example: if you store all values in a fixed length string and left-pad it with either zeroes or spaces, their alphabetical order will be the same as the numerical order.
For example:
00000000055
00000000450
00000055000
00000450000
05500000000
45000000000
Since you're using some really large numbers, it might also be worth to ensure Firebase interprets them as strings everywhere by prefixing them with an alphanumeric value, like:
"key00000000055"
"key00000000450"
"key00000055000"
"key00000450000"
"key05500000000"
"key45000000000"
Related
So I want to specify a time after which a post gets deleted. The time is 3 months, in my code I would define this as
const THREE_MONTHS_IN_MS = 7889400000
export const TIME_AFTER_WHICH_USER_IS_DELETED = THREE_MONTHS_IN_MS
How can I define this in my database without resorting to the use of a magic number? Basically it looks like this right now:
timeAfterWhichUserIsDeleted: 7889400000
Or as a direct screenshot of the database: https://gyazo.com/67abfdc329e1e36aae4e66b0da4b4f75
I would like to avoid this value in the database and instead have it be more readable.
Any tips or suggestions?
The 7889400000 is a UNIX timestamp, indicating a number of milliseconds since the epic. While you can store a value indicating the same moment in a different format, you'll want to make sure that the format you use still allows you to query the value.
A common format that is both readable and queryable it ISO-8859-1, and my current time in that format would be 2022-03-22 06:50:48.
I noticed after re-reading your question that your timeAfterWhichUserIsDeleted is actually an interval and not a moment. If the interval is always going to be in months, you could store countOfMonthsAfterWhichUserIsDeleted: 3 as a more readable form of the same intent. Just note that 3 is equally magic as 7889400000 and the main difference is that I've named the field more meaningfully.
I'm building an app that will display a list of user info, with each one a numeric ID that is stored when creating the profile and used as the docID in firebase. To facilitate the search, I used this method so the ID would be displayed in ascending order. But, after some tests, I notice that, for example, 100 comes first then 11. Why does it happen? Is there a way to correct/prevent it?
I was storing ID as String. But, as the answer suggested, I changed it to both int and double. Still, 11 comes after 100
It's hard to say for certain without seeing your database, but most likely you're storing the numbers as strings. In such cases Firebase (both Firestore and Realtime Database) will sort the values lexicographically, and in that order "100" comes before "11" - just as "baa" comes before "bb".
Why is 100 in front of 11 in firebase documents order?
Because you're sorting alphabetically instead of numerically. 0 comes before 1 in most character encodings like ASCII and Unicode.
After the answers I got and some research I finally got it.
The main problem was that I was storing the ID as String.
After fixing it, I added .orderBy('id') in the place where I retrieve the
uses' list.
Thank you everyone one for the time spent trying to help me.
Another way is to perform sorting after you queried. It is not efficient though, but in case you cannot change the data type or ids themselves:
const query = await db.collection("my-collection").get();
query.docs.sort((doc1, doc2) => parseInt(doc1.id) - parseInt(doc2.id));
This latitude should have a '0' at the end, but whenever I add it - Firebase deletes it. Being a coordinate I need it to be exactly 51.3910 not 51.391. Any idea how I'd force Firebase to leave the '0' in there?
From docs you have many options, since you have not added you code, you may try a code like this to solve the issue.
Firebase busCoords = mRef.child("Location");
busCoords.setValue(location.getLatitude()+ ", "+location.getLongitude());
This MUST be working, but you may also try turning the number to a string, which can be done with a code like this:
String numberAsString = String.valueOf( -895.25);
The Firebase Realtime Database uses JSON to store data, so will accept the following data types:
string
number
boolean
array
JSON object
null
The data type for your Latitude node will be considered a number, which does not support trailing or leading zeros.
Therefore, you'll need to manually pad your data when retrieving it from the database, or store it as a string instead.
So having looked into it for hours, I have figured out the problem lied with Google giving me wrong coordinates when I typed in 'example coordinates'. The coordinates were not right and the coordinates I wanted didn't end in a 0!
Thank you for your help.
I am currently using ref.endAt().limit(n).on(...) to get the 'last' n values.
All the .priority are null so the list is sorted by name which is a 0 padded timestamp
It seemed that if I set the .priority of each item also to the timestamp that it would take more storage. Does it?
Regardless of whether or not it takes more storage, is there a significant performance difference for retrieving the last n sorted items if .priority is all null (so name sort is used) or if .priority are all unique and that .priority sort is used?
I am currently designing for it to work well with 10,000 ish items in a list. Is .priority or name sort better when a list gets over 1,000,000 items?
What about using ref.startAt(null, timeStart).endAt(null, timeEnd).on(...)?
I could profile, but how would I know that server load or network delays are or are not affecting it?
There should be no performance difference between using priority or key names to sort items. Firebase first looks for priority to sort items, and if it doesn't exist, sorts items by key name. There might be a very small performance gain by using priority instead of key name, but I expect this to very small.
I have a JDOQL/DataNucleus storage layer which stores values that can have multiple primitive types in a varchar field. Some of them are numeric, and I need to compare (</>/...) them with numeric constants. How does one achieve that? I was trying to use e.g. (java.lang.)Long.parse on the field or value (e.g. java.lang.Long.parseLong(field) > java.lang.Long.parseLong(string_param)), supplying a parameter of type long against string field, etc. but it doesn't work. In fact, I very rarely get any errors, for various combinations it would return all values or no values for no easily discernible reasons.
Is there documentation for this?
Clarification: the field is of string type (actually a string collection from which I do a get). For some subset of values they may store ints, e.g. "3" string, and I need to do e.g. value >= 2 filters.
I tried using casts, but not much, they do produce errors, let me investigate some more
JDO has a well documented set of methods that are valid for use with JDOQL, upon which DataNucleus JDO adds some additional ones and allows users to add on support for others as per
http://www.datanucleus.org/products/accessplatform_3_3/jdo/jdoql.html#methods
then you also can use JDOQL casts (on the same page as that link).