i have basic question. Iam using parse android SDK to retrieve some data from backend. I have 2 collections : "User" and "Photo". What i want to do is that i want to query "Photo" collection which contains some data about image and join that against "User" collection and get some info about owner of picture. Please see code below:
ParseQuery<ParseUser> queryInner = ParseUser.getQuery();
ParseQuery<ParseObject> query = ParseQuery.getQuery("Photo");
query.whereMatchesKeyInQuery("owner", "username", queryInner);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> resultSet, ParseException exception) {
if (exception == null) {
parsqQueryResult = new ArrayList<ObjectUserPhoto>();
ObjectUserPhoto row = new ObjectUserPhoto();
Log.e("size",String.valueOf(resultSet.size()));
for (int a = 0; a < resultSet.size(); a++) {
row = new ObjectUserPhoto();
//this works
row.setDescription(resultSet.get(a).getString(Constants.DB_COL_USER_PHOTOS_DESCRIPTION));
//this is not working
Log.e("username",String.valueOf(resultSet.get(a).getString("col_from_user_table")));
parsqQueryResult.add(row);
}
}
}
});
So basically iam able to acces columns from "Photo" collection, but iam not able to acces any column from "User" collection. How can i acces data from "User" collection ??
Thanks
Martin
In your comment you mentioned that you are not using pointers. I assume that you are just storing the id of the ParseUser objects.
Given a ParseObject's ID, you can retrieve an object by issuing a ParseQuery and passing the ID. Refer to this document.
However, I do not see any reason why you would want to store just the ID and not the Pointer to the object. Imagine if you want to display the information on a list then that means for every item you will need to perform a ParseQuery.
If you store a Pointer then you can leverage on the "include" method (see it here at the bottom part of the "Relational Queries"). This allows you to include the actual object the Pointer is pointing to. So in your case, the results of the Photo query will include the User objects too.
And lastly, I suggest that you read through at least the whole Objects and Queries sections of the documentation as you would learn the basics on how to use the SDK.
Related
I have these Classes in parse db.
User ...
Post (user pointer<_User> | images Relation )
Image (post pointer | image File )
Follow ( user_from pointer | user_to pointer)
The questions are,
1- How to get the list of posts with their images of users who i am following. (in java android)
2- How to get a list of my posts.
3- How o get a list of my followers.
4- example of java class of User, Post, Image and Follow objects.
thanks
probably you'll need to construct a relational queries, like the example below:
ParseQuery<ParseObject> innerQuery = ParseQuery.getQuery("Post");
innerQuery.whereExists("image");
ParseQuery<ParseObject> query = ParseQuery.getQuery("_User");
query.whereEqualTo("postPointer", innerQuery);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> commentList, ParseException e) {
// comments now contains the comments for posts without images.
}
});
You can check more about it at Parse Docs
I have the following denormalized data structure:
A Contact can associate with multiple Records. A Record can have multiple associated Contacts (many<->many relationship). To keep track of their relationship, an int value to indicates the contact's role in a particular record, and store the role value in two separate references
Contact
- Contact1:data
- Contact2:data
- Contact3:data
Record
- Record1:data
- Record2:data
Record_Role_Ref
- Record1
-- Contact1: roleA
-- Contact2: roleA
-- Contact3: roleD
- Record2
-- Contact1: roleB
Contact_Role_Ref
- Contact1
-- Record1: roleA
-- Record2: roleB
I'm using FirebaseIndexRecyclerAdapter is to show a list of associated Contacts to a particular Record id. So for the key reference I would use Record_Role_Ref/record_id, and for the data reference I would use Contact, like so:
// Setup the reference to the all the associated contact list in record_role_ref, using the record id as key
Query mRecordRoleRef = firebaseDatabase.getReference().child(DB_RECORD_ROLE_REF).child(mRecordId);
// Reference the Contact data ref
Query mContactRef = firebaseDatabase.getReference().child(DB_CONTACT);
FirebaseIndexRecyclerAdapter mContactAdapter = new FirebaseIndexRecyclerAdapter<Contact, ContactViewHolder>(Contact.class,
R.layout.item_contact,
ContactViewHolder.class,
mRecordRoleRef, // The Firebase database location containing the keys associated contacts to this record
mContactRef)// The Firebase database location to watch for data changes. Each key key found at keyRef's location represents a list item in the RecyclerView.
Limitation(s): I don't want to store the role value in each contact and record object because each time a role is changed, both the contact and record's entire object would have fetched and updated. Users want to delete, modify, move both contact and records, and change roles.
Problem(s):
The contact's role value is stored as value of the key in the mRecordRoleRef. Is it possible/how to get the value from the key reference in on-go with FirebaseIndexRecyclerAdapter? What is the good/best practice in this kind of situation?
Thanks In Advance :)
As of now, I just form another data read request inside the populateViewHolder callback method. Since the data read request is itself also async, I'm not yet sure if this would work for a large list and when the view recycles. The viewHolder returned by the populateViewHolder is set to final.
Query mRecordContactRoleRef = firebaseDatabase.getReference().child(DB_RECORD_CONTACT_ROLE_REF).child(mRecordId).child(mContact.getContactId());
mRecordContactRoleRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Getting the role int base on record type
Long roleNum = (Long) dataSnapshot.getValue();
viewHolder.setContactRoleTv("hi, the role is " + roleNum);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
How set objectId with Parse.com with primary key.Can you help me ?
When i create new row, i want setObjectId of row.
final ParseObject parseObject = new ParseObject(ChapsModel.PARSE_OBJECT);
parseObject.put(ChapsModel.PARSE_FIELD_NAME_CHAPS,
chapsModel.get(i)
.getNamChap());
parseObject.put(ChapsModel.PARSE_FIELD_LINK_CHAP,
chapsModel.get(i)
.getLinkChap());
parseObject.put(ChapsModel.PARSE_FILED_TEAM_TRANSLATE,
chapsModel.get(i)
.getTeamTranslate());
parseObject.put(ChapsModel.PARSE_FIELD_OBJECT_MANGA,
ParseObject.createWithoutData(MangaModel.PARSE_OBJECT,
chapsModel.get(i)
.getObjectManga()));
parseObject.saveInBackground(new SaveCallback() {
#Override
public void done(final ParseException e) {
if (e == null) {
Log.e(">>>>>",
"done" + ojectId);
// parseObject.setObjectId(ojectId);
} else {
Log.e(">>>>>",
"else" + e.getMessage());
}
}
});
Log
java.lang.RuntimeException: objectIds cannot be changed in offline mode.
Log:
Sorry my english. thank
It's not possible to set objectId with Parse.com with primary key.
Although parse.com doesn't allow us to set the objectId of a row, you can create a new column named anything you want and you can set that new column to any objectId you want. For example, you can create a new column named myObjectId and set it to a string.
From the parse.com website at https://www.parse.com/docs/js/guide#cloud_code
The Data Browser
The Data Browser is the web UI where you can update and create objects in each of your apps. Here, you can see the raw JSON values that are saved that represents each object in your class.
When using the interface, keep in mind the following:
The objectId, createdAt, updatedAt fields cannot be edited (these are set automatically).
These are the columns of my Follow Table:
user (Pointer _User)
follower (Pointer _User)
What I want to do is to get all the user where
follower = currentUser
user.username begins with a certain string
I know that in lower-lever db (like mySQL) these data can all be fetched with a single query.
Is it possible in parse? If not, what's the best way to do such a thing?
Assuming your currentUser object is a PFUser
Note... I am program with parse in objective-c so I am not 100% sure this will run. But I feel like this is what your looking for... Your going to have to first query for all the followers who's follower field is equal to the current user.
Then join that query with a user query whose usernames or names, whatever, are equal to your string you pass in... beware the string you pass into the query is case-sensitive... i think...
So if a user in your app searches for BOB and the database has Bob stored... the query won't return Bob... It will just return nothing....
ParseQuery<ParseUser> userQuery = ParseUser.getQuery();
userQuery.whereEqualTo("username", certainString);
ParseQuery<ParseObject> followerQuery = ParseQuery.getQuery("Followers");
followerQuery.whereEqualTo("follower", ParseUser.getCurrentUser());
followerQuery.matchesKeyInQuery("user", "follower", userQuery);
userQuery.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> list, ParseException e) {
// comments now contains the comments for posts with images.
}
});
EDIT Going through Parse's Anypic project that does what you want... I feel that this is not possible... Your going to have to first make a query for the users in the followers table whose followers key is the current user. Then find the objects. Once the result is returned, iterate through the objects to whose names is contained within the contains string.
ParseQuery<ParseObject> followerQuery = ParseQuery.getQuery("Followers");
followerQuery.whereEqualTo("username", certainString);
followerQuery.whereNotEqualTo("username", ParseUser.getCurrentUser().username);
followerQuery.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> list, ParseException e) {
for (ParseObject element : list) {
if (element.user == ParseUser.getCurrentUser()) {
//This is a follower of the current user... append to a list object or whatever
}
}
// update a label or table once the iteration is done.
}
});
There still may be a solid solution for what you want to do in one query but I can't think of it right now... Ill come back to this post if I do.
I have pinned object for first time. Next time i try to fetch same object it takes time sometimes like 5 to 6 second in this the screen turns blank.
Here is my code for pinning. (Both pinning and querying data from local store is done on same table in parse)
ParseQuery<ParseObject> query = ParseQuery.getQuery(PARSE_IMAGE_TABLE);
List<ParseObject> images = query.find();
for each image i get i do following:
parseObject.pinInBackground(PARSE_PIN_WALLPAPER_INFO,
new SaveCallback() {
#Override
public void done(ParseException arg0) {
System.out.println();
}
});
When querying:
ParseQuery<ParseObject> query = ParseQuery.getQuery(PARSE_IMAGE_TABLE);
query.whereEqualTo(PARSE_IMAGE_THUMB_URL, imageURL);
query.fromLocalDatastore();
query.fromPin();
List<ParseObject> images = query.find(); -- this call takes time
Yes their is a lot of performance tweaks you can do in your code.
Pinning a list of objects is faster and better approach.
Instead of using find query use findInBackground.
Also start using pin(String name) and fromPin(String name) instead of fromPin() and fromPin(String name). This has a huge advantage if you have a lot of rows in your parse local storage.