ParseQuery include returning null - java

For an app I'm working on, I'm using Parse (www.parse.com) and I have two different pointer arrays in the _User class. That class contains two columns that I'm trying to include in my query: "following" and "friends".
My problem is that the result is always either null or empty pointers, depending on how I query it.
Parse mentions:
In some situations, you want to return multiple types of related objects in one query. You can do this with the include method.
However, using this include method causes the results to be null. This is my code:
ParseQuery<AAUser> query = ParseQuery.getQuery(AAUser.class);
query.include("following");
query.include("friends");
query.getInBackground(ParseUser.getCurrentUser().getObjectId, new GetCallback<AAUser>() {
#Override
public void done(AAUser user, ParseException e) {
if(e != null)
return;
Log.d(TAG, String.valueOf(user.getFollowing()));
}
});
user.getFollowing() alwas returns [null] whenever I include that field. However, if I don't include it, it returns an empty pointer as it should. [AALocation{id='iLUigvrvrc'}]
As you can see, I queried my subclassed AAUser class. I still get the same results by querying the ParseUser class so I don't see how subclassing made a difference.
How can I solve this issue? Is this a bug with the Parse SDK? I'm using version 1.7.1 of the Parse Android SDK.
.
I'm basically trying to refresh the current user data with these fields included but I see it's not working as it should...
And yes, I tried fetchInBackground() but it doesn't give me any ways to include those fields. My current workaround is to use the empty pointers and query all of them one by one but I find this to be an awful workaround... please halp.

Try this:
ParseQuery<ParseObject> query = ParseQuery.getQuery("_User");
query.include("following");
query.include("friends");
query.findInBackground(new FindCallback<ParseObject>()
{
public void done(List<ParseObject> followinglist, ParseException e)
{
for (ParseObject following : followinglist)
{
ParseObject follow = following.getParseObject("following");
ParseObject friend=following.getParseObject("friends");
}
}
});

Related

Get Field value from entity using DTO

I have an app with several #MappedSuperClasses. Out of one of them I need to write a csv with columns in a very particular order stablished by the client.
Doing a Entity.class.getDeclaredFields() used to be enough to retrieve and write the columns in the right order before we had superclasses, but now, even if I use a custom solution to iterate through the superclasses's fields the order is incorrect, so I resorted to using a DTO Entity which returns the right order when calling getDeclaredFields().
The problems come when I try to retrieve the values present in the entities related, we used to do something like:
Object value = getLineFromField(field, line);
Where getLineFromField() method would be like:
private Object getLineFromField(Field field, Entity line) {
Object value = null;
try {
value = field.get(line);
} catch (Exception e) {
LOG.info("There is no value. Adding a WhiteSpace to the Column Value");
}
return value;
}
The problem appears in the field.get(line), this method from the Field library will always return a null value
Any experience out there doing a similar mapping?
Just trying to avoid writing a super-ugly 100-liner switch case in the codebase...
EDIT to add internal exception I get from the Field library: UnsafeObjectFieldAccessorImpl

how to fetch more than one object in parse android

public void getSchoolClasses(ArrayList<SchoolClass>schoolClassesIds , final CompletionHandler completionHandler){
ParseQuery<ParseObject> query = ParseQuery.getQuery("schoolClasses");
query.whereContainedIn("objectId",schoolClassesIds);
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if (e==null){
for (int i =0 ; i < objects.size();i++){
SchoolClass schoolClass=(SchoolClass)objects.get(i);
schoolClass.getTeacher().fetchInBackground(new GetCallback<ParseObject>() {
#Override
public void done(ParseObject object, ParseException e) {
}
});
}
}else{
completionHandler.onError(e);
}
}
});
}
How do I know when all objects are finished being fetched and to fire the completion handler?
from your code i can understand that you have a School class and each school can have 1...many teachers.
For that structure you should go with pointers.
Pointers allows you to save one to many relation between 2 parse objects and the big advantage is that you can execute one api call to get all the data that you need so you will not need to call fetch in a loop which is a bad practice.
In order to use pointers you need to do the following:
Go to your School sub class and add setter and getter for teachers. The teachers will be of type List<{Teacher Sub Class object}>
Your query should look like the following now:
ParseQuery<ParseObject> query = ParseQuery.getQuery("schoolClasses");
query.whereContainedIn("objectId",schoolClassesIds);
query.include("teachers"); // this line will fetch also the teachers together with the school
In your query callback you can now access the teachers in the following way:
SchoolClass schoolClass=(SchoolClass)objects.get(i);
schoolClass.getTeachers();
Pointers also allows you to retrieve relation of relations by using dot notation inside the include function (e.g. "teachers.students" will bring all the teachers and all the students for each teacher). That is the reason why i told you to use Pointers.
You can read more about it in here
I also suggest you to read also on Sub Classing your parse objects. By looking at your code it looks like you are not really using it. Sub classing of parse objects allows you to keep your code more organized and also expose easy access to the parse objects.
Please read more about Subclass and how to use it in here
It's not mandatory only a recommendation :)

Order a ParseQuery by the date at which only one field has been updated

I have a feed containing posts that are currently ordered by "updatedAt". My original intention was to push up posts to the top of the feed which were last replied to (I do this by incrementing a "replyCount" field in each post when a user leaves a comment), not totally cognizant of the fact that another field, "likeCount" is also being updated when user's "like" a post. I would still like to push those posts that were recently "replied to" to the top of the feed, but do not at the expense of the weird UX behavior that associated with liking posts pushing them up as well. I'm not sure how to separate the two.
What should I do here? Can I maybe add another column called "lastReplyCountTime" and then sort queries based on that? Maybe set lastReplyCountTime for all posts to the current time when saved to the database, and then only update that value when a post receives a reply?
String groupId = ParseUser.getCurrentUser().getString("groupId");
ParseQuery<ParseObject> query = new ParseQuery<>(ParseConstants.CLASS_POST);
query.whereContains(ParseConstants.KEY_GROUP_ID, groupId);
/*query.addDescendingOrder(ParseConstants.KEY_CREATED_AT);*/
query.orderByDescending("updatedAt");
query.findInBackground((posts, e) -> {
if (mSwipeRefreshLayout.isRefreshing()) {
mSwipeRefreshLayout.setRefreshing(false);
}
if (e == null) {
// We found messages!
mPosts = posts;
String[] usernames;
usernames = new String[mPosts.size()];
int i = 0;
for(ParseObject post : mPosts) {
usernames[i] = yeet.getString(ParseConstants.KEY_SENDER_NAME);
i++;
}
FeedAdapter adapter = new FeedAdapter(
getListView().getContext(),
mYeets);
setListAdapter(adapter);
}
});
}
You have 2 options:
Like you suggested you can create another date property let's call it sortedUpdatedAt and update it with the current date each time you are updating the relevant values
If you still want to use updatedAt you can wrap your like object in a separate parse object (class). This class will be saved as a relation in the parent class and then each time the user "like" you can just update only this class and not the whole object. This way the updatedAt of your parent object will not be changed.
I think that option 1 is great since it's not so complicated and you can do it very quick.

Parse Query, How to create a query that checks if arrays contain a particular string

I am using Parse.Com's backend service.
I am currently trying the code below:
I've tried a few variations and nothing seems to work. Is this even possible?
ArrayList<String> cities = new ArrayList<>(1);
cities.add(OriginCity);
cities.add(EndCity);
ParseQuery<ParseObject> mpassthroughcities = ParseQuery.getQuery("Ride").
whereContainsAll("Cities", cities).
whereGreaterThanOrEqualTo("Date", mCurrentDate);
After the following code runs, I use cities I know are contained within "Cities" and I get nothing.
Your code should works (see parse documentation)
Do you execute your query after ? like that:
mpassthroughcities.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> rides, ParseException e) {
// check rides for results
}
});
This list is empty ? Have you tried without the "whereGreaterThanOrEqualTo" ?

Insert or update table using JDBC

I have some records to import. It's ok the first time when they are being inserted. If I try to import the same data again I receive a org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint. How can I update the records in the database if the data is the same/or changed and insert if it's new data using JDBC?
public void store(Object entity) throws Exception {
try {
if (this.updateEntity((XEntity) entity) == 0) {
this.insertEntity((XEntity) entity);
}
...
} catch (SQLException sqlEx) {
...
}
}
private int updateEntity(XEntity entity) throws SQLException {
PreparedStatement prepStmt = this.getUpdatePreparedStmt();
...
return prepStmt.executeUpdate();
}
private void insertEntity(XEntity entity) throws SQLException {
...
this.getInsertPreparedStmt().executeUpdate();
}
The problem is fixed now. I've provided an answer below.
You can try using postgres SQL 'MERGE' or 'REPLACE'
You can pass the UPDATE command as a string through JDBC.
According to this SO post, you will have to write 2 statements.
If you want to use the same method to insert and update your data, you'll need to check if the data exists first. The SQL command used to insert a new object is INSERT, whereas the one used to update an element is UPDATE. So, what you could do is do a SELECT to check if your data is already here, and then do an INSERT or UPDATE based on the results.
However, this is a workaround. You would really need to clarify your implementation, and make different methods whether you are adding or updating data. Business-side, these are clearly two very different functions, so one method for both seems to me like a design problem.
This test logic works.
if (this.updateEntity((XEntity) entity) == 0) {
this.insertEntity((XEntity) entity);
}
The problem was in the method that updated the record. The WHERE clause in the update prepared statement was using different data(data containing spaces) so updateEntity would always return 0. That was the reason why only inserts were made, instead of updates. Thank you very much for your help.

Categories