I want to know how can I achieve the following SQL query on parse,
e.g. assume we have 2 tables/classes in our DB: User, Profile with example values in brackets.
User
- email(tt#tt.com)
- Name(tt)
Profile
-email(tt#tt.com)
-age(23)
Sql query,
select User.email,User.name,Profile.age from User
JOIN Profile on User.email = Profile.email
Where User.email = 'tt#tt.com'
The resulting recordset would be "tt#tt.com,tt,23e".
Now, if I want to make the same thing with Parse, or better, how can I achieve this??
I read about these structures but I don't know if they apply to this case and how to use them. I'm developing in Android
any help would be greatly appreciated.
If you have pointers to _Users on your Class Profile best method would be this one :
var Profile = Parse.Object.extend("Profile");
var query = new Parse.Query(Profile);
query.equalTo("email", request.params.email);
return query.first().then(null, function(error) {
return Parse.Promise.error('Sorry, this profile was not found.');
}).then(function(profile) {
profile.get('_User').fetch().then(function(user) {
console.log(
'name : ' + user.get('name') + ' ' +
'age : ' + profile.get('age')
);
});
});
Note for profile.get('_User') your pointer's name may change and not be _User
Try this solution.
In User class, create a Pointer to Profile. Then you can query from User class to get Profile.
ParseQuery<User> parseQuery = ParseQuery.getQuery("User");
parseQuery.whereEqualsTo("emai", "youremail#mail.com");
parseQuery.getFirstInBackground(new GetCallback<User>() {
public void done(User user, ParseException e) {
if (e != null) {
Log.d("score", "The getFirst request failed.");
return;
}
Profile profile = (Profile) user.get("profile");
}
});
Related
I am working on a chatting application in which i can send messages , images , videos etc
i have done this in one to one chat also fulfill it in group chat .
But the issue is :-
I have to always join the each group everytime i login otherwise i am not been able to recieve message from different groups .
here is the way i join group each time .
MultiUserChat muc= new MultiUserChat(mConnection,"hsjsmqb#conference.11.111.111.111");
String userNAme ="222222222";
muc.join(userNAme);
if i do not join group everytime i do not recieve messages .
if i join group i started recieving messages .
My Question is is this the only solution or all group chatting works this way.
or am i doing some thing wrong
i googled but did not find any solution .
if it is duplicate question or any answer related to my question please share the link
thanks
This is the code :-
public boolean createChatRoom() {
String name = edtGroupName.getText().toString();
if (!(connection.isConnected() && name.length() != 0)) {
return false;
}
try {
// Create a MultiUserChat
String userName = Utils.covertIntoSubString(connection.getUser(), Constant.AT);
roomName = (name + md5String(getDateTime()) + userName + Constant.CONFERENCE + connection.getServiceName()).replaceAll(" ", "");
MultiUserChat muc = new MultiUserChat(connection, roomName);
// Create a chat room
muc.create(roomName);
// set Room Name as room subject
muc.changeSubject(name);// RoomName room name
// To obtain the chat room configuration form
Form form = muc.getConfigurationForm();
// Create a new form to submit the original form according to the.
Form submitForm = form.createAnswerForm();
// To submit the form to add a default reply
for (Iterator<FormField> fields = form.getFields(); fields
.hasNext(); ) {
FormField field = (FormField) fields.next();
if (!FormField.TYPE_HIDDEN.equals(field.getType())
&& field.getVariable() != null) {
// Set default values for an answer
submitForm.setDefaultAnswer(field.getVariable());
}
}
// Set the chat room of the new owner
List<String> owners = new ArrayList<String>();
owners.add(connection.getUser());// The user JID
// submitForm.setAnswer("muc#roomconfig_roomowners", owners);
// Set the chat room is a long chat room, soon to be preserved
submitForm.setAnswer("muc#roomconfig_persistentroom", true);
// chat room is public
submitForm.setAnswer("muc#roomconfig_publicroom", true);
// Allows the user to modify the nickname
submitForm.setAnswer("x-muc#roomconfig_canchangenick", true);
// Allows the possessor to invite others
// submitForm.setAnswer("muc#roomconfig_allowinvites", true);
// submitForm.setAnswer("muc#roomconfig_enablelogging", true);
// Only allow registered nickname log
// submitForm.setAnswer("x-muc#roomconfig_reservednick", true);
// Allows the user to register the room
// submitForm.setAnswer("x-muc#roomconfig_registration", true);
muc.sendConfigurationForm(submitForm);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
public void inviteFriends(String userJid) {
try {
String groupName = edtGroupName.getText().toString();
Message msg = new Message();
msg.setBody(groupName);
MultiUserChat muc = new MultiUserChat(connection, roomName);
if (muc != null) {
muc.grantMembership(userJid);
muc.invite(msg, userJid, groupName);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void invitationrecvd(){
MultiUserChat chatRoom = new MultiUserChat(con, rum);
try {
chatRoom.join(userName);
saveGroupsToDb(userName + Constant.AT + Constant.HOST + Constant.SLASHSMACK, rum, group);
} catch (Exception e) {
e.printStackTrace();
}
}
And This is the group message Listener on home screen
PacketFilter filter = new MessageTypeFilter(Message.Type.groupchat);
groupMessagesListeners = new GroupMessagesListeners();
mConnection.addPacketListener(groupMessagesListeners,filter);
The groupchat is addressed to a XMPP muc (multi user chat) so you would need to join the muc in order to receive messages sent in that particular group. You can read more about this in https://xmpp.org/extensions/xep-0045.html.
Here is an excerpt from the link:
7.2.1 Groupchat 1.0 Protocol
In order to participate in the discussions held in a multi-user chat
room, a user MUST first become an occupant by entering the room. In
the old groupchat 1.0 protocol, this was done by sending presence with
no 'type' attribute to , where "room" is the room
ID, "service" is the hostname of the chat service, and "nick" is the
user's desired nickname within the room:
More or less I already had answered this kind of answer, but your code it's much cleaner (Can't able to receive group chat messages using smack-android:4.1.4).
1) When you create a multiuserchat, to finalize it you must JOIN this chat or the room it's just configurated but not still active.
muc.sendConfigurationForm(submitForm);
muc.join("My Nickname","password"); //omit password if not needed
2) To automatically join your groupchats, you can use PubSub feature
A snippet with Smack can looks like:
BookmarkManager bookmarkManager = BookmarkManager.getBookmarkManager(mConnection);
bookmarkManager.addBookmarkedConference
("My roomname label",
roomName,
true,
"My Nickname",
password);
add this code when:
you create a groupchat
you accept an groupchat's invitation.
(To remove a bookmark, just:
this.bookmarkManager.removeBookmarkedConference(roomName)
)
Finally, after login, add a method to autojoin the groupchat:
List<BookmarkedConference> list = BookmarkManager.getBookmarkManager(mConnection).getBookmarkedConferences();
MultiUserChat muc;
for (BookmarkedConference conference : list)
{
System.out.println("- Conference with bookmark: " + conference.getName() +
" and jid: " + conference.getJid());
if ( (muc = multiUserChatManager.getMultiUserChat(conference.getJid()) ) != null
&& conference.isAutoJoin())
{
muc.join("My Nickname");
//foo
}
}
After this you have all to config and manage your groupchats. Personally I don't like to add to mConnection a generic PacketListener due to the consequent difficoulty to synchronyze messages receveid with front end, but this will be eventually another branch.
I have a problem querying the data of a user using pointer, so this is my tables (class):
_User
objectId<string> | username<string> | ...
Posts
objectId<string> | post<string> | writerId <pointer>(_User)
The writerId contains the user id of the writer of the post.
I'm showing the posts in a custom ListView in this way:
variables_posts = new ArrayList<VariablesPosts>();
ParseQuery<ParseObject> query = ParseQuery.getQuery("Posts");
query.selectKeys(Arrays.asList("post"));
query.include("writerId");
on = query.find();
for (ParseObject post : on) {
VariablesPosts map = new VariablesPosts();
map.setWriter((String) post.get("username"));
map.setPost((String) post.get("post"));
variables_posts.add(map);}
The problem is that the writerId is a pointer and not a string if I put
map.setWriter((String) post.get("writerId"));
The app will crash, so I used from another help the line query.include("writerId"); to directly get the username but this line:
map.setwriter((String) post.get("username"));
is crashing the app too, when I delete it the app works fine, so in my case how can I get the username from User class by the pointer writerId?
I don't know exact Java syntax, but when you include writerId and then want to get username of that writerId User, you must first get the User object from Post's writerId .. something like:
(String)((ParseUser)post.get("writerId")).get("username")
Your naming of the pointer column is a little misleading as the column does not contain IDs. You should call it writer instead.
To get the username, do this:
query.include("writerId");
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> postList, ParseException e) {
if (e == null) {
for (ParseObject post : postList) {
ParseObject writer = post.getParseObject("writerId");
String userName = writer.getString("username");
// .. (do whatever with userName)
}
} else {
Log.d("post", "Error: " + e.getMessage());
}
}
});
Ive got application on android which should work without internet and with parse database when internet is on.
Also I faced with problem of getting of pinned ParseObject which not saved in online database before.
So what I do:
ParseObject car = new ParseObject("cat");
cat.put("name","Pussy");
cat.pinInBackground();
So, now I want to get this cat by query with query.getInBackground but, I cant do it because I haven't objectId, which automatically generated only after saving in online database.
You can search for cats (objects) with given properties in the local datastore:
ParseQuery<ParseObject> query = ParseQuery.getQuery("cat");
query.fromLocalDatastore();
query.whereEqualTo("name", "Pussy");
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> catList, ParseException e) {
if (e == null) {
Log.d("cat", "Retrieved " + catList.size() + " cats");
} else {
Log.d("cat", "Error: " + e.getMessage());
}
}
});
However, if name is the only property, you'll likely get a list of objects with more than one entry. Here, you may add other properties (e.g. an owner) to limit the number of possible matches.
I want something like
objectid id name lastname pic
hx5w887 1 name1 lastname1 pic1
lops4wus 2 name2 lastname2 pic2
zh7w8sa 3 name3 lastname3 pic3
I don't want to change the objectId, just I want that field and every time I save an object increment in 1. I am searched a lot in google, about this, it is no possible at least you can something with Cloud Parse code, but I do not know how to make this function, I don't know if "Increment" can help me with this, and I do not know how to run the function anyway.
Parse.Cloud.afterSave("counter", function(request) {
var nameId = request.object.get("name").id;
var Name = Parse.Object.extend("Name");
var query = new Parse.Query(Name);
query.get(nameId).then(function(post) {
post.increment("idkey",+1);
post.save();
}, function(error) {
throw "Got an error " + error.code + " : " + error.message;
});
});
I deploy and
call the function in Android
ParseCloud.callFunctionInBackground("counter", new HashMap<String, Object>(), new FunctionCallback<String>() {
// #Override
public void done(String result, ParseException e) {
if (e == null) {
} else {
// handleError();
}
}
});
But nothing happens, what can be the problem? Sorry my bad english.
You can use ParseCloud 'beforeSave' functionality.
You can declare a code which will run before saving a new object of a specific class.
In this code you query for your class items, order it and get the first item (the highest value) then you can the next value (highest +1) to the new saved object.
For more info you can take a look at Parse documentation and in this thread (it is not in java but it is very similar)
EDIT: Since Parse is not longer is now an open source might be that things have changed.
It is said that we can retrieve our data if we are having objectId for that particular row, but it is auto generated and we cant insert it while setting data , so how to get data if i am not having object id , or any other means so that i can set objectId on my means.
Code is here as in comment:
ParseObject gameScore = new ParseObject("My Parse File");
String objectId = gameScore.getObjectId();
ObjectId doesnt't exist until a save operation is completed.
ParseObject gameScore = new ParseObject("My Parse File");
To retrieve the object id you need to save the object and register for the save callback.
gameScore.saveInBackground(new SaveCallback <ParseObject>() {
public void done(ParseException e) {
if (e == null) {
// Success!
String objectId = gameScore.getObjectId();
} else {
// Failure!
}
}
});
ObjectId can be retrieved from the original ParseObject(gameScore) once the done save callback is fired.
You can use this for getting current user object id
ParseUser pUser= ParseUser.getCurrentUser();
String objId= pUser.getObjectId();
not sure if this will apply to android , but I was trying to retreive the objectid, but for an entry that is already created. I did something like this and it worked.
ParseObject gameScore = new ParseObject("My Parse File");
var obId = gameScore.id;
Got it from the Javascript docs on Parse.com
The three special values are provided as properties:
var objectId = gameScore.id;
var updatedAt = gameScore.updatedAt;
var createdAt = gameScore.createdAt;
You can't unfortunately use the ObjectId until the object's been saved. I'm having this same problem now. The only solution I can think of, and posted a similar question relating to it here
My solution would be to make a tempId on the object and refer to that locally until it has an actual ObjectId, perhaps using a saveInBackground or saveEventually() callback to set other objects relating to it, to it's newly created ObjectId instead of it's old temp one.. when it's made available
It takes times for your values to be stored in table. Use this to get ObjectId
gameScore.saveInBackground(new SaveCallback() {
public void done(ParseException e) {
if (e == null) {
// Saved successfully.
Log.d("main", "User update saved!");
Log.d("main", "ObjectId "+gameScore.getObjectId());
} else {
// The save failed.
Log.d("main", "User update error: " + e);
}
}
});
In case you're handling the thread yourself:
First save:
gameScore.save();
Then you'll be able to access the id:
String parseId = gameScore.getObjectId();