Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
97
rated 0 times [  101] [ 4]  / answers: 1 / hits: 18509  / 7 Years ago, thu, january 4, 2018, 12:00:00

I tried to read sorted data from Cloud Firestore using OrderBy.
And Firestore returned data as Following Order:



AAA

BBB

aaa

bbb



Now, what I want is something like following:



AAA

aaa

BBB

bbb



I want this result only using OrderBy not by manual Sorting.

Is there any way to sort like this in Firestore?



Please provide me a solution for this.



Thanks in Advance.


More From » firebase

 Answers
22

Sorting and filtering in Cloud Firestore are case sensitive. There is no flag to make the sorting or filtering ignore the case.


The only way to achieve your use-case is to store the field twice.


Let's say your field that stores 'AAA' & 'aaa' is called myData. In your client code you'll need to store a second field called myData_insensitive where you store a case-insensitive copy of the data.


DocA:
-> myData = 'AAA'
-> myData_insensitive = 'AAA'

DocB:
-> myData = 'aaa'
-> myData_insensitive = 'AAA'

DocC:
-> myData = 'BBB'
-> myData_insensitive = 'BBB'

DocD:
-> myData = 'bbb'
-> myData_insensitive = 'BBB'

Now you can query and/or order by myData_insensitive, but display myData.


Two interesting thing about this area is:



  1. With Unicode, removing case is more complex than just 'toLowerCase'

  2. Different human languages will sort the same characters differently


Without creating separate indexes for each collation to solve (2), one implementation approach to deal with (1) is via case folding. If you want to only support modern browser versions, then the following gives you a JavaScript example:


caseFoldNormalize = function (s){
return s.normalize('NFKC').toLowerCase().toUpperCase().toLowerCase()
};
caseFoldDoc = function(doc, field_options) {
// Case fold desired document fields
if (field_options != null) {
for (var field in field_options) {
if (field_options.hasOwnProperty(field)) {
switch(field_options[field]) {
case 'case_fold':
if (doc.hasOwnProperty(field) && Object.prototype.toString.call(doc[field]) === "[object String]") {
doc[field.concat("_insensitive")] = caseFoldNormalize(doc[field])
}
break;
}
}
}
}
return doc;
}

var raw_document = {
name: "Los Angeles",
state: "CA",
country: "USA",
structure: 'Waſſerſchloß',
message: 'quıt quit' // Notice the different i's
};

var field_options = {
name: 'case_fold',
country: 'case_fold',
structure: 'case_fold',
message: 'case_fold'
}

var firestore_document = caseFoldDoc(raw_document, field_options);

db.collection("cities").doc("LA").set(firestore_document).then(function() {
console.log("Document successfully written!");
}).catch(function(error) {
console.error("Error writing document: ", error);
});

This will give you a document in Cloud Firestore with the following fields:


{ 
"name": "Los Angeles",
"state": "CA",
"country": "USA",
"structure": "Waſſerſchloß",
"message": "quıt quit",
"name_casefold": "los angeles",
"country_casefold": "usa",
"structure_casefold": "wasserschloss",
"message_casefold": "quit quit"
}

To handle older browser, you can see one solution in How do I make toLowerCase() and toUpperCase() consistent across browsers


[#55545] Saturday, December 30, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
aileenreynap

Total Points: 140
Total Questions: 106
Total Answers: 99

Location: Andorra
Member since Sun, Oct 18, 2020
4 Years ago
;