How structure a SQLite database for offline support? - android

I'm trying to give the offline support in my app, so user can read the information without the internet also. I'm creating an app to show some packages from different companies. I have created my API and following database in the remote server.
companies -- id, name
duration-- id, type (type could be, monthly, weekly, yearly)
packages -- id, name, company_id, duration_id
My API is returning result as
{
"id":3,
"package":"premimum",
"company_id":6,
"duration_id": 5,
}
Now I want to store all information fetched from the API to the local database SQLite. Now I want to know how I should structure my local database? should I structure same as the remote database? should I create the three tables in the local database SQLite same as?
companies -- id, name
duration-- id, type (type mean package duration, monthly, yearly, daily)
packages -- id, name, company_id, duration_id
If yes then id will be different in local database and in the remote database, because both databases will generate own primary key how I can handle this? or something you can suggest me to keep the same ID? or should I keep the id different?

You don't necessarly need the internal Ids on your local database to match those of your cloud server database. For instance, if you use Parse as cloud server, Parse will generate its own internal object ID. Your app does not need to know them.
Having said that, I strongly suggest you have a common key attribute between your local object and cloud object, so that you can keep them synced.
For example you could add a package_id attribute on both your local and cloud object. This package_id will be the same on both side, so that you can update your local object when the remote object is updated and vice-versa.
For example, here is the code to create an object on the Parse server:
ParseObject gameScore = new ParseObject("GameScore");
gameScore.put("score", 1337);
gameScore.put("playerName", "Sean Plott");
gameScore.put("cheatMode", false);
gameScore.saveInBackground();
You can them retrieve this object from the app as follows:
ParseQuery<ParseObject> query = ParseQuery.getQuery("GameScore");
query.getInBackground("xWMyZ4YEGZ", new GetCallback<ParseObject>() {
public void done(ParseObject object, ParseException e) {
if (e == null) {
// object will be your game score
int score = object.getInt("score");
String playerName = object.getString("playerName");
boolean cheatMode = object.getBoolean("cheatMode");
} else {
// something went wrong
}
}
});
I suggest you read the documentation for more infos on storing object on a Parse server:
https://docs.parseplatform.org/android/guide/
Also, this lib could help you to sync data between local database and a Parse server:
https://github.com/ntoskrnl/DataSync

Related

How apply sql query to Firebase in Xamarin Android?

I need get return data from Firebase. In Sql query it would be like this:
Select * from * Group By field1, field2 HAVING count(*)=1
How to apply above to FireBase in Xamarin Android. So I have node "chats", here I want retrieve record only not repeated on field "user_email":
chats
|-...
|---date_and_time:
|---user_email:
|-...
|---date_and_time:
|---user_email:
...
at this moment I get whole data from "chat", here code:
public List<MessageContent> listOfContacts = new List<MessageContent>();
FirebaseClient firebase;
...
firebase = new FirebaseClient(GetString(Resource.String.database_name));
...
var firebaseContacts = await firebase.Child("chats")
.OnceAsync<MessageContent>();
foreach (var item in firebaseContacts)
listOfContacts.Add(item.Object);
Firebase's realtime database is a NoSQL database. Trying to directly map a SQL query to it is going to give you a rough time. I highly recommend reading NoSQL data modeling and watching Firebase for SQL developers.
In NoSQL databases you typically get more complex write operations and in return get more performant/scalable read operations. So in your case, that could mean that you actually store a list of the records that you're trying to query and update that list with every write.
Some previous questions that deal with similar scenarios can be found in this list.

Google App Engine - Datastore - Get an entity, not by it's key

I'm building an Android app, and I'm using Google App Engine to store user's data. I want users to be able to connect from other devices to their account, but I could not figure how.
The users table (kind) has 4 properties: id, email, nickname and level:
I have read this:
https://cloud.google.com/appengine/docs/standard/java/datastore/creating-entities
It's written their that I can only get entities by their key, and it's a problem for me, because in a new device, I can only get the user's email, not the key and Id. I need to get the key and id by their email.
Is this possible?
If it's not, is their any other solution?
You just need to do a simple query. What language are you using in the GAE backend? For example, in Python, you would do something like:
def get_user_by_prop(prop, value):
this_user = User.query(getattr(User, prop) == value).get()
return this_user
Judging from the link in your question, I assume you are using Java? Here are the docs for a query: https://cloud.google.com/appengine/docs/standard/java/datastore/retrieving-query-results
where they use the example:
Query q =
new Query("User")
.setFilter(new FilterPredicate("nickname", FilterOperator.EQUAL, "billybob"));
PreparedQuery pq = datastore.prepare(q);
Entity result = pq.asSingleEntity();
What is stored at the id property? Does it have some meaningful value or just random unique number to be used as a unique identifier?
It seems like you can design your database differently so the email address would be your unique identifier. In that case, you will have a User table contains the following properties:
email (your unique identifier), nickname and level.
That way you will be able to use the following code snippet:
Key userEmail; //Get user's email
Entity user = datastore.get(userEmail);
Regardless of that, you are still able to access your entity without the need for the entity's key, by using a query. That way you won't be using the entity's key in order to get its instance but you would rather get the desired entity by using the given property value and finding the matching entity with that property value.
The query would look something like that:
String userEmail; //Get user's email
Filter propertyFilter =
new FilterPredicate("email", FilterOperator.EQUAL, userEmail);
Query q = new Query("User").setFilter(propertyFilter);
PreparedQuery pq = datastore.prepare(q);
try {
Entity user = pq.asSingleEntity()
//Same as Entity user = datastore.get(userEmail) mentioned above
} catch (TooManyResultsException e) {
// If more than one result is returned from the Query.
// Add code for dealing the exception here
}

How to save more then one row in database using parse

I am new to parse SDK services using Android Studio and I have to ask that how to store more than one row in parse database . I am using back4app parse server whenever I want to put data on data base I.e more than one row then it does not store the first row but the second one as from the code below
ParseObject obj = new ParseObject("Table");
obj.put("Name","John");
obj.put("Score","40");
obj.put("Name","Jack");
obj.put("Score","50");
obj.saveInBackground();
So when I run app then only name and score for Jack stored in database creating one row and I want rows for both John and Jack, Kindly help me resolving this issue
You override your object fields ("name" and "score"), i.e. you delete John before save. Make a method that save your person:
private void savePerson(String name, String score){
ParseObject obj = new ParseObject("Table");
obj.put("Name",name);
obj.put("Score",score);
obj.saveInBackground();
}
and in code where you want to save person, call created method to do that:
savePerson("John", "40");
savePerson("Jack", "50);

Saving locally stored parseobject to cloud

I am trying to save some data to parse cloud using this code:
ParseObject po=new ParseObject("Gamescore");
po.put("score",myscore);
po.saveInBackground();
I am successful in saving this object to parse cloud.But I need to store it locally first and then at sometime when user clicks a button, the parse object must update the table in the Parse Cloud and save it self in the cloud.Please don't consider the code as any game scenario,it is just an example,I am using.
I tried to understand parse.com documentation but it is not so much helpful.
Using local datastore https://parse.com/docs/android_guide#localdatastore
You can do something like:
ParseObject po=new ParseObject("Gamescore");
po.put("score",myscore);
po.pinInBackground(); // now it is saved locally
Then later when user press a button
ParseQuery<ParseObject> query = ParseQuery.get("Gamescore")
.fromLocalDatastore()
.findInBackground(new FindCallback() {
public void done(List<ParseObject> objects, ParseException e) {
// all Gamescores pinned locally
for (ParseObject score: objects) {
// keep in local database till successfully saved online
score.saveEventually();
}
}
});
Instead of saveEventually() you could of course also simply do saveAllInBackground() which is more efficient if you have many objects, but then it will timeout at some point if there is no internet connection.

Android - Best way to sync SQLite with MySQL [duplicate]

This question already has answers here:
Synchronizing client-server databases
(6 answers)
Closed 8 years ago.
I'm working on a project containing web app and mobile app which records daily user's data. User are able to delete, update their data and they can use many devices to insert data.
I intend to develop this way:
User enter their data and then insert to SQLite. A service will start periodically (each 5hr or sth) to sync with MySQL using timestamp.
I did search for a sample using service and timestamp on the internet but I found nothing. It would be great if there are a sample or tutorial.
I'm new at Android and I have no idea what is the best way to develop an app like this. Thanks in advance.
----EDIT----
I consider using timestamp or synced. Which is more effective?
you could use volley library by google or any alternative libraries, it depends on how you want to send the data, the best approach is that you use JSON to make your life easier, get the data from sqlite that you like to sync with your backend and send it over JsonObjectRequest using volley, for example your request can look like this
jsonObjectRequest postForm = new JsonObjectRequest(Request.Method.POST, URL, YourJsonData,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// here you can get your response.
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// here you can tell there is something went wrong.
}
});
u could add a new value which indicates whether the value has been sync or no from your local database. for example, lets say you have a table called student and this table has three columns which are ID, NAME and synced in above code when your response return success update that row synced column with true|false which indicates whether this row synced with your backend or no. and to get the data from your database you should do something like this.
public String getStudents() {
List<Student> students = new ArrayList<Student>();
String query = "SELECT * FROM student WHERE synced = 0";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
if (cursor.moveToFirst()) {
do {
Student st = new Student();
st.setId(cursor.getString(cursor.getColumnIndex(ID)));
st.setName(cursor.getString(cursor.getColumnIndex(NAME)));
st.setSynced(cursor.getInt(cursor.getColumnIndex(SYNCED)));
students.add(st);
} while (cursor.moveToNext());
}
db.close();
return new Gson().toJson(students);
}
The esieast way AFAIK is to use a lib like http://loopj.com/android-async-http/ or volley lije k0sh says to send data to a PHP script that will manage you mysql data.
You'll have to write a php( or java) script in your server to receive your data ( You should write a REST API)
To select your HTTP lib, you should look here:
What is the most robust HTTP library for android?
You should really care about how you are going to sync your datas, because it could drain your battery.
Here you will learn how to optimize your updates:
https://developer.android.com/training/efficient-downloads/index.html
Hope it helps!

Categories

Resources