How to avoid inconsistency when adding data to Firestore? - firebase

We are building an app where we want to display cities. Each city has also an image which is stored in Firebase Storage. We are adding data to the db either using the Firebase console or programmatically. The problem arrives when we add data that contain special characters, for instance, I have this url:
https://firebasestorage.googleapis.com ... München.png
This is how it looks like in the browser. If we are adding this url using the Firebase console it will be saved the same as above, however, when we do it programmatically, that url is saved:
https://firebasestorage.googleapis.com ... M%C3%BCnchen.png
So the following query:
db.collection("cities")
.whereEqualTo(
"cityPictureUrl",
"https://firebasestorage.googleapis.com ... München.png"
);
Won't work since the name in the database is M%C3%BCnchen and not München. How to have the data stored in most correct way to avoid inconsistency?

You may encode the URI before querying, as follows:
String imageURI = "https://firebasestorage.googleapis.com ... München.png";
String imageURIEncoded = URLEncoder.encode(imageURI, "utf-8");
db.collection("cities")
.whereEqualTo(
"cityPictureUrl",
imageURIEncoded
);
URLEncoder.encode() will "encode a Uniform Resource Identifier (URI) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character"

Related

Purpose of tilde delimited values in URL fragment instead of GET params

I came across an unusual URL structure on a site. It looked like this:
https://www.agilealliance.org/glossary/xp/#q=~(infinite~false~filters~(postType~(~'post~'aa_book~'aa_event_session~'aa_experience_report)~tags~(~'xp))~searchTerm~'~sort~false~sortDirection~'asc~page~1)
It seems the category, pagination and sort options of a widget on the page injects and reads through these values. Does this format for storing data in the URL have a name, or is this an esoteric format someone made?
What's the purpose of doing this over using regular GET params, or at least using a more conventional format after the fragment?
If you inspect the URL carefully, you'll see that the parameters you describe are placed after the fragment (#), meaning they're not sent to the server but used by the client instead.
In this case, the client (JavaScript) builds them into something like an ElasticSearch query that's then POSTed to the server, in order to update listing you see on your screen.

Is base64 a good option for encoding custom Document IDS for Firestore?

I am working on creating some users in my firebase app and I would like to provide custom user ids as they are authenticating with an external service.
For example my user ID generation is consisted by 2 parts like so:
AuthService:AuthServiceUsername
That can look in reality like:
Instragram:dimitrioskanellopoulos
But I dont like to have this string used as a user id so I encode it to base64 like so:
const uid = Buffer.from(`instagram:${serviceUserID}`).toString('base64');
Is there any risk for me doing that ? Is base64 ok to be used also in regards to query params?
Firestore document IDs are quite flexible on what's allowed and not. See https://firebase.google.com/docs/firestore/quotas#limits.
But base64 would actually not be safe, since it contains /, which is disallowed in Firestore document IDs

Using a substring of a return value in a subsequent request

I'm attempting to construct a series of Paw calls using the variables feature. I have one situation I'm unable to solve.
At authentication into the server I'm using, I get a JSON response, with one value that looks like this:
endpoint = "https://sub.something.com/thingone/thingtwo.php?token=sometoken&id=blahblah"
The endpoint portion "https://sub.something.com/" is then used as the base for subsequent calls, where a call might be "GET https://sub.something.com/data?id=123".
I don't want to hardcode the endpoint in Paw, as the endpoint will vary based on factors I can't predict at my end.
Is there a way to do basic string processing like this either in Paw, or by calling out to a shell script and using the return value of said script as a Paw variable?
That's doable using that RegExp Match dynamic value extension. Click on that previous link and hit Install Extension.
Type "Regexp" in the field you expect this value to be used. Pick Regexp Match from the completion results:
Then enter a regexp that matches your need, https?://[^/]+/? should be good:
I've put your example string in the screenshot above to show that it works, but you can instead put a "pointer" (Response Dynamic Value) to the response you want:
In the choices, pick Response Parsed Body if you want to parse a JSON or XML from the reponse. If the string is simply in plain text in the response body, pick Response Raw Body.
Once these steps are completed, you've got a working "Pointer" + "Parser" to the response that extract the part of the string you need. You can do the same operation with another regex for the token…
Tip: these dynamic value tokens can be selected like text and copy/pasted (Cmd+C/Cmd+V) :-)

Save File Prompt instead of FileWriteAllBytes

Long time lurker first time poster. Working with .Net / Linq for just a few years so I'm sure I'm missing something here. After countless hours of research I need help.
I based my code on a suggestion from https:http://damieng.com/blog/2010/01/11/linq-to-sql-tips-and-tricks-3
The following code currently saves a chosen file (pdf, doc, png, etc) which is stored in an sql database to the C:\temp. Works great. I want to take it one step further. Instead of saving it automatically to the c:\temp can I have the browser prompt so they can save it to their desired location.
{
var getFile = new myDataClass();
//retrieve attachment id from selected row
int attachmentId = Convert.ToInt32((this.gvAttachments.SelectedRow.Cells[1].Text));
//retrieve attachment information from dataclass (sql attachment table)
var results = from file in getFile.AttachmentsContents
where file.Attachment_Id == attachmentId
select file;
string writePath = #"c:\temp";
var myFile = results.First();
File.WriteAllBytes(Path.Combine(writePath, myFile.attach_Name), myFile.attach_Data.ToArray());
}
So instead of using File.WriteAllBytes can I instead take the data returned from my linq Query (myFile) and pass it into something that would prompt for the user to save the file instead?). Can this returned object be used with response.transmitfile? Thanks so much.
Just use the BinaryWrite(myFile.attach_Data.ToArray()) method to send the data since it is already in memory.
But first set headers appropriately, for example:
"Content-Disposition", "attachment; filename="+myFile.attach_Name
"Content-Type", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
Content-type guides the receiving system on how it should handle the file. Here are more MS Office content types. If they are known at the point the data is stored, the content-type should be stored, too.
Also, since the file content is the only data you want in the response, call Clear before and End after BinaryWrite.

CA1305: int.Parse(String)

I am getting a CA1305 Warning.
Microsoft.Globalization : Because the
behavior of 'int.Parse(string)' could vary based on the
current user's locale settings,
replace this call in
'_Default.CalculateImageButton_Click(object,
ImageClickEventArgs)' with a call to
'int.Parse(string,
IFormatProvider)'. If the result of
'int.Parse(string,
IFormatProvider)' will be displayed to
the user, specify
'CultureInfo.CurrentCulture' as the
'IFormatProvider' parameter.
Otherwise, if the result will be
stored and accessed by software, such
as when it is persisted to disk or to
a database, specify
'CultureInfo.InvariantCulture'.
What exactly can go wrong if I omit specifying the culture when parsing Int32?
It means that when you read "1,234" from a data file or Database record, then try to cast it to an Int via Parse, you'll get 1234 in America and 1 in Germany. The warning gives good advice - if you're interacting with the user, specify CurrentCulture (thanks Andrew!), and if you're interacting with a filesystem or database (or anything !user), use InvariantCulture
If you are parsing an integer, it may have thousand separators, which can be "," or "." depending on the locale.

Resources