I'm fetching longitude and latitude values from a database using a home address.
The structure of each of the documents in the collection is as follows:
"Ext": string
"Lat": string
"Long": string
"Parish": string
"Postal": string
"Street": string
"Number": string
There are a handful of different where() conditions, all wrapped in if statements.
The street number where() condition always causes the query to return no matches, and all of the other where()'s find matches correctly.
I have tried:
function addressToCoords() {
// returns an array of coordinates if successful, false otherwise
const ADD = document.getElementById("address").value;
let NUM;
let STREET;
if (ADD) {
NUM = ADD.match(/^[0-9]+/)[0];
STREET = ADD.replace(/^[0-9]+\s/, "");
if (NUM === STREET) {
console.log("NUM = STREET. regex split failed");
STREET = null;
return false;
}
}
const CTY = document.getElementById('parish').value;
const POS = document.getElementById('postalCode').value.replace(/\s/, "");
let coords = [0.0, 0.0];
let query = f.addresses;
if (CTY) { console.log("CTY: ", CTY); query = query.where("Parish", "==", CTY); }
if (STREET) { console.log("STREET: ", STREET); query = query.where("Street", "==", STREET); }
if (POS) { console.log("POS: ", POS); query = query.where("Postal", "==", POS); }
// -FIXME- doesn't match
if (NUM) {
// Usual test case outputs:
// NUM: 1 string 1
console.log("NUM: ", NUM, " ", typeof(NUM), " ", NUM.length);
query = query.where("Number", "==", NUM);
}
query.limit(5)
.get()
.then(querySnapshot => {
if (!querySnapshot.empty) {
querySnapshot.docs.forEach (ele => {
console.log("doc found!: ", ele.data());
});
coords[0] = querySnapshot.docs[0].Lat;
coords[1] = querySnapshot.docs[0].Long;
} else {
console.log("no doc found!");
}
}).catch(function(error) {
console.log(error);
});
document.getElementById("Latitude").value = coords[0];
document.getElementById('Longitude').value = coords[1];
return coords;
}
Any insight is appreciated.
Edit: I'm currently also going back and forth with firebase support, and apparently my code successfully queries the example database the rep built and functions correctly.
That seems to leave some kind of issue with the database structure, but...
This is probably my ignorance talking, but the problem seems pretty bizarre.
Firebase support is very helpful. This answer is thanks to the support rep that figured it out.
Thanks Carlos!
So it turns out my code was correct, there was a remarkably subtle problem with my data.
I had downloaded the data in this database from another database in csv format, verified the contents with Excel, and at some point saved it. Excel, being Excel, decided that any good UTF-8 encoded csv file needs to begin with a Byte-Order-Mark.
For those who don't know (like I didn't), Byte-Order-Mark's are invisible characters (zero width) in the unicode character set. They'll show up as weird question mark symbols in some text editors, but usually just don't get displayed at all.
Specifically, BOM's are used for specifying the endianness of a string of bytes so that they can be properly interpreted.
The BOM ended up being the first character in the name of the database Number field because that was the first column specified in the csv file and, counter-intuitively enough, it wasn't the value that wasn't matching, it was the field name.
There were a couple indications of this that I lacked the background to recognize:
The solution was to either:
Update each and every entry in the collection (since the csv column name became the property name in my csv to json conversion, then the firestore field name when I uploaded),
or
Delete the collection entirely and use some kind of find and replace tool (VS Code's search did the job) to replace all of the BOM's with an empty string (simply not specifying a replacement value in VS Code search and hitting "replace all" worked).
If the data had some other problems with zero-width (or other undesirable) characters they could be filtered out with a whitelist filtering tool. Blacklisting would work in theory, but with a character set as large as unicode's it wouldn't be practical unless you were only filtering out zero-width characters.
Thanks to everyone who took a look!