My CO-worker has created the below code for iOS to make a user defined string SQL search safe.
i.e to remove the possibility of SQL-injections and that kind of thing
char * sqlSafeQuery = sqlite3_mprintf("%q",[searchTerm UTF8String]);
searchTerm = [NSString stringWithFormat:#"%s", sqlSafeQuery];
sqlite3_free(sqlSafeQuery);
Is there a way in android to so something similar? I can't see much on the Google's :)
Thanks.
You may use prepared statements, see an Android question on how to use these in sqlite. As the statement is parsed without the user input in it, the parameters cannot change the statement itself; thus the injection cannot happen.
Related
While I was trying the following SQL command , I got sql error.
INSERT INTO exampleTbl VALUES('he doesn't work for me')
where doesn't contain the apostrophe.
What is the way to insert text having ' (apostrophe) into a SQL table.
In SQL, the way to do this is to double the apostrophe:
'he doesn''t work for me'
However, if you are doing this programmatically, you should use an API that accepts parameters and escapes them for you automatically. Programmatically escaping and using string concatenation to assemble a query yourself is a sure way to end up with SQL injection vulnerabilities.
INSERT INTO exampleTbl VALUES('he doesn''t work for me')
If you're adding a record through ASP.NET, you can use the SqlParameter object to pass in values so you don't have to worry about the apostrophe's that users enter in.
$value = "he doesn't work for me";
$new_value = str_replace("'", "''", "$value"); // it looks like " ' " , " ' ' "
INSERT INTO exampleTbl (`column`) VALUES('$new_value')
try this
INSERT INTO exampleTbl VALUES('he doesn''t work for me')
insert into table1 values("sunil''s book",123,99382932938);
use double apostrophe inside of single apostrophe,
it will work
I know the question is aimed at the direct escaping of the apostrophe character but I assume that usually this is going to be triggered by some sort of program providing the input.
What I have done universally in the scripts and programs I have worked with is to substitute it with a ` character when processing the formatting of the text being input.
Now I know that in some cases, the backtick character may in fact be part of what you might be trying to save (such as on a forum like this) but if you're simply saving text input from users it's a possible solution.
Going into the SQL database
$newval=~s/\'/`/g;
Then, when coming back out for display, filtered again like this:
$showval=~s/`/\'/g;
This example was when PERL/CGI is being used but it can apply to PHP and other bases as well. I have found it works well because I think it helps prevent possible injection attempts, because all ' are removed prior to attempting an insertion of a record.
yes, sql server doesn't allow to insert single quote in table field due to the sql injection attack. so we must replace single appostrophe by double while saving.
(he doesn't work for me) must be => (he doesn''t work for me)
you can use backslash '\' if you want to display a single quote in your text.
INSERT INTO exampleTbl VALUES('He doesn(\')t') ;
I want to create a simple search in my app, but cannot find anything on interwebs about it, that's more recent than 2014. There must be a better way. There are startAt and endAt functions but they don't work as expected and are case sensitive. How do you guys solve this problem? How can this functionality still not exist in 2016?
In my case I was able to partly achieve a SQL LIKE in the following way:
databaseReference.orderByChild('_searchLastName')
.startAt(queryText)
.endAt(queryText+"\uf8ff")
The character \uf8ff used in the query is a very high code point in the Unicode range (it is a Private Usage Area [PUA] code). Because it is after most regular characters in Unicode, the query matches all values that start with queryText.
In this way, searching by "Fre" I could get the records having "Fred, Freddy, Frey" as value in _searchLastName property from the database.
Create two String variables
searchInputToLower = inputText.getText().toString().toLowerCase();
searchInputTOUpper = inputText.getText().toString().toUpperCase();
Then in the Query set it to:
DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("Products");//Your firebase node you want to search inside..
FirebaseRecyclerOptions<Products> options =
new FirebaseRecyclerOptions.Builder<Products>()//the Products is a class that get and set Strings from Firebase Database.
.setQuery(reference.orderByChild("name").startAt(searchInputUpper).endAt(searchInputLower + "\uf8ff"),Products.class)
.build();
the "name" it's the node inside the Products Main Node.
the .startAt(searchInputUpper) & .endAt(searchInputLower + "\uf8ff") to make the search as contains all characters that typed in the inputText.getText() that you get.
finally I got it you can use where clause to get you result like SQL
LIKE keyword like% or %like
syntax :
Firestore.collection(collectionName).orderBy(field).where(field, ">=", keyword.toUpperCase()).where(field, "<=", keyword.toUpperCase() + "\uf8ff").get()
I my case used:
var query = 'text'
databaseReference.orderByChild('search_name')
.startAt(`%${query}%`)
.endAt(query+"\uf8ff")
.once("value")
In this way, searching by "test" I could get the records having "Test 1, Contest, One test" as value in 'search' property from the database.
Firebase is noSQL therefore it does not have searches built in like you'll find in SQL. You can either sort by values/key or you can equalto
https://firebase.google.com/docs/database/android/retrieve-data
You can find examples at the link above. That is the latest documentation for firebase.
If you are looking for SQL like searches. Then take a look at elastic search. But that will increase the complexity since you need a platform to put it on. For that i could recommend Heroku or maybe GoogleCloudServers
Here is a blog post about advanced searches with elastic search
https://firebase.googleblog.com/2014/01/queries-part-2-advanced-searches-with.html
This question might be old but there is a documented way of how to achieve this way, It is simple to implement. Quoted:
To enable full text search of your Cloud Firestore data, use a third-party search service like Algolia. Consider a note-taking app where each note is a document:
Algolia will be part of your firebase functions and will do all the searches you want.
// Update the search index every time a blog post is written.
exports.onNoteCreated = functions.firestore.document('notes/{noteId}').onCreate(event => {
// Get the note document
const note = event.data.data();
// Add an 'objectID' field which Algolia requires
note.objectID = event.params.noteId;
// Write to the algolia index
const index = client.initIndex(ALGOLIA_INDEX_NAME);
return index.saveObject(note);
});
To implement the search, the best way is to use instant search - android
Sample Search Image: GIF
The feature you're looking for is called full-text search and this is something most databases (including Firebase) don't provide out-of-the-box because it requires storing the data in a format that's optimized for text search (vs optimized for filtering) - these are two different problem sets with a different set of trade-offs.
So you would have to use a separate full-text search engine in conjunction with Firebase to be able to do this, especially if you need features like faceting, typo tolerance, merchandizing, etc.
You have a few options for a full-text search engine:
There's Algolia which is easy to get up and running but can get expensive quickly
There's ElasticSearch which has a steep learning curve but uber flexible
There's Typesense which aims to be an open source alternative to Algolia.
I don't know about the certainty of this approach but using the firebase version 10.2.6 on android, i get to do something like this:
firebaseDatabase.getReference("parent")
.orderByChild("childNode")
.startAt("[a-zA-Z0-9]*")
.endAt(searchString)
It seems to work well sometimes
Finally joined SO just to answer this.
For anyone coming here from/for the python firestore.client here's a solution that seems to work for me.
It's based on the accepted answer's concept but via the client rather than db.reference() and mixed with the answer from user12750908.
from firebase_admin import firestore
users = db.collection("users")\
.order_by("last_name")\
.where("last_name", ">=", last_name.upper())\
.where("last_name", "<=", last_name.lower() + "\uf8ff")\
.stream()
It works for the simple test I did, but I'll update my answer if I have issues with it later. And just a reminder, this is similar to
LIKE search%
and not
LIKE %search%.
Edit 1
I didn't see any tags for the question, but the title attribute mentions Android so this may not necessarily answer the question directly, but if you have a python API, this should work. I'm unfortunately not sure if there's an equivalent client/db separation in the Android version like there is in the Firebase Admin for Python. I didn't want to delete the answer since I hadn't seen any answers for firestore client during my search for a similar answer and hope it helps anyone else stumbling around.
Edit 09-03-2020 This works a portion of the time it seems. Most of the time I didn't seem to have an issue, but when I applied it to another project I was getting unexpected results. Long story short you may need to replicate how you save the data you're comparing against. For example, you may need to have a field to save the last_name in all caps and another field to save it in all lowercase, then you change the first where clause to compare last_name_upper and the second to compare last_name_lowercase. In my second project so far this seems to yield more accurate results so you may want to give that a try if the previous answer doesn't work well
EDIT 09-07-2020 Previous edit from 09-03-2020 is partially accurate. During my haste of thinking I had it fully resolved I completely forgot firebase doesn't let you use <, >, <=, >= across different fields. You may need to do two queries and merge them, but you'd probably still be reading more docs than you really intend. Doing the comparison against either the upper or lower version with the appropriate search term seems to give the original results expected from the original answer. For example:
.orderBy("last_name_upper")
.where("last_name_upper", ">=", this.searchForm.text.toUpperCase())
.where("last_name_upper", "<=", this.searchForm.text.toUpperCase() + "\uf8ff")
As firebase documentation, firebase doesn't support full text search.
But to do that you can use third-party tools.
Check this link to learn more https://firebase.google.com/docs/firestore/solutions/search
I need to work with a persistent String Array (n Rows, 1 column).
* On first running the app, the String Array needs to be created empty.
* On subsequent app executions the Array will be populated from a File and the contents need to be available throughout the rest of the app.
* As the app is executed, the Array needs to be able to 'grow' in row count
* As the app is executed, the Array rows need to be able to grow in length
* The user will have the option to Clear the Array of previous entries.
* At the end, the String Array contents will be written back to a File.
I find a lot of references to Putting and Getting from an existing SharedPreferences String[] but, in the newness of my Android development, I am struggling with how to proceed.
EDIT Follows...
The data itself suggests using an Array
Example:
MAIN ST. F55 63 KY08:57 12142015--------KY11:24 12142015345TMH KY13:57 12142015
MAIN ST. F56 WYE123 IN08:57 12142015--------KY11:24 12142015--------KY13:57 12142015
1ST ST. F57 --------KY08:57 12142015--------KY11:24 12142015789FPF KY13:57 12142015
1ST ST. F58 456FPF KY08:57 12142015998FPF KY11:24 12142015--------KY13:57 12142015
1ST ST. F59 789TTM KY08:57 12142015--------KY11:24 121420151234DG KY13:57 12142015
I first need to have this data in a File
Then in one GUI I check for the existence of the file.
If one exists, fine
If none exists, I create one.
Then, in subsequent GUI's, I must check for the existence of parameters
If they do not already exist, add them to the existing data lines.
If they already exist, notify the user
And so on and on.
Then when all of the current 'pass' data has been collected via multiple, separate GUI's, I have to write out the whole data-set into the file.
My reason for thinking that I need a SharedPreference approach is the need to find and check data from GUI to GUI as the user progresses through the app.
If that 'belief' is wrong, I am open to better approach suggestions.
EDIT 2 follows....
On further study of web references, I am beginning to think that perhaps the best approach for this data and how the data needs to change might be to use a SQLite approach. Any ideas about this?
Any assistance/suggestions you might have would be greatly appreciated.
i would discourage you from using sharedpreferences for anything else than preferences. means things that change rarely - really rarely and are really lightweight. do not put much data in there. less is better. the data structures underlying sharedpreferences are not a database.
another note. it is not a string list, but it would be a string set. sets are not necessarily ordered, nor do they necessarily keep their order. means - it is not rows. its a collection of strings that can come back in any fun order (usually there is some, but that depends on the implementation which i do not know)
now you could go and make your own list, your own data structure, save it into a string and read it out, use json to do exactly that or something similar, or better - use a database, which would exactly do that.
http://developer.android.com/training/basics/data-storage/databases.html
explains it, but as you'll see its something that might take some time.
now dont get me wrong, but i have to warn you about the following approach. it is valid, but has many problems and is far from thread safe. it will not be a problem as long as you only open it from the ui thread and do not keep anything in memory to cache - if you do it will create lots of problems.
your problem of adding a line and clearing can be solved by using a file. just a simple file
look here
http://developer.android.com/training/basics/data-storage/files.html#WriteInternalStorage
the change is to append when writing:
openFileOutput("filename", Context.MODE_APPEND);
see the context mode? now you can basically just write one line and append every time.
if you wanna clear the file, just deleteFile("filename")
this is as said not threadsafe, but can be a viable option if used carefully.
Please follow this step to achieve what you want with sharedPreference
create the class Parent for SharePreference
Create your empty Array
Convert Your empty array to String and put it on SharedPreference
to call your empty array from sharedPreference
Call your sharedPreference using your key
Convert the String to array
You get your array from the sharePreference
Hope it helps, and maybe this link will help you :
http://www.androidhive.info/2012/08/android-session-management-using-shared-preferences/
You can use my open-source library called prefser, which solves this problem and uses SharedPreferences and Gson under the hood. It's basically wrapper for default Android mechanism.
You can use it in the following way:
Prefser prefser = new Prefser(context); // create Prefser object
prefser.put("key", Arrays.asList("one", "two", "three")); // save array of Strings
String[] value = prefser.get("key", String[].class, new String[]{}); // read array of Strings
For more information check repository of the project, tests and README.md file.
Link: https://github.com/pwittchen/prefser
Please note, SharedPreferences have some limitations and shouldn't be used for storing large amount of data. If you expect a lot of data, consider using SQLite database or another type of database (e.g. with NoSQL or similar approach if you strive for simplicity).
OK, based on the data, how it needs to be manipulated and the pros and cons of using a SharedPreferences approach, I have decided to go with a SQLite approach.
With that approach I should be able to readily check:
* if the necessary table exists (if not create it)
* if the necessary Field1 + Field2 exists (if not create a new record)
* and I will be able to modify the record's Field3 contents as needed
Then when the user's actions are complete I can convert the SQLite table 'records' into strings and write them out as a File and then either DROP or PURGE the associated SQLite table (until needed next time).
I sincerely appreciate all of your suggestions.
Thank you.
I am using ormlite for database operations in my Android app. I want to update around 1000 records at a time. But, if these records have any special characters such as ' / \ % , I am getting the following exception.
java.sql.SQLException: Problems executing Android statement: UPDATE `staticresource`
SET `Content` = 'Tick next to member and add by clicking on \'Invite Selected\'
button to create invite list.' ,`Id` = '3' WHERE `Alias` = 'tm'
So, how to update these records optimally. Thanks in advance.
You can escape special character's using
DatabaseUtils.sqlEscapeString();
String updateString = DatabaseUtils.sqlEscapeString("Tick next to member and add
by clicking on \'Invite Selected\' button to create invite list.");
updateString can be pass to ormlite update method.
How to update these records optimally.
The right thing to do is to use the UpdateBuilder combined with a SelectArg (which is a poor name). The SelectArg will use the ? SQL feature in which case your string can include special characters without issue.
UpdateBuilder ub = dao.updateBuilder();
updateBuilder.where().eq("Alias", "tm");
updateBuilder.updateColumnValue("Content",
new SelectArg("... on \'Invite Selected\' button to ..."));
updateBuilder.update();
This will generate something like:
UPDATE `staticresource` SET `Content` = ? WHERE `Alias` = 'tm'
And it will set the ? value to be your string. You don't need to worry about escaping anything. This is also how you protect user input from SQL injection attacks.
I am new to both Android and Stack Overflow. I have started developing and Android App and I am wondering two things:
1) Is it possible to parametrize a TextView? Lets say I want to render a text message which states something like: "The user age is 38". Lets suppose that the user age is the result of an algorithm. Using some typical i18n framework I would write in my i18n file something like "The user age is {0}". Then at run time I would populate parameters accordingly. I haven't been able to figure out how to do this or similar approach in Android.
2) Let's suppose I have a complex object with many fields. Eg: PersonModel which has id, name, age, country, favorite video game, whatever. If I want to render all this information into a single layout in one of my activities the only way I have found is getting all needed TextViews by id and then populate them one by one through code.
I was wondering if there is some mapping / binding mechanism in which I can execute something like: render(myPerson, myView) and that automatically through reflection each of the model properties get mapped into each of the TextViews.
If someone has ever worked with SpringMVC, Im looking for something similar to their mechanism to map domain objects / models to views (e.g. spring:forms).
Thanks a lot in advanced for your help. Hope this is useful for somebody else =)
bye!
In answer to #1: You want String.format(). It'll let you do something like:
int age = 38;
String ageMessage = "The user age is %d";
myTextView.setText(String.format(ageMessage, age));
The two you'll use the most are %d for numbers and %s for strings. It uses printf format if you know it, if you don't there's a quicky tutorial in the Formatter docs.
For #2 I think you're doing it the best way there is (grab view hooks and fill them in manually). If you come across anything else I'd love to see it.