Why is 100 in front of 11 in firebase documents order? - firebase

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));

Related

Preventing magic numbers used in firebase realtime database

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.

What exactly does firebase use when ordering Childs in firebase database

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"

Stop Firebase from removing 0 from a number

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.

Google Could Firestore order string field like number

i am trying to order a field in Firestore which is a string, but contains numbers. Can i somehow specify the ordering method or customise it?
** Edit 1:
The order i am getting is like this:
1 -> 10 -> 100 -> 101
But i want:
1 -> 2 -> 3 -> 4
If you have a need for strings to behave like numbers, you're using the wrong data type. Use numbers when you need numeric behavior. It sounds like you may have to rewrite all your documents and update your code to properly type the data.
In short, no, you can't do what you're asking (without making a change, or reordering the documents on the client).
I was trying to order items in my Firestore Recycler by querying a number value field and the app was crashing.
So i tried :
Query query = placesRef.orderBy( String.valueOf("likesNum"), Query.Direction.DESCENDING).limit(5);
And it worked. Although the compiler is saying String.valueOF() is not necessary, my problem is perfectly solved.
Maybe that helps someone with same issue.
query = placesRef.orderBy( String.valueOf("likesNum"), Query.Direction.DESCENDING).limit(5);
This only works because when you order by String, the limit is 9 items. Nothing will show up again after that so the best way is to store the field as a number.

element-attribute-range-query fetching result but element-attribute-value-query is not fetching any result

I wanted to fetch the document which have the particular element attribute value.
So, I tried the cts:element-attribute-value-query but I didn't get any result. But the same element attribute value, I am able to get using cts:element-attribute-range-query.
Here the sample snippet used.
let $s-query := cts:element-attribute-range-query(xs:QName("tit:title"),xs:QName("name"),"=",
"SampleTitle",
("collation=http://marklogic.com/collation/codepoint"))
let $s-query := cts:element-attribute-value-query(xs:QName("tit:title"),xs:QName("name"),
"SampleTitle",
())
return cts:search(fn:doc(),($s-query))
The problem with range-query is it needs the range index. I have hundreds of DB's in multiple hosts. I need to create range indexes on each DB.
What could be the problem with attribute-value-query?
I found the issue with a couple of research.
Actually the result document is a french language document. It has the structure as follows. This is a sample.
<doc xml:lang="fr:CA" xmlns:tit="title">
<tit:title name="SampleTitle"/>
</doc>
The cts:element-attribute-value-query is a language dependent query. To get the french language results, then language needs to be mentioned in the option as follows.
cts:element-attribute-value-query(xs:QName("tit:title"),xs:QName("name"), "SampleTitle",("lang=fr"))
But cts:element-attribute-range-query don't require the language option.
Thanks for the effort.

Resources