Parse local store for an App - android

Hi I am doing an android app that has a 3 different parse classes. Is there a way to store all the info from this classes in the local data store and sync them every time the app opens? (I just need to read the info from the server the app doesn't change any of the info of the db.) Also do I have to initialize the local data store in all the activities or only in the one that I get the info from the server? code samples would be appreciated. (I already read the documentation in parse.com but I am still confused in how the local data store works.)
Thanks

Yes, you can have all the data related to each class as local store inside your application ,and you can sync data with server.
To do this, you need to create a Application class in your project add Parse.enableLocalDatastore(getApplicationContext()); among other properties recommended by Parse.com such as Parse.initialize(this, "YOUR_APP_ID", "YOUR_CLIENT_KEY");
So this is a one time thing and local data store will work.
But to saving data specific for each class, you need to query data from Parse database and pin it to the local database.
Basically it happens like this
saveButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
todo.setTitle(todoText.getText().toString());
todo.setDraft(true);
todo.setAuthor(ParseUser.getCurrentUser());
todo.pinInBackground(TodoListApplication.TODO_GROUP_NAME,
new SaveCallback() {
#Override
public void done(ParseException e) {
if (isFinishing()) {
return;
}
if (e == null) {
setResult(Activity.RESULT_OK);
finish();
} else {
Toast.makeText(getApplicationContext(),
"Error saving: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
});
}
});
to sync only the latest data, you need to have a flag to recognize whether that data is already synced or not in your class.(as in the todo.setDraft(true); in this sample).
TodoListApplication.TODO_GROUP_NAMis the unique constant to identify the class specific for each local table. since this is saved in local data store, now you can query even without network connection to retrieve data.
ParseQueryAdapter.QueryFactory<Todo> factory = new ParseQueryAdapter.QueryFactory<Todo>() {
public ParseQuery<Todo> create() {
ParseQuery<Todo> query = Todo.getQuery();
query.orderByDescending("createdAt");
query.fromLocalDatastore();
return query;
}
};
Hope this helps

Related

Android. Parse.com: array is not updating

On every launch my app loads fresh data from parse.com and pins all objects to use app without network requests like this^
public void pinKids() {
ParseQuery<ParseObject> query = ParseQuery.getQuery(ParseConstants.CLASS_KIDS);
query.whereEqualTo(ParseConstants.KEY_PARENT, currentUser);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(final List<ParseObject> kidsList, ParseException e) {
if (e == null) {
ParseObject.unpinAllInBackground(ParseConstants.LABEL_KIDS, new DeleteCallback() {
#Override
public void done(ParseException e) {
ParseObject.pinAllInBackground(ParseConstants.LABEL_KIDS, kidsList, new SaveCallback() {
#Override
public void done(ParseException e) {
Log.d("Hello", "pinKids");
}
});
}
});
}
}
});
}
One of the columns in my class is an array of strings (it stores history messages). I found that my code doesn't refresh this array if that array was updated from the other device (the same user did something on the other device). The rest of the data (other columns) refresh without problems. But the array of strings stays as it was downloaded at first launch.
In parse.com dashboard I see that array is updated. But code doesn't download this array while all the other columns are downloaded correctly.
Let me say that when I update this array on device-1 the new data is stored on device-1 and on "parse.com" too. But it doesn't update on device-2.
Please help!
OK! I've solved it.
This problem is a bug of parse.com.
I've created an issue on parse's github.
So I found that my problem is a part of parse's bug.
So the answer is: replace all calls to getJSONArray(key) with getList(key). You might also need revert()/revert(key)

Update entry(existing row) in microsoft azure database through android application

I am making an android application with database connectivity through Microsoft Azure. I have successfully created table in Azure and connected it to my application.I have used SQL management studio(2014) for creating Database. I am also able to enter data to the table by my application, according to the methods specified in Microsoft Azure mobile services, but I am facing problem in updating my database. I entered information to my database at one point in the app. At later stage I need to enter data to other columns corresponding to the previous entry (i.e updating existing row), which I am not able to do. The solutions available are not helping me to obtain my goal. Please tell me the exact code(java) which I need to write in my android application or procedure which I should follow to update properly. Thanks.
The following code shows how to update data in a table. In this example, item is a reference to a row in the ToDoItem table, which has had some changes made to it. The following method updates the table and the UI adapter.
private void updateItem(final ToDoItem item) {
if (mClient == null) {
return;
}
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
mToDoTable.update(item).get();
runOnUiThread(new Runnable() {
public void run() {
if (item.isComplete()) {
mAdapter.remove(item);
}
refreshItemsFromTable();
}
});
} catch (Exception exception) {
createAndShowDialog(exception, "Error");
}
return null;
}
}.execute();
}
For further queries visit :https://azure.microsoft.com/en-us/documentation/articles/mobile-services-android-how-to-use-client-library/#updating

ParseQuery gives 0 objects when querying from local datastore even after successfully pinning

I am using the Android SDK of parse.com and have arrived at a peculiar problem.
From a fragment's onCreate:
Fetch an object from the server.
Pin it.
Fetch an object from the local datastore.
Here is a snippet of the code from the onCreate:
ParseObject myChatGroup = ParseObject.createWithoutData("ChatGroup", "mOJGWRiLPC");
myChatGroup.fetchInBackground(new GetCallback<ParseObject>() {
#Override
public void done(ParseObject chatGroup1, ParseException e) {
if (e == null) {
l.d("Fetched chat group: " + chatGroup1 + " from server");
chatGroup1.pinInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
l.d("Successfully pinned chat group");
ParseQuery<ParseObject> chatGroupParseQuery = new ParseQuery<>("ChatGroup");
chatGroupParseQuery.fromLocalDatastore()
.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> list, ParseException e) {
if (e == null) {
l.d("Found " + list.size() + " chat groups from local datastore");
} else {
e.printStackTrace();
}
}
});
} else {
e.printStackTrace();
}
}
});
} else {
e.printStackTrace();
}
}
});
Here is the log:
Fetched chat group: ChatGroup { objectId: mOJGWRiLPC, name: Admin } from server
Successfully pinned chat group
Found 0 chat groups from local datastore
But this doesn't make any sense! I just pinned an object so how can there be 0 objects in the local datastore. The code is so simple. What am I doing wrong? Could it be a bug with the SDK?
Any insight will be much appreciated I have been trying to find the issue for days now.
The Parse setup looks fine to me:
ParseObject.registerSubclass(ChatGroup.class);
Parse.enableLocalDatastore(this);
Parse.initialize(this, AppProps.properties.appId,
AppProps.properties.clientKey);
ParseUser.enableRevocableSessionInBackground();
Parse.setLogLevel(Parse.LOG_LEVEL_DEBUG);
Note:
It works fine when trying the same logic with the ParseUser object. And even other classes of mine like my Message which leads me to suspect that something is wrong with my ChatGroup class.
I have added two fields to my ChatGroup class on the parse.com data browser: name(String) and messages(Relation) with read and wrote access to a role called Admin.
When browsing to the actual parse db (using root access) I find that the database table (ParseObjects) does contain the row that I pinned. But somehow parse shows 0 results on querying it!
Parse doesn't seem to support ACLs on local datastore. So the easiest way to get around this issue is to do ignoreACLs() on the query -- assuming you do have roles/acls setup correctly on the server side, so whatever you have pinned locally should be OK permission-wise already.
I found the issue. It seems to be more like a bug with the Android SDK of parse. I narrowed it down to an issue with retrieving pinned objects with special ACLs using the Android SDK.
Initially, the object had the ACL such that only the role 'Admin' (that I created) can read and write. The funny thing is that the user with which I was testing the pinning and querying was an 'Admin'! But, when I changed the ACL such that public can read but only Admin can write, the problem was resolved!
My theory was that querying the local datastore behaves like a public query, no matter what role the user that is making the query has! But if any other theory explaining this would be appreciated. Luckily, in my case I need public read access, but this bug can be a huge downfall for some who need to have read access restricting ACLs! Hopefully parse.com will fix this issue soon.
This is quite a big issue! I am surprised that I couldn't find a question regarding this issue.
Yeah so basically you have to set ACL for current user and pin it before you pin the chat group.
ParseACL acl = new ParseACL();
acl.setReadAccess(ParseUser.getCurrentUser(), true);
ParseUser.getCurrentUser().setACL(acl);
ParseUser.getCurrentUser().pinInBackground();

Uploading Multiple Images to parse.com online database

I am having a problem with Parse.com online database . In my app I need to upload multiple images to the Parse.com database.At this moment I am able to upload single image to parsefile and save it to parse object.Please suggest some answers.
I didn't tried with images, but the saveAllInBackground worked for me. Although I'm having problems getting the objects Ids after the process complete.
Try this:
ParseObject.saveAllInBackground(objectsToUpload, new SaveCallback() {
#Override
public void done(ParseException e) {
if ( e == null )
{
//success
}
} else {
//error
}
}
});
It's worth mentioning that the objectsToUpload is an ArrayList of ParseObjects.
As I said the operation worked, but I couldn't manage to get the objectsId from the objects uploaded

Saving data into Parse.com cloud for another user

I have an app which works with users, and offers the possibility to follow certain users, at the current user choice.
Unfortunately, I don't know how to modify data of a user which is not the current user. I have not seen anything like that stated in the Parse.com docs(or i missed).
I have a column in my database in "Users" class called "usersFollowed" and when the current user clicks "Follow" i want to add the current user to the "usersFollowed" list, but adding them like you will see in the following code does not work.
Follow user code:
dialog = ProgressDialog.show(context, "",
"Following...", true);
viewHolder.userFollow.setSelected(true);
viewHolder.userFollow.setText("FOLLOWING");
ParseQuery<ParseUser> userListQuery = ParseUser.getQuery();
userListQuery.whereEqualTo("screenName", parseUserList.get(position).get("screenName").toString());
userListQuery.findInBackground(new FindCallback<ParseUser>() {
#Override
public void done(List<ParseUser> parseObjects, ParseException e) {
parseUserFollowedList = new ArrayList<>();
if (parseObjects.get(0).getList("usersFollowed") == null) {
parseUserFollowedList.add(ParseUser.getCurrentUser());
parseObjects.get(0).addAll("usersFollowed", parseUserFollowedList);
} else {
parseUserFollowedList = parseObjects.get(0).getList("usersFollowed");
parseUserFollowedList.add(ParseUser.getCurrentUser());
parseObjects.get(0).addAll("usersFollowed", parseUserFollowedList);
}
parseObjects.get(0).saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
dialog.dismiss();
}
});
}
});
.saveInBackground does not work because it throws exception: Cannot save info for user that is not logged in".
Can anyone help me in how to do this?
Cheers!
Users may modify only their own data. But the idea of following can be implemented such that only the currentUser's record requires write access: If Jack chooses to follow Jill, then Jack writes to his "following" relation. This works as long as we don't try to represent "followedBy" in Jill's data (which can be achieved instead with a query).
Or consider that the User table represents the private relationship between a real person and your app. It might make better sense to model the idea of a user's public face with your own custom object, and model following relationships between those. I mention this idea elsewhere here and here.

Categories

Resources