ParseQuery for profile picture while displaying post - android

I am working on a sample app like Instagram in parse.com.Each post displays the profile picture(resized)of the uploader and the post photo.The user info is stored in a different class "_user" containing the profile picture in "profileimage" and the posts are stored in a different class "Posts".How to make a query to fetch them both (in a single query to reduce payload).The thing I have tried so far.I want to know what to add in my query.
ParseQuery<ParseObject> query=ParseQuery.getQuery("testing");
query.orderByAscending("createdAt");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> arg0, ParseException arg1) {
for(ParseObject obj:arg0){
ParseFile pfile=obj.getParseFile("Image");
coaching coach=new coaching();
coach.setId(obj.getObjectId());
coach.setName(obj.getString("Name"));
coach.setPlace(obj.getString("Place"));
coach.setImageurl(pfile.getUrl());
array.add(coach);
}
listView.setAdapter(new parseadapter());
}
});

What you're looking for is a relation, specifically a ParseRelation. You'll have to add a Pointer from your "Posts" class to your "Users" class. Do note that you add the user as a Pointer using their objectId. Something like:
Next you have to add the following code your query to include the Pointer object because by default the SDK does not.
query.include("postAuthor"); //your column name for pointer
Lastly you have to fetch the ParseObject containing the User data separately (in your loop)
ParseObject author = obj.getParseObject("postAuthor"); // column name for pointer
ParseFile authorPicture = author.getParseFile("profileimage"); // column user profile picture
authorPicture.getUrl(); // profile picture URL
author.getString("name"); // name of the user
Consider fetching the name of the user who posted* as I have above, this is a better database design and will correspond to changes made to the name of a user.
I hope this helps you and others stuck in similar situations. You can read more about ParseRelation here.

Related

Android Contacts List View same like Whatsapp using Firebase database

What approach is Whatsapp using to show an "Invite" button for contacts which are not on Whatsapp?
I also want to show a button in Contact list view for only those which don't exist in my app in Firebase database.
I am using Custom BaseAdapter to show contacts in List View.
Can you please help me in understanding how Whatsapp Contact is working?
My Question is not duplicate as that is to read contact list only. I want to show 'Invite' button also as per firebase data.
Thanks!
Well I am not confident what exactly whatsapp is using but as I can the contacts that are not on whatsapp appear in the last. So you can dump the contact list from your firebase Db then query the contacts in the device and make two arraylist in which one is having contact list present in your app means your app users then another is the new users then merge them and show in the Recyclerview or Listview as per your requirement and for invite button you can use different cell layout which contais a button by setting any bool in array list and check it in your base adapter or you can also set its visibility in the same cell as per data in your arraylist.
First of All you have to get the all contacts from clients device,
Note : You Have to Check For Contacts Permissions by your self & don't Forgot to add Permissions Manifest.
Call initData() in onCreate or After Checking Permissions.
here is the code to get Contacts from Clients Device.
private void initData() {
Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null,null);
while(Objects.requireNonNull(cursor).moveToNext()){
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
// Finds the contact in our database through the Firebase Query to know whether that contact is using our app or not.
findUsers(number);
}
}
While Getting Each Contact one by one from clients device, simultaneously we will trigger the firebase query to check whether that contact is using our app or not.
So we are using "findUser" Method to check whether that contact is using our app or not.
private void findUsers(final String number){
Query query = FirebaseDatabase.getInstance().getReference()
.child("User")
.orderByChild("phone")
.equalTo(number);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.getValue() != null){
Map<String, Object> map = (Map<String, Object>) snapshot.getValue();
// this will print whole map of contacts who is using our app from clients contacts.
Log.d("ContactSync", snapshot.getValue().toString());
// so you can use any value from map to add it in your Recycler View.
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.d("ContactSync", error.getMessage());
}
});
}
Here is how my database structure looks like.
Thanks for reading this answer,
I hope this will be helpful!

Query a Parse User

I am creating an app in android that allows the user to search other users registered in the app.
Each user is asked to enter a set of details like "Date of Birth" before entering into the app.These data are directly stored in the user class.
My requirement is that if a user enters a username and searches he must be able to see all the details available on that particular user.
For eg.:Lets assume every user must have a email(String) and date of birth(String).An User searches for name "John". What should the query be so that I can retrieve both email and DOB of a user with username "John".
The data given in the Parse.com guide is
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereEqualTo("username", name);
query.findInBackground(new FindCallback<ParseUser>() {
public void done(List<ParseUser> objects, ParseException e) {
if (e == null) {
Toast.makeText(getApplicationContext(),"Query Success",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),"Query Not Successful",Toast.LENGTH_LONG).show();
}
}
});
What are the changes that I need to make so that I can achieve my goal?
How to access the string stored inside the object?
If I retrieve multiple records from my query how can I handle it?
I have edited my query like this
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereMatches("username", name);
query.findInBackground(new FindCallback<ParseUser>() {
public void done(List<ParseUser> objects, ParseException e) {
if (e == null) {
for(ParseUser singleobject:objects){
String mail=singleobject.get("email").toString();
Toast.makeText(getApplicationContext(),mail,Toast.LENGTH_LONG).show();}
} else {
Toast.makeText(getApplicationContext(),"Query Not Successful",Toast.LENGTH_LONG).show();
}
}
});
No toast is generated but the query is executed without any exception.
Is the looping statement correct or am i doing something wrong??
What are the changes that I need to make so that I can achieve my goal?
The code looks like it correctly queries ParseUser for an exact match of a username. To match more loosely, consider using whereMatches
How to access the string stored inside the object?
Parse.Object provides getString() as well as other "get" variations depending on the attribute type.
If I retrieve multiple records from my query how can I handle it?
The "objects" parameter of the findInBackground completion handler is an array that contains zero or more matches to the query. Handle this array the way you would any other.

Updating a row in parse table using the object Id of the current device

Hi I am trying to update the location of the current device into the parse database using the objectId of this device.
ParseQuery innerQuery = new ParseQuery("_Installation");
innerQuery.whereEqualTo("objectId", ParseInstallation.getCurrentInstallation());//current phone
ParseQuery<PhoneFinder> query = ParseQuery.getQuery(PhoneFinder.class);
query.whereMatchesQuery("identification", innerQuery);
query.findInBackground(new FindCallback<PhoneFinder>() {
#Override
public void done(List<PhoneFinder> list, ParseException e) {
for (PhoneFinder loc : list)
{
loc.setLocation(geoPoint);
loc.saveInBackground();
}
}
});
If I use the objectId explicitly is works fine.
Any suggestions?
You haven't said what's wrong with the code you posted (that is, exactly what it does wrong) but I'm going to guess innerQuery doesn't return any rows. If that is the case, this information from the API docs may help:
Note: We only allow the following types of queries for installations:
query.get(objectId)
query.whereEqualTo("installationId", value)
query.whereMatchesKeyInQuery("installationId", keyInQuery, query)
whereEqualTo("objectId",value) isn't on that list, so that is probably why it's not working. Also, ParseInstallation.getQuery is the best way to get a query to use for installations.

Android and parse

i made a listview with all the posts in the list.
what i want is when i click the child in the list i want another activity to be opened showing that specific post and the related comments
the question is how to know which item is clicked and how to show that particular post ParseObject in next activity
as they do in messaging app in which you click the message from the listview and subsequent messages are shown in the next activity
i might be very thankful to you if you solve this for me!!
Please Try this code:
Please implement your object class with Serializable
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position,
long arg3) {
try
{
Log.v("position",position); // hear is your list item position
MyClass obj = new MyClass(); // Class must be implements with Serializable
Intent showintent = new Intent(context,<activity class to open>);
showcontactintent.putExtra("obj",obj);
startActivity(showintent);
}
catch(Exception e)
{
e.printStackTrace();
}
}
});
Use: Relational Data
Objects can have relationships with other objects. To model this behavior, any ParseObject can be used as a value in other ParseObjects. Internally, the Parse framework will store the referred-to object in just one place, to maintain consistency.
For example, each Comment in a blogging app might correspond to one Post. To create a new Post with a single Comment, you could write:
// Create the post
ParseObject myPost = new ParseObject("Post");
myPost.put("title", "I'm Hungry");
myPost.put("content", "Where should we go for lunch?");
// Create the comment
ParseObject myComment = new ParseObject("Comment");
myComment.put("content", "Let's do Sushirrito.");
// Add a relation between the Post and Comment
myComment.put("parent", myPost);
// This will save both myPost and myComment
myComment.saveInBackground();
You can also link objects using just their objectIds like so:
// Add a relation between the Post with objectId "1zEcyElZ80" and the comment
myComment.put("parent", ParseObject.createWithoutData("Post", "1zEcyElZ80"));
By default, when fetching an object, related ParseObjects are not fetched. These objects' values cannot be retrieved until they have been fetched like so:
fetchedComment.getParseObject("post")
.fetchIfNeededInBackground(new GetCallback<ParseObject>() {
public void done(ParseObject post, ParseException e) {
String title = post.getString("title");
// Do something with your new title variable
}
});
You can also model a many-to-many relation using the ParseRelation object. This works similar to List, except that you don't need to download all the ParseObjects in a relation at once. This allows ParseRelation to scale to many more objects than the List approach. For example, a User may have many Posts that they might like. In this case, you can store the set of Posts that a User likes using getRelation. In order to add a post to the list, the code would look something like:
ParseUser user = ParseUser.getCurrentUser();
ParseRelation<ParseObject> relation = user.getRelation("likes");
relation.add(post);
user.saveInBackground();
You can remove a post from the ParseRelation with something like:
relation.remove(post);
For more read: https://parse.com/docs/android/guide#objects-relational-data
^why did I copy all the words here instead of just providing the link? Because parse links are broken sometimes and doesn't direct you to the section you need (instead it just sends you to https://parse.com/docs/android/guide and because the doc is so large, you won't be able to find it.

How do I create groups of ParseUsers using Parse.com?

Currently I'm using Parse.com in order to create multiple ParseUsers. This works perfectly and each user can login individually. However from here I want to expand my app to allow Users to create groups of users and therefore have data that is only relevant and shared between these Users. This will mean that when the User logs in, they can see a List of the groups they are members of and from there can share data simply just to those users of that individual group. What would be the best way to tackle this and does anybody have any examples or tutorials that I could follow in order to understand this concept?
I've considered creating a Group class and then making this store User's IDs in an array and then allow each User to store an array of the Group IDs that they're currently members of. I'm just not really sure how to broach this issue.
Thanks in advance!
I ended up doing as shown below:
ParseQuery<ParseRole> query = ParseRole.getQuery();
Intent intent = getActivity().getIntent();
String groupId = intent.getStringExtra("groupId");
query.whereEqualTo("objectId", groupId);
groupUsers = new ArrayList<String>();
query.findInBackground(new FindCallback<ParseRole>() {
#Override
public void done(List<ParseRole> objects, ParseException e) {
if(e == null) {
for(ParseRole role : objects) {
ParseRelation<ParseUser> usersRelation = role.getRelation("users");
ParseQuery<ParseUser> usersQuery = usersRelation.getQuery();
usersQuery.findInBackground(new FindCallback<ParseUser>() {
#Override
public void done(List<ParseUser> objects, ParseException e) {
for(ParseUser user : objects) {
groupUsers.add(user.getUsername());
}
}
});
}
} else {
Toast.makeText(getActivity(), "ERROR", Toast.LENGTH_SHORT).show();
}
}
});
I passed in the group ID from the Intent that sent me to that Fragment that I was checking and then populated my ListView with the list that I've returned from the query on the Parse database with the specific group ID. I hope this helps anyone else who had the same issue as me. Good luck!
Since you probably want to use it for security as well as making it easier for code/users, look at the Roles security feature.
You can add/remove Users from Roles, and assign ACL permissions to Roles instead of Users. This way when people are added-to/removed-from the Role the permissions don't require any changes.
Initially there was a limit to the number of Roles you were allowed to create based on account type, but this restriction was removed last year I believe.

Categories

Resources