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
Related
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.
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();
I use a Parse database. I would like to have access for simple users and an admin user. The would be that each user could see only his/her own data but the admin user could see all of users' data.
I create a ParseUser, and if the current user is equal with it, it should be known it is the admin user.
I get the following error:
java.lang.IllegalArgumentException: cannot setReadAccess for a user with null id
I think the mistakes are with if function (never become true) and this: acl.setReadAccess(ADMIN,true);
Could anyone suggest something?
ParseUser ADMIN = new ParseUser();
ADMIN.setUsername("ADMIN3");
ADMIN.setPassword("a");
// Create a post.
AnywallPost post = new AnywallPost();
// Set the location to the current user's location
post.setLocation(geoPoint);
post.setText(text);
post.setUser(ParseUser.getCurrentUser());
ParseACL acl = new ParseACL();
// Give read accesses
if (ParseUser.getCurrentUser() == ADMIN) {
acl.setReadAccess(ParseUser.getCurrentUser(), true);
}
else
{
acl.setReadAccess(ParseUser.getCurrentUser(),true);
acl.setReadAccess(ADMIN,true);
}
post.setACL(acl);
// Save the post
post.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
dialog.dismiss();
finish();
}
});
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.
I am just following the basic Parse quickstart guide found here:
https://www.parse.com/apps/quickstart#social/mobile/android/native/new
Everything compiled and ran just fine, but I checked and found that no user was actually being signed up on Parse. I checked the log and here is the error I am getting:
PARSE.COMīš FAILEDjava.lang.IllegalArgumentException: Cannot save a ParseUser until it has been signed up. Call signUp first.-1
Here is the code I am working with. As you can see, I just copied the tutorial exactly with the addition of outputting to the Log.
public class ParseApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
// Initialize Crash Reporting.
ParseCrashReporting.enable(this);
// Enable Local Datastore.
Parse.enableLocalDatastore(this);
// Add your initialization code here
Parse.initialize(this, "myappid", "mykey");
ParseUser.enableAutomaticUser();
ParseACL defaultACL = new ParseACL();
// Optionally enable public read access.
// defaultACL.setPublicReadAccess(true);
ParseACL.setDefaultACL(defaultACL, true);
ParseUser user = new ParseUser();
user.setUsername("my name");
user.setPassword("my pass");
user.setEmail("email#example.com");
// other fields can be set just like with PareObject
user.put("phone", "650-555-0000");
user.signUpInBackground(new SignUpCallback() {
public void done(ParseException e) {
if (e == null) {
Log.e("PARSE.COM", "SUCCESS");
} else {
Log.e("PARSE.COM","FAILED" + e.getMessage() + Integer.toString(e.getCode()));
// Sign up didn't succeed. Look at the ParseException
// to figure out what went wrong
}
}
});
}
}
I don't understand why the error is prompting me to call signUp first, is that not exactly I am doing with signUpInBackground? Any help would be greatly appreciated.
it looks like a same bug.
https://developers.facebook.com/bugs/426365424187686/
if you delete "Parse.enableLocalDatastore(this);" it will be work fine.
(API level doesn't matter)
and.. they assured me that they will fix the bug with next release.
but despite of updates(1.8.2->1.9.0) it is remained yet.
i'm sorry about my broken english.