Benni
Benni

Reputation: 969

Parse.com objectID issue

I'm storing 10 different booleans to the cloud with Parse.com , the issue I'm having is that if a user changes one booleans value and saves, all the rest that wasn't set before saving are undefined with the new objectID. I simply want to update one of the values of the Object, not rewrite and create a whole new row with new objectID etc.

The workflow I had in mind was: 1. User changes some settings giving some new values to the booleans in the "Settings" ParseObject:

prefs.put("audio", true);
prefs.saveInBackground(new SaveCallback() {
                @Override
                public void done(ParseException e) {
                    if (e == null) {
                        preferences.putBoolean("audioLocal", true);
                        Gdx.app.postRunnable(new Runnable() {
                            @Override
                            public void run() {
                                preferences.flush();
                                setScreen(new MainScreen(main));
                            }
                        });
                    } else {
                        utils.toast_error("Failed, something went wrong.");
                    }
                }
            });

It saves in background as shown above.

In my main class's create method I fetch all the data and apply it to local preferences.

prefs = new ParseObject("Preferences");
if(ParseUser.getCurrentUser() != null){
        prefs.setACL(new ParseACL(ParseUser.getCurrentUser()));
    }
query.getInBackground(prefs.getObjectId(), new GetCallback<ParseObject>() {
        @Override
        public void done(ParseObject parseObject, ParseException e) {
            if(e == null){
            if(parseObject.getBoolean("audio")){
                preferences.putBoolean("audioLocal", true);
              }
                preferences.flush();
            }else{
                utils.toast_error("Check your internet connection");
            }
        }
    });

How I noticed this issue was when I uninstalled my app which resulted in all local preferences disappearing including the one holding the objectID. Suddenly all photos, settings that my testuser had uploaded was to waste. All set back to default and my query can no longer recognize the objectID no matter what I put in there.

Upvotes: 0

Views: 83

Answers (1)

Lucas Crawford
Lucas Crawford

Reputation: 3118

From what I gather, you are trying to store user preferences within your ParseUser object to keep track of what the user has elected to save for their app settings.

You have a number of options:

1) Use JSONObject

JSON is a simple way to store data in key/value format. Let's make it easy to keep track of all the settings in one place, with one single object. You can then store the object as a field for your ParseUser and save/update it when the user has made changes.

Example of initializing the preferences:

JSONObject newUserPrefs = new JSONObject();
newUserPrefs.put("audio", true);
newUserPrefs.put("anotherBoolean", false);
ParseUser user = ParseUser.getCurrentUser();
user.put("prefs", newUserPrefs);
user.saveInBackground(); //Not shown here but I suggest using SaveCallback

Example of getting the preferences:

ParseUser user = ParseUser.getCurrentUser();
JSONObject userPrefs = user.getJSONObject("prefs");
if(userPrefs.optBoolean("audio", false)){
    preferences.putBoolean("audioLocal", true);
}
//do more stuff here with other values!

The advantage here is you only have to query the DB for your ParseUser and you have immediate access to the user's preferences! No extra queries needed.

2) Use ParseObject

Later on down the road, your preferences might get a little more complex (ParseFiles, other ParseObjects, etc...) so this might be another alternative for a more advanced set of preferences. Here instead of a JSONObject, you store a reference to a ParseObject instead. This will require a query every time you need to access it, but provides more power (not just simple types!). I suggest subclassing this object and creating it as a simple POJO:

@ParseClassName("UserPreferences")
public class UserPreferences extends ParseObject {

     public ParseFile getBackground(){
         return getParseFile("background.jpg");
     }

     public boolean getAudioStatus(){
         return getBoolean("audio");
     } 

     public void setAudioStatus(boolean status){
         put("audio", status);
     }

     ...
     ...
} 

Now, when you create an instance of this new object type:

UserPreferences userPrefs = new UserPreferences();
userPrefs.setAudioStatus(true);
//do more setters/getters maybe
ParseUser user = ParseUser.getCurrentUser();
user.put("prefs", userPrefs);

//may or may not be necessary, the user's save in background might capture this, but to be safe we save this object as well!
userPrefs.saveInBackground() 
user.saveInBackground();  //again, use SaveCallback

Retrieving it:

ParseUser user = ParseUser.getCurrentUser();
UserPreferences userPrefs = user.getParseObject("prefs");
userPrefs.fetchInBackground() //again, use a callback to ensure it's successful fetch

//do stuff with the userPrefs now that you fetched it, like setting local preferences!

Note: See how I stored the ParseObject for User prefs as a field for the ParseUser, and saved the ParseUser. This updates the DB to have an object storing all the user preferences, similar to how we did with the JSONObject. And also note that when we fetch the ParseObject for UserPreferences, we have to fetch the object after getting reference to it. This is because that object still has data that has not been retrieved by the network yet, because it is not just a simple object.

The problem your facing is that you are storing the objectID for the preferences in your local preferences, which defeats the purpose you are trying to accomplish! You want to store reference to the preferences object on the cloud so that every time the app is wiped from a device, or data is wiped, you can restore the preferences, which means you need to store it on the Parse cloud. At the same time, you want to store the reference to the preferences with the associated ParseUser so make it a field of that parse user using the above examples I provided. I suggest starting with a simple JSONObject and going from there

References: Parse Objects Parse Data Types JSONObjects

Upvotes: 1

Related Questions