I would like to start using Parse.com to build a new application. I read the good documentation on their site but I am afraid there is something I might be missing out.
I understand that I can add DB data from the application. Assume I want to save some "note" to DB from my Android application - As I can see I am calling from the Android SDK a method that saves it into my DB:
String data = txtnote.getText().toString(); // read the note from the view
ParseObject note = new ParseObject("Notes"); // saves to notes DB
note.put(USER_NAME_KEY, username);
note.put("note", data);
note.saveInBackground(new SaveCallback()
{
#Override
public void done(ParseException e)
{
// DO SOMETHING
}
});
I am wondering whether this code is safe? It seems that if someone tries to reverse engineer my code he can actually see some information about my parse account (when I initialize the application I use APP_ID and CLIENT_KEY). If I compare it to using a REST API installed on some server then I only send the data I want to store with the authentication key for the user?
Am I missing anything? Is there a way to completely make some king of REST API on parse.com using the cloud code? without only the need to to some operations before save?
I will appreciate your answers and if you can direct me somewhere I can learn more.
APP_ID and CLIENT_KEY are just used for making a connection to parse servers, not authorization to modify your data. MASTER_KEY is the crucial and important one, and you will not have that plain in your apk, so nobody can reverse engineer your apk for it. Please see this notes on connection between client and server on parse doc site.
Yes, certainly you should move data sensitive operations to cloud code, and only do not-so-sensitive ops in your clients/apps. See this notes on implementing business logic and security related ops in cloud code using the MASTER_KEY.
Additionally, you should consider taking advantage of Class level and object level (ACL) restrictions and access permissions. When you create your data model, make sure to carefully configure their access levels.
Related
In my app I have SQLite db. I want to introduce sync between devices of my users. Firebase DB looks like an acceptable solution, but Firebase DB is cloud db at first. So, I can't use it as local db if user will reject auth dialog and let him use app, but without cloud-sync.
Now I think about combining my local SQLite db with cloud Firebase db.
For example, when user adds new row to local SQLite db, my app will also put data into Firebase DB. Other devices of this user will catch this event and update their local db. When the user uses authentification and installs app on new device, I want it to download all rows and put them into local SQLite db. That's my idea: use Firebase DB only for synchronizing data, not for storing it at device. Main reason for it is to let user use my app without authentification&synchonization. The second is that Firebase DB is not designed to be used as local db.
I'm right? Is it okay to use Firebase DB with another local DB?
Related question:
link He want the same as I want:
my plan is to offer the user the option to stay offline
If your firebase structure is not too complex you could also make a interface which defines methods like
void addData(Data data);
Data getData(long id);
void editData(Data data, long id);
void deleteData(long id);
then create 2 classes implementing that interface, one using Firebase the other using SQLite.
DatabaseImplementation
FirebaseImplementation
Inside your Firebase implementation, you would publish the data like normal, and publish one new node to something like root/requestUpdate/userId/push/ and push would contain information on where you request an update, and what deviceId published it.
Then have a ValueEventListener tied to that mentioned node, and if it gets a new child, have it look whether the deviceId is the same or not. If it is not, have the FirebaseImplementation getData using the information you got, and then use the DatabaseImplementation, to addData.
That would make sure that whenever a change is made, any other logged in client will know to update its firebase. If the client is not online, the next time he will be online he will do it as ValueEventListener triggers when it is attached. Make sure to loop through all the requested updates to make sure all are made. Also store the push keys of any updates you did complete on a local database that way you dont end up updating more than once.
Basically the firebase will always be up to date and store any changes a user made on a seperate node which is listened to by all clients.
Obviously this solution still has many problems you would need to fix, like figuring out when to delete the requestUpdate node. Logically after every user has synced but how do you determine this? ...
As for the first login, you would need to write a populateDatabaseFromFirebase() method which will do a whole lot of getDatas and addDatas. How you would do that will depend on how your DB looks. You then would store that the user has already logged in with SharedPreferences and the firebase UID.
That all being said, this will only work if your firebase is pretty flat. If you have a complex database, then everything becomes much more complicated and entangled and then it might be worth looking into an external library.
Some options for HTML5 hybrid apps
This is not what the OP asked about, but hopefully useful to some seekers.
You can use any combination of client and server database to implement storing remotely-maintained data in the device so it will be available when offline.
Some client options :
SQLite
(which is using the "native" browser database, works on iOS Safari
and Android webkit browsers)
IndexdDB
(another "native" option, but not supported in early Android, or
fully supported for iOS - so NOT a good option)
JayData
(which provides an abstraction layer from the underlying native implementation)
Lawnchair
(another popular client abstraction - I found the documentation lacking and have not used this for that reason)
Some server options :
MongoDB
RethinkDB
MySQL (for an SQL DB on the server)
and, of course there are many many more.
trying to build an Android and Web client that has Parse.com as a backend. User has to be authenticated first to log into the app. If someone gets hold of the Application keys, client keys etc. he can access the app without the authentication with Rest calls. How can this be avoided to restrict the Parse Query to return results ONLY with a user session? Looking for that security measure.
All the Parse Application and client keys (except for the master key) are considered public information and NOT secrets. This is clearly mentioned in the Parse documentation. There is no way to hide them and they will be part of your app/website and they can be easily retrieved by any user. This means any data in your classes with Public read access can be retrieved by anybody.
Parse lets you control the data read permissions ONLY via Class Level Permissions(CLPs) and Access Control Lists(ACLs). If you think these solutions cannot give you the security measures you are looking to implement, you have to disable the public read access to your data completely and implement your own Cloud Functions to retrieve the data from server. This way, you can test the user credentials, permissions, etc before returning any data.
Read Update 1 for a beter question description. Sorry about that.
I'm trying to figure out how to build a Android App and Web App that syncs there data.
I know that I should make an REST API for the MySQL database to sync with the Android App.
I have made a App before that syncs data but only for retrieval (SELECT queries) on the android side.
I now want to make a Android App / Web App that should create/update items on both platforms and syncs so both have the new/updated items. The app should also work offline.
I'm used to creating id's for most database tables as key with autoincrement. Now that I'll have 2 databases i'm not sure how to create those unique IDs. Or should I ditch those id's and use a combination of columns as primary key (with a timestamp or something).
Hope it makes sence, english is not my native language.
UPDATE 1
Narowing the question:
So i have a MySQL database with an PHP API. The API will be used by the Web App and Android App.
Question is how to handle offline data creation in de android App. If you rely on a id with autoincrement of the MySQL Database.
Example: When creating a person how to get an id for that person (If the MySQL database handles ID creation)
Thanks in advance,
Otto Vanluchene
What you're asking is a very broad question and there's a lot of options, but this is how I do it.
HOW TO HANDLE NATIVE SIDE REST CALLS:
First of all I use an HTTP library to handle my GET/POST REST API calls. It handles the callbacks and can be super helpful.
This is the one I usually use:
LoopJ's Async HTTP Callback Library
This will handle GET and POST requests with a lot of cool features such as custom timeouts, JSON format, onSuccess() and onFailure() methods, etc. There's a lot of working examples of this library too. I've used it in all my apps and haven't had any problems yet!
DATABASE SETUP:
Your going to want to create a MySQL database to store all your data. You may want to read up on common DB practices.
API SETUP
I write all my APIs in PHP, but that's just my preference. The APIs you write here will be used in your web AND mobile apps to keep things consistent. Assuming you use GET, you can just pass an argument (which I usually call "callback") that will determine what chunk of information the API will return.
For example:
http://www.ottosite.com/otto_api.php?callback=get_users
So in your PHP code, you'll have it checking if callback=get_users, and if it does, it will query the database for all the users, format the json string, then simply echo it.
This may return something like:
{"status":"success","users":["user1","user2","user3"]}
So this is obviously a JSON formatted response, then in your app, when you call that API, you just parse the response into a JSONObject (JSONArray for users) and then grab whatever data you need from it.
Hopefully this helps.
My application consists of the following activities
Activity A --> Connects to a web server and obtains a list of users. It also caches the list in the database so as to provide offline access as well as not making repetitive http requests to the server.
Clicking on item in Activity A displays Activity B which contains information related to the user. It is also cached in the database.
Currently, I decide to make the request to the server for getting the list of users only if no data is present in the database or if the onCreate method of activity A is called. Following is the code snippet for it
#Override
protected void onResume() {
super.onResume();
dbHelper = new DatabaseHelper(this);
int numOfUsers = dbHelper.numOfUsers(); //Retrieve the count of users
if (numOfUsers <= 0 || isOnCreateCalled) {
// retrieve the list of users from the server
// Update the database with the new values
} else {
// retrieve the list of users from the database
}
}
A similar approach is used to cache the user-related data present in Activity B.
I was wondering are there any better strategies than this simple approach to decide when to read data from the network and invalidate the cached database data versus when to read from the cache.
Thanks in advance.
The answer to this question will depend on the use case, but the question here is can you show stale data to the user and how important is that? If it's not that important, then what you have works great. If you'd like a more robust strategy, I would recommend using GCM, Google Cloud Messaging. With GCM, your server can send you "tickles" when there's fresh data. Your app can then respond to the "tickle" and fetch all the latest data from your server. The good thing about this is that you can keep your database up-to-date even when the user isn't running your app.
I'm not sure this kind of functionality comes built-in. There are libraries like Volley that will cache network I/O based on the parameters you set. However, you're best bet is probably to build your own solution, use something along the lines of HTTP headers, Entity Tags, etc. Maybe you can always make a request to the server for some tiny serialized data, compare the results, and determine from there whether or not to make additional requests.
Short answer: there's lots of ways!
I'm actually a beginner in android and needs a lot of help. I have made an app with embedded database and now want to put it onto some dynamic location. Have simple form of data (some addresses and branch information etc). I actually have no idea about how to use a dynamic server placed on dynamic location.
How can I do this? Please guide me stepwise
I browsed and found some terms like "write Service", "Close/open back-ends" etc. Kindly do guide me. Another question that I have is: do I need some kind of registration, api-key or any other thing. I just added the "google plugins" for eclipse and I can create App engine connected with Android App
Yes you do need a key. Look at this http://developer.android.com/google/gcm/gs.html
First, we need to send data to/from the client for the example you set up (App engine connected with Android App) using
com.google.android.gcm.server.Sender helper class
Again, that helper class is step #4 and how to use it is in Writing the Server-side Application Server-side Application
Naturally then you want to persist or look up data. You can do that in the whatever class is used to send/receive messages (which of course uses the Sender helper class above)
Then the easiest and maybe best way for AppEngine if you are using Java is to use Objectify. Trust me or google it to see how good it is. https://code.google.com/p/objectify-appengine/
The docs for Objectify are really good and I didn't really have any trouble the first times.
Their simple example is:
#Entity
class Car {
#Id String vin; // Can be Long, long, or String
String color;
}
ofy().save().entity(new Car("123123", "red")).now();
Car c = ofy().load().type(Car.class).id("123123").get();
ofy().delete().entity(c);
I think you are good to go.
Summary:
YourMessageClass (on Appengine)
-- uses com.google.android.gcm.server.Sender to send/recieve data
-- uses Objectify to persist data.
The next question is where are you putting YourMessageClass. Will it be in a Servlet that is handling a short-lived request? (https://developers.google.com/appengine/docs/java/runtime#Requests_and_Servlets) Will it be in a long-running backend? (https://developers.google.com/appengine/docs/java/backends/) but that is beyond the scope of this discussion.