I am trying to get records from parse. My table in parse contains an array of pointers; I was facing difficulties to write parse query, so I first save array of pointers in an ArrayList, now I make a for loop to execute the query; for each loop iteration, I want to get records from parse and update local db then same as for next iterations. But this is creating some different problems. parse getInBackground is not working sequentially.... my outer for loop completely executes then parse method called due to which I am facing problems to save values in local db.
public void insertGroupsInDB(ArrayList<TempGroupClass> temp)
{
Log.d(TAG,"insertGroupsInDB: temp size:"+temp.size());
for(int i = 0;i<temp.size();i++) `//my target is to make inner query run till no of loop times and for each iterations inner parse query will run and then insert records in db against outer insertion group`
{
Groups grp = new Groups();
grp.setGroupTitle(temp.get(i).getGroupTitle());
grp.setGroupType(temp.get(i).getGroupType());
grp.setParseObjectId(temp.get(i).getParseObjectId());
long groupinsert = (YouinDatabase.getInstance(context)).addGroup(grp,context);
//}
/*try
{
final CountDownLatch latch = new CountDownLatch(1);*/
if(groupinsert != -1)
{
//now insert friends
//long friendInsertId = YouinDatabase.getInstance(context).addFriend();
//now get friends from members id
Log.d(TAG,"groups inserted successfully:"+groupinsert);
final ArrayList<Integer> list = new ArrayList<Integer>();
if(temp.get(i).getFriendObjectIdList().size() > 0)
{
for(int j =0;j<temp.get(i).getFriendObjectIdList().size();j++)
{
Log.d(TAG," >>>>>>>>>>>>>>>friend objectId>>>>>>>>>>>>>>:"+temp.get(i).getFriendObjectIdList().get(j));
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereContainedIn("objectId",temp.get(i).getFriendObjectIdList());
query.findInBackground(new FindCallback<ParseUser>() {
#Override
public void done(List<ParseUser> arg0,
ParseException arg1) {
// TODO Auto-generated method stub
if(arg1 == null)
{
//Log.d(TAG,"arg0 size:"+arg0.size());
if(arg0.size() >0)
{
for(int i = 0;i<arg0.size();i++)
{
Log.d(TAG,"arg0.size():"+arg0.size());
Friend f = new Friend();
f.setUsername(arg0.get(0).getString("username"));
f.setParseObjectId(arg0.get(0).getObjectId());
f.setHasAdded(false);
boolean userAlreadyExist = YouinDatabase.getInstance(context).checkUserExistInFriendTable(arg0.get(0).getString("username"));
long friendInsertId = -1;
ArrayList<Integer> list = new ArrayList<Integer>();
int friendid;
if(!userAlreadyExist)
{
// Log.d(TAG,"friend Already not exist :"+userAlreadyExist);
friendInsertId = YouinDatabase.getInstance(context).addFriend(f);
list.add(YouinDatabase.getInstance(context).findFriendIdOfLatestRecord());
friendid = YouinDatabase.getInstance(context).findFriendIdOfLatestRecord();
}
else
{
//Log.d(TAG,"friend Already exist :"+userAlreadyExist);
//list.add(YouinDatabase.getInstance(context).getFriendIdFromFriendName(arg0.get(0).getString("username")));
friendid = YouinDatabase.getInstance(context).getFriendIdFromFriendName(arg0.get(0).getString("username"));
}
// Log.d(TAG,"list size 1 :"+list.size());
int latestGroupInsertId = YouinDatabase.getInstance(context).findGroupIdOfLatestRecord();
long id = YouinDatabase.getInstance(context).addFriendInConnection(friendid,latestGroupInsertId);
//now update user setHasAdded
long updateFriendTable = -1;
if(id != -1)
{
updateFriendTable = YouinDatabase.getInstance(context).updateFriendTable(friendid);
}
Log.d(TAG,">>>>updated friend id information:>>>>");
if(updateFriendTable != -1)
{
Friend friendDetails = YouinDatabase.getInstance(context).getFriendDetailsFromFriendId(friendid);
Log.d(TAG,"friend name:"+friendDetails.getUsername());
Log.d(TAG,"friend:"+friendDetails.getParseObjectId());
Log.d(TAG,"friend added :"+friendDetails.isHasAdded());
Log.d(TAG,"groupId:"+latestGroupInsertId);
}
//YouinDatabase.getInstance(context).get
}
Log.d(TAG,"list size 2"+list.size());
}
}
else
{
Log.d(TAG,"arg1 != null:"+arg1.getMessage());
}
}
});
}
// Log.d(TAG,"list size:"+list.size());
}
//latch.countDown();
}
/*latch.await();
}
catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
*/
}
Right now, the problem is that my outer loop executes twice one after another and then after the loop ends, then my parse method brings data from parse ...due to which it's only updating record in db against last group id ...and it's not inserting records against first groupId
How to resolve this issue? I have used this technique because I failed to write query to get object result of array of pointers using parse.
You could use find() which should do a synchronous operation which might hold up your ui. I have not used parse yet so i dont know. Or you can set up something like below. Remove the outer and check conditions in your callback to determine when to launch the next query.
private int j = 0;
private int loopnumber = temp.size();
ArrayList<TempGroupClass> temp; //setup temp somewhere else
private void doQuery() {
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereContainedIn("objectId",temp.get(i).getFriendObjectIdList());
query.findInBackground(new FindCallback<ParseUser>() {
#Override
public void done(List<ParseUser> arg0,
ParseException arg1) {
// TODO Auto-generated method stub
if(arg1 == null)
{
...
...
else
{
Log.d(TAG,"arg1 != null:"+arg1.getMessage());
}
//at the end call the same method to start a query if the loop conditions have not been reached.
if(++i < loopnumber) {
doQuery();
}
}
});
}
}
Related
So I am trying to review all objects back from Parse. I know parse has a limit of 1000, but I found some solutions that allows me to page through the results. However, I can not get those solutions to work. Wondering if someone has dealt with this before.
Declare a global variable for storing the complete data
private static List<ParseObject>allObjects;
allObjects = new ArrayList<ParseObject>();
ParseQuery<ParseObject> query3 = ParseQuery.getQuery("HashTag");
query3.whereExists("Tag");
query3.setLimit(1000);
query3.findInBackground(getallobjects());
callback method:
int limit = 1000;
int skip = 0;
private FindCallback<ParseObject> getallobjects() {
return new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> list, ParseException e) {
allObjects.addAll(list);
if (list.size() == limit) {
skip = skip + limit;
ParseQuery<ParseObject> query = ParseQuery
.getQuery("HashTag");
query.setSkip(skip);
query.setLimit(limit);
query.findInBackground(getallobjects());
}
else {
//you have full data in allobjects
for (int i = 0; i < allObjects.size(); i++) {}
}
The issue seems to be that "getallobjects" is not resolved and I can't get the errors to go away.
A quick question - would an exception be caused on a Parse query if no matches were found and no data was returned by the query? For example, I'm looking to query my username table to find out if a user/username already exists or not. So I'm wondering if no matches were found on a username then would that return an unsuccesful query with an exception or a successful query with no data in the list of objects?
ParseQuery<ParseUser> userQuery = ParseUser.getQuery();
query.whereEqualTo("username", usernameInput);
query.findInBackground(new FindCallback<ParseUser>() {
#Override
public void done(List<ParseUser> objects, ParseException e) {
//query was successful
if (e == null) {
}
//query was unsuccessful
else {
}
}
If you follow the code from ParseQuery:
public Task<List<T>> findInBackground() {
return findAsync(builder.build());
}
you’ll eventually stumble upon this:
// Converts the JSONArray that represents the results of a find command to an
// ArrayList<ParseObject>.
/* package */ <T extends ParseObject> List<T> convertFindResponse(ParseQuery.State<T> state,
JSONObject response) throws JSONException {
ArrayList<T> answer = new ArrayList<>();
JSONArray results = response.getJSONArray("results");
if (results == null) {
PLog.d(TAG, "null results in find response");
} else {
String resultClassName = response.optString("className", null);
if (resultClassName == null) {
resultClassName = state.className();
}
for (int i = 0; i < results.length(); ++i) {
JSONObject data = results.getJSONObject(i);
T object = ParseObject.fromJSON(data, resultClassName, state.selectedKeys() == null);
answer.add(object);
/*
* If there was a $relatedTo constraint on the query, then add any results to the list of
* known objects in the relation for offline caching
*/
ParseQuery.RelationConstraint relation =
(ParseQuery.RelationConstraint) state.constraints().get("$relatedTo");
if (relation != null) {
relation.getRelation().addKnownObject(object);
}
}
}
return answer;
}
Inspect the above - you can see that a successful query, even though it might contain no data, will still return a non-null ArrayList instance.
In my fragment, I have declared the food variable
public class EatingFragment extends Fragment {
...
static int food = 0;
}
I load the variable from a parse.com database. Inside the onCreateView() function, I call the function loadSwallowCount(), implemented as below
void loadSwallowCount() {
SharedPreferences pref = this.getActivity().getApplicationContext().getSharedPreferences("MyPref", 0);
String id = pref.getString("parse_object_id", "empty");
if (id == "empty") {
food = 0;
Log.d("Not stored"," Swallow count not stored on device");
}
else {
ParseQuery<ParseObject> query = ParseQuery.getQuery("UserData");
query.getInBackground(id, new GetCallback<ParseObject>() {
public void done(ParseObject onlineData, ParseException e) {
if (e == null) {
food = onlineData.getInt("SwallowCount");
Log.d("mes", "food is " + food);
}
}
});
}
}
When I test the food count inside the loadSwallowCount function, I get the proper value. However, after the function returns to onCreateView(), I do another log, and strangely the value of food is 0.
loadSwallowCount is a function that use the method call getInBackground, which has a asyncronous callback in new GetCallback<ParseObject>.
This means that your code reach your log in onCreateView before the callback is called.
In this case, you will be able to use your food variable only after the callback is executed.
try this:
public void done(ParseObject onlineData, ParseException e) {
if (e == null) {
food = onlineData.getInt("SwallowCount");
processFoodValue();
}
}
i have around 13000 records on one table(HashTag -classname) . i want to retrieve all of them on a single query. but parse allows only 1000 per query. any other ways get the all the records..
ParseQuery<ParseObject> query = ParseQuery.getQuery("HashTag");
query.whereExists("Tag"); query.orderByAscending("Type"); query.setLimit(1000);
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> list,
ParseException e) {
// TODO Auto-generated method stub
if (e == null)
{
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
ParseObject p = list.get(i);
String tagid = p.getString("Tag");
String Type = p.getString("Type");
class2 c2 = new class2();
c2.type = "" + Type;
c2.tag = "" + tagid;
listClass2.add(c2);
}
}
Sure, you can run multiple queries on the same table, with query's skip property incremented by 1000 each time:
Get the total number of records via query.count(), and use it to set a 'skip' variable
Run a new query for each 1000 records, updating your skip property accordingly
Process records as normal when each query returns
Something like this:
ParseQuery<ParseObject> query = ParseQuery.getQuery("HashTag");
query.whereExists("Tag");
query.countInBackground(new CountCallback() {
public void done(int count, ParseException e) {
if (e == null) {
// The count request succeeded. Run the query multiple times using the query count
int numQueries = Math.ceil(count / 1000); //Gives you how many queries to run
for(int skipNum = 0; l < numQueries; l++){
ParseQuery<ParseObject> query = ParseQuery.getQuery("HashTag");
query.whereExists("Tag"); query.orderByAscending("Type");
query.setLimit(skipNum * 1000);
query.findInBackground(new FindCallback<ParseObject>() {
//Run your query as normal here
}
}
} else {
// The request failed
}
}
//Declare a global variable for storing the complete data
private static List<ParseObject>allObjects;
allObjects=new ArrayList<ParseObject>();
ParseQuery<ParseObject>query3=ParseQuery.getQuery("HashTag");
query3.whereExists("Tag");
query3.setLimit(1000);
query3.findInBackground(getallobjects());
int limit=1000;
int skip=0;
//callback method:
private FindCallback<ParseObject>getallobjects(){
return new FindCallback<ParseObject>(){
#Override
public void done(List<ParseObject>list,ParseException e){
allObjects.addAll(list);
if(list.size()==limit){
skip=skip+limit;
ParseQuery<ParseObject>query=ParseQuery.getQuery("HashTag");
query.setSkip(skip);
query.setLimit(limit);
query.findInBackground(getallobjects());
}else{
//you have full data in allobjects
for(int i=0;i<allObjects.size();i++){}
}
}}}
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("TestObject");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> list, ParseException e) {
for(ParseObject p : list){
Log.d("--", (String) p.get("foo")+p.getCreatedAt());
}
}
});
I'm using the Parse library to query some records from DB that will be shown in a ListView with a custom adapter. I've a table with records and each record should I do a counting query from other table.
This is the thread for the counting query of each object retrieved:
getVisualizations = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < events.size(); i++) {
ParseQuery<ParseObject> query = ParseQuery.getQuery(ParseConstant.PT_VISUALIZ);
query.whereEqualTo(ParseConstant.PT_VISUALIZ_EVENTO, events.get(i));
events.get(i).setVisualizations(query.count());
}
}
});
events is an Object ArrayList
And this is the code in the main
ParseQuery<ParseObject> query = ParseQuery.getQuery(ParseConstant.PT_EVENT);
query.setLimit(30);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> resultList, ParseException e) {
if (e == null) {
events = new ArrayList<Event>();
for (int i = 0; i < resultList.size(); i++) {
Event event = (Event) resultList.get(i);
events.add(event);
}
if (!getVisualizations.isAlive()) {
getVisualizations.start();
}
if (adapter != null) {
adapter.notifyDataSetChanged();
} else {
adapter = new AdapterEvent(getActivity(), R.layout.list_event, events, list);
AnimationAdapter animAdapter = new SwingBottomInAnimationAdapter(adapter);
animAdapter.setAbsListView(list);
list.setAdapter(animAdapter);
}
loadingBar.setVisibility(View.INVISIBLE);
} else {
Log.d("score", "Error: " + e.getMessage());
}
}
});
The problem is that after the thread has started, I don't know how to block the main thread until the other thread finish. (Sorry for the english :/ )
perhaps you should use Thread.join() - if we are dealing with 2 threads, this will block one thread, while allowing the other to complete, then once it does complete, it will resume. Here is a tutorial on it