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
Related
I'm using Parse as my backend and I'm trying to "like" a post that another user posted on the app. I'm querying to get the post, then incrementing the number of likes by 1, then adding the current user's object ID to an array that holds all the ID's of users which liked the post.
carLikeQuery.getInBackground(carItem.getObjectId(), new GetCallback<ParseObject>() {
#Override
public void done(ParseObject object, ParseException e) {
object.increment("likes");
object.addUnique("usersWhoLike", ParseUser.getCurrentUser().getObjectId());
object.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if(e==null) {
Log.d("SAVE", "Like saved :)");
} else {
Log.e("SAVE", "Not saved :( :" + e.getLocalizedMessage());
}
}
});
}
});
The error I'm getting:
E/SAVE: Not saved :( :java.lang.IllegalArgumentException: Cannot save a ParseUser that is not authenticated.
I saw the source code for the ParseUser from somewhere:
void validateSave() {
if (getObjectId() == null) {
throw new IllegalArgumentException("Cannot save a ParseUser until it has been signed up. Call signUp first.");
}
if (!isAuthenticated() && isDirty()) {
throw new IllegalArgumentException("Cannot save a ParseUser that is not authenticated.");
}
}
Doing the same kind of checking in my code reveals that the the currentUser is AUTHENTICATED and NOT DIRTY.
What could the issue be? To be honest, I want to say that it was working just fine before today, but obviously I was changing something and made a mistake down the line and I can't find it! Any help would be greatly appreciated.
I resolved the issue by creating an entirely new Parse application with the same data structure/layout. It just plain worked without any code changes.
You can follow the issue on GitHub here
I have project where I send messages between 2 and 2 ParseUsers, and save the messages as a ParseObjects where I keep a Pointer to the 2 users sending messages to each other. The code works for every user in the database except when I send a message to 1 particular user. Then I get "Cannot save a ParseUser that is not authenticated", so it seems like Parse tries to save the other User object, together with saving my message ParseObject, just with this one particular user.
Tried to create a "Save without data" object, but get the same error. Anyone experienced this before?
ParseObject message = new ParseObject("MSG");
message.put("sender", meUser);
message.put("receiver", otherUser);
message.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if( e== null){
Log.i(TAG, " Worked...");
}else {
e.printStackTrace();
}
}
});
The problem was that I actually did try to to change another users object. I found out where by backtracking using the "isDirty()" method on the object that was giving me issues to find out where I was making changes on the object. This method lead me to the root of the problem.
isDirty() returns true if you have made any changes to an object but not saved it yet.
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 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();