I'm using Parse to save an object to the local datastore:
ParseObject product = new ParseObject("Product");
product.put("title", "Product A");
product.put("available", false);
product.pinInBackground();
Later I'm updating some properties:
ParseQuery<ParseObject> query = ParseQuery.getQuery("Product");
query.fromLocalDatastore();
query.whereEqualTo("name","Product A");
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> productList, ParseException e) {
if (e == null) {
for (ParseObject product: productList) {
product.put("available", true);
// [A]: call product.pinInBackGround() again?
}
} else {
// something went wrong
}
}
});
Now I would like to have these changes stored to the local datastore. Is this done automatically, or do I have to call pinInBackground again (see [A])? The documentation isn't very clear on this (ie. what does save mean?):
Whenever you save changes to the object, or fetch new changes from
Parse, the copy in the datastore will be automatically updated, so you
don't have to worry about it.
Note that I don't sync over the network, i.e. saveEventually or saveInBackground are never called.
No, there's no need to pin object again.
And you can test it by fetching this object from local data store.
Related
I'm trying to use Parse in a personal project but I faced a problem when I tried to get data from a new object called "Image". What I'm trying to do is from a list of users select one and display all the images related to the selected user, If I remove the whereEqualsTo I receive the images related to the user I'm login in. If I put whereEqualsTo I receive nothing.
This is my code:
private void getUserImages(final String selectedUserName) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("Image");
query.whereEqualTo("username", selectedUserName);
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
if (objects.size() > 0){
//Do something
}
}
}
});
}
This is my config class:
public void onCreate() {
super.onCreate();
Parse.enableLocalDatastore(this);
Parse.initialize(new Parse.Configuration.Builder(this)
.applicationId("202ac01cxxxxxxxxxxa41d1136bc8a86213328b4")
.clientKey("76b883b596xxxxxxxxxf60f9352fdb926dde46e")
.server("http://ec2-xx-xx-xxx-59.us-east-2.compute.amazonaws.com:80/parse/")
.build());
ParseACL defaultACL = new ParseACL();
defaultACL.setPublicReadAccess(true);
ParseACL.setDefaultACL(defaultACL, true);
}
Someone has any idea, how can I fix this?
The ParseUser class is secured by default. Data stored in a ParseUser can only be modified by that user. By default, the data can still be read by any client. Thus, some ParseUser objects are authenticated and can be modified, whereas others are read-only.
For any object, you can specify which users are allowed to read the object, and which users are allowed to modify an object. To support this type of security, each object has an access control list, implemented by the ParseACL class.
See this documentation on how to set Access Control list and give specific permissions.Parse User documentation
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)
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
I am using this code for getting a row from the parse cloud but everytime I am fetching objects it is giving me empty list,Although there is a corresponding row available in the parse which I am trying to find and update.
public void onClick(View v) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentInfo");
query.whereEqualTo("rollnum",rollnum.getText().toString());
query.whereEqualTo("name",name.getText().toString());
query.whereEqualTo("city",city.getText().toString());
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if(e == null && objects.size() > 0){
obj=objects.get(0);
obj.put("rollnum",rollnum.getText()
.toString());
obj.put("name",name.getText().toString());
obj.put("city", city.getText().toString());
obj.saveInBackground();
}
else if(objects.size()==0){
Toast.makeText(getApplicationContext(), "No relation Found!"+e,Toast.LENGTH_LONG).show();
}
}
}
If the object is there I am updating it with new values with help of put method.But it is always giving me an empty list of Parse Objects.
I think you are trying to update the available objects.You can do it this way.
public void onClick(View v) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentInfo");
query.whereEqualTo("rollnum",rollnum.getText().toString());
query.whereEqualTo("name",name.getText().toString());
query.whereEqualTo("city",city.getText().toString());
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if(e == null ){
if(object.size()==0){
//here you can put object with help of put method if object is not there and when the object size is greater than 1 you remove the other objects except the objects.get(0).All other objects except one will be removed and only the zeroth object will be updated at the time user updates it
}
else if( objects.size() > 0){
obj=objects.get(0);
obj.put("rollnum",rollnum.getText()
.toString());
obj.put("name",name.getText().toString());
obj.put("city", city.getText().toString());
obj.saveInBackground();
}
}
else{
//exception in getting data
}
}
}
If you are getting a empty list of objects then that means there are no objects stored that match the criteria that you are querying against.
Make sure you understand your query. The way you are setting up your query, there has to be a ParseObject stored where the rollnum, name, and city are equal to those values you are testing against, and they must be exactly equal. If no objects match that criteria, then parse will return an empty list. Use the Logcat and Parse Dashboard to debug and find out what's wrong with your query.
I have a registered app on Parse with a signup/login system. Now I want to create an activity which grabs all the available users in the app and to display them one-by-one as a listview. Can someone tell me how can I do that?
Once you've setup your ListView's adapter you can call this whenever you need to update it's contents:
public void updateUsers() {
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.findInBackground(new FindCallback<ParseUser>() {
#Override
public void done(List<ParseUser> userObjects, ParseException error) {
if (userObjects != null) {
mUserAdapter.clear();
for (int i = 0; i < userObjects.size(); i++) {
mUserAdapter.add(userObjects.get(i));
}
}
}
});
}
That updates my adapter which is plugged into my ListView. If you have more than 100 users you want to return you'll need to up the limit as I hear that's the default (then you have to page the results, not sure how yet)
Side note: As far as I know you can't Subclass the ParseUser at the moment (you can, but you then can't use that as the object you're querying with using ParseUser.getQuery() (Which would normally be done by ParseUser.getQuery(MyCustomUserClass.class) if you were to query a customised object.