How to use Parse Cloud to get one user to follow another? - android

For my Android application, I want to make possible that a user follows another user. So I added a relation column for the users which will contains the following users.
Here is my parse cloud function. I'm just trying to add the currentUser to the followers relation of the user he wants to follow.
Parse.Cloud.define('sabonner', function(request, response) {
var userId = request.params.userId;
var User = Parse.Object.extend('_User');
user = new User({ objectId: userId });
var currentUser = request.user;
var relation = user.relation("abonnesRelation");
relation.add(currentUser);
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
Here is how I call it:
String targetId=mUsers.get(position).getObjectId();
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("userId",targetId );
ParseCloud.callFunctionInBackground("sabonner", params,
new FunctionCallback<String>() {
public void done(String result, ParseException e) {
if (e == null) {
Log.d("ParseCloud", "successs :"+result);
} else {
Log.d("ParseCloud", "unsuccesss :" + e.getMessage());
}
}
});
For now I'm having this error:
parsecloud java.lang.ClassCastException: com.parse.ParseUser cannot be cast to String.
It's my first use of Parse Cloud so I'm sure that there there are many things to modify here.

Seems like in functionCallback you're receiving ParseUser not String.
Just try to change your callback as follows:
ParseCloud.callFunctionInBackground("sabonner", params, new FunctionCallback<ParseUser>() {
public void done(ParseUser result, ParseException e) {
if (e == null) {
Log.d("ParseCloud", "successs :"+result);
} else {
Log.d("ParseCloud", "unsuccesss :" + e.getMessage());
}
}
});

Related

How to pass Stripe token from Android to ParseServer?

Welcome all!
I am currently working to pass a token generated by Stripes API from an Android app to a ParseServer. Below is my code, please be advised that I commented out previous failed attempts to let you know what I have tried and to also spark your imagination. Please note that with trial and error the issue presents to be with saving the data to the server. I have double checked that the class User has write permissions and it has an Object attribute titled token.
// Test the data.
if (userCard.validateCard()) {
Stripe stripe = new Stripe(CardActivity.this, "correct data is here I removed it, for StackOverflow");
stripe.createToken(
userCard,
new TokenCallback() {
public void onSuccess(final Token token) {
// Send token to your server
// Query the users, and get the username.
ParseQuery<ParseObject> query = ParseQuery.getQuery("User");
ParseUser user = ParseUser.getCurrentUser();
String objectId = user.getObjectId();
// Query the current user.
//query.whereEqualTo("objectId", username);
ParseObject object;
try {
object = query.get(objectId);
object.put("token", token);
object.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Toast.makeText(CardActivity.this, "Success", Toast.LENGTH_SHORT).show();
}
}
});
} catch (ParseException e) {
Toast.makeText(CardActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
// Attempt to update... Currently not working.
/*query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null && objects != null) {
for (ParseObject object : objects) {
object.put("token", token);
object.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Toast.makeText(CardActivity.this, "Success", Toast.LENGTH_SHORT).show();
}
}
});
}
} else {
Toast.makeText(CardActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});*/
}
public void onError(Exception error) {
// Show error message
Toast.makeText(CardActivity.this,
error.getMessage(),
Toast.LENGTH_LONG
).show();
}
}
);
} else {
Toast.makeText(CardActivity.this, "Something went wrong", Toast.LENGTH_SHORT).show();
}
A few things here:
1) Parse allows you to add/overwrite information to objects from their "shell". This is a ParseObject instance, set to a specified class, assigned an objectId, and then whatever values you want to add/change, and then saved. Any field you did not assign a value to will be ignored, so say you only set field3, field2 and field1 will not be overwritten to nothing.
2) ParseUser user = ParseUser.getCurrentUser() already returns a user object. You don't even need to create a shell from the id, this is a fully functioning parse object. You can then set the value you want and save it!
3) Queries and fetches (and cloud function calls) are asynchronous. This means that the code executes over time on a background thread, and your main thread will go on. So, things that require the results of these methods need to be called within the completion handler. You're doing object = query.get(objectId), but query.get() takes a bit to run so you're probably running through the rest of the code block before object has a proper value.
4) To my knowledge (not an Android developer, but I've used the JS and iOS SDKs) the Parse SDKs have a specific query for the User class that is a bit easier and safer to use than creating a ParseQuery set to the "User" class. Should be something like ParseUser.query()
So, not being an Android developer, I think what you want is more like this:
// Test the data.
if (userCard.validateCard()) {
Stripe stripe = new Stripe(CardActivity.this, "correct data is here I removed it, for StackOverflow");
stripe.createToken(
userCard,
new TokenCallback() {
public void onSuccess(final Token token) {
// Send token to your server
// Query the users, and get the username.
ParseQuery<ParseObject> query = ParseQuery.getQuery("User");
ParseUser user = ParseUser.getCurrentUser();
try {
user.put("token", token);
user.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Toast.makeText(CardActivity.this, "Success", Toast.LENGTH_SHORT).show();
}
}
});
} catch (ParseException e) {
Toast.makeText(CardActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
public void onError(Exception error) {
// Show error message
Toast.makeText(CardActivity.this,
error.getMessage(),
Toast.LENGTH_LONG
).show();
}
}
);
} else {
Toast.makeText(CardActivity.this, "Something went wrong", Toast.LENGTH_SHORT).show();
}

Parse Android SDK is not allowing delete request and returns [MongoError: exception: Mod on _id not allowed] in the log

The Parse android SDK does not allow updating of a column in the user table
while I am using getCurrentUser() method to mark it as authenticated. When I call saveInBackground() on it I get the following error in the log file:
Uncaught internal server error. { [MongoError: exception: Mod on _id not allowed]
name: 'MongoError'
Below is the code I am using for saving:
byte[] data = "Working at Parse is great!".getBytes();
final ParseFile file = new ParseFile("abcdef.txt", data);
ParseUser currentUser = ParseUser.getCurrentUser();
if (currentUser != null) {
// do stuff with the user
currentUser.put("column_name", file);
currentUser.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.i("KQ", "update successfully");
} else {
Log.i("KQ", "update error e = " + e);
}
}
});
} else {
// show the signup or login screen
Log.i("KQ", "else");
}
You have to save the ParseFile before attaching it to the User object.
Your code should be like this
byte[] data = "Working at Parse is great!".getBytes();
final ParseFile file = new ParseFile("abcdef.txt", data);
file.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if(e==null)
{
ParseUser currentUser = ParseUser.getCurrentUser();
if (currentUser != null) {
// do stuff with the user
currentUser.put("column_name", file);
currentUser.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.i("KQ", "update successfully");
} else {
Log.i("KQ", "update error e = " + e);
}
}
});
} else {
// show the signup or login screen
Log.i("KQ", "else");
}
}
}
});
Till I get a good answer.I am currently using my cloud code beforeSave trigger in parse to remove the id field to get rid of the exception and unblock my work.
any good answer will still be appreciated.
code I am using right now is as follows in the cloud code.
Parse.Cloud.beforeSave(Parse.User, function(request, response) {
// For Android SDK remove id field while updating a user becasue it was creating MongoDB Exception in android.
if (request.object.get("updatedFrom") == 'android') {
request.object.unset("updatedFrom");
request.object.unset("id");
}
response.success();
});
thanks.

Add to another user array Parse Android

In Parse I have another column in the User table known as 'Friends' which is an array. From my current user I am trying to add to another user's friends array.
I have tried:
//buddy = a string of the other person's username
//to add to CURRENT user's array (this is working)
UserList.user.addUnique("Friends", buddy);
UserList.user.saveEventually();
//this is to add to another user's array (NOT WORKING)
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereEqualTo("username", buddy);
query.findInBackground(new FindCallback<ParseUser>() {
public void done(List<ParseUser> objects, ParseException e) {
if (e == null) {
// The query was successful.
for (ParseObject friend : objects) {
friend.addUnique("Friends",UserList.user.getUsername());
friend.saveEventually();
}
} else {
// Something went wrong.
Log.d("Username", "Error: " + e.getMessage());
}
}
});
Write a method in a java that passes data to the cloud, and calls the function on the cloud by its name:
// the passes to the cloud is stored on HashMap
HashMap<String, Object> params = new HashMap<String, Object>();
// user's name to add the buddy to it
params.put("username", username);
// buddy's name to pass to the cloud
params.put("buddy", buddy);
ParseCloud.callFunctionInBackground("addBuddyToFriendsList", params, new FunctionCallback<String>(){
public void done(String result, ParseException e){
// e==null means no errors in running the function
if(e==null){
System.out.println(result);
}else{
System.out.println(e.getMessage());
}
}
});
Ok, and now let's write the function to be used in the cloud (assuming you know how to deploy functions on the cloud):
[EDITED]
Parse.Cloud.define("addBuddyToFriendsList", function (request, response){
Parse.Cloud.useMasterKey();
var query = new Parse.Query(Parse.User);
query.equalTo("username", request.params.username);
query.find({
success: function(user) {
// query.find returns an array.....
user[0].addUnique("Friends", request.params.buddy);
user[0].save(null, {
success: function(success){
response.success();
},
error: function (error){
response.error(error);
}
});
},
error: function(object, error) {}
});
});
Try this:
ParseQuery<ParseObject> query = ParseQuery.getQuery("_User");
query.whereEqualTo("username", buddy);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
// The query was successful.
for (ParseObject friend : objects) {
friend.addUnique("Friends",UserList.user.getUsername());
friend.saveEventually();
}
} else {
// Something went wrong.
Log.d("Username", "Error: " + e.getMessage());
}
}
});
I tried to call that class in different way then you did, I referred to it like a normal class. Usually this way works for me.
The thing is with "ParseUser" type is limited, for security reasons.

Login to Parse cloud code using android

In my android app I'm using ParseCloud.callFunctionInBackground() to call my cloud function:
Parse.Cloud.define("delete", function(request, response)
{
Parse.User.logOut();
Parse.User._currentUser = new Parse.User();
Parse.User._currentUser._if=request.params.user;
Parse.User._currentUser._sessionToken = request.params.token;
var query = new Parse.Query(Parse.User);
query.get(request.user)
.then(function(user)
{
Parse.User._saveCurrentUser(user);
response.success("User login valid!");
},
function(err)
{
response.error("Login failed: " + JSON.stringify(err));
});
});
While I've expected this to login the user, it always returns "Object not found". I'm sending the user id returned by "user.getObjectId()" and session "user.getSessionToken()".
The general rule of thumb for logging in via cloud code is to call the logIn function, return the session token and in the app code call the becomeInBackground method, like this:
In your cloud code:
Parse.User.logIn(username, password).then(function(user) {
response.success(user._sessionToken);
}, function(error) {
response.error(error);
});
And then in your app code:
// call cloud code function that returns sessionToken
ParseUser.becomeInBackground(sessionToken, new LogInCallback() {
#Override
public void done(ParseUser parseUser, ParseException e) {
if (e == null) {
// log in successful
} else {
// log in failed
}
}
});
Why dont you use the built in login function with parse?
ParseUser.logInInBackground(username, password, new LogInCallback() {
#Override
public void done(ParseUser user, ParseException e) {
// TODO Auto-generated method stub
if(e == null)
loginSuccessful();
else
loginUnSuccessful();
}
});

Change Password and Forgot Password with ParseUser in Parse.com

I am working on an application using Parse.com as backend support.I have used ParseUser for login and signup ,but now I have to implement change Password and forgot password ,but don't know how to implement it..Please help me to implement this functionalities.
The code which I have used to login the ParseUser is as follows:
ParseUser.logInInBackground(str_email2, str_password2, new LogInCallback() {
#Override
public void done(ParseUser user, ParseException e) {
dlg.dismiss();
if(e == null)
{
Log.d(">>>","ObjId>>"+user.getObjectId()+" Username>>>"+user.getUsername());
}
else
loginUnSuccessful();
}
});
To request a new password (in case the user forgot it) you can use this:
ParseUser.requestPasswordResetInBackground("myemail#example.com",
new RequestPasswordResetCallback() {
public void done(ParseException e) {
if (e == null) {
// An email was successfully sent with reset instructions.
} else {
// Something went wrong. Look at the ParseException to see what's up.
}
}
});
And to change a password you can just get the current user and do the following:
ParseUser currentUser = ParseUser.getCurrentUser();
currentUser.setPassword("new_password");
currentUser.saveInBackground();
In the doc, you have this sample code:
ParseUser.requestPasswordResetInBackground("myemail#example.com",
new RequestPasswordResetCallback() {
public void done(ParseException e) {
if (e == null) {
// An email was successfully sent with reset instructions.
} else {
// Something went wrong. Look at the ParseException to see what's up.
}
}
});
Source: https://parse.com/docs/android_guide#users-resetting
You can not reset the password for not signed (anonymous) ParseUser.
If you are using email feature for ParseUser, you can send password reset mail like this
ParseUser.requestPasswordResetInBackground(
stringEmail,
new RequestPasswordResetCallback() {
public void done(ParseException e) {
...
}
}
);
If you are not using email feature, you need to write a cloud method in your main.js file, like this
Parse.Cloud.define("resetPassword", function (request, response) {
Parse.Cloud.useMasterKey(); /*important*/
var username = request.params.username;
var password = request.params.password;
var objUser = Parse.Object.extend("User");
var qUser = new Parse.Query(objUser);
qUser.equalTo("username", username);
qUser.find().then(function (resultObj) {
if(resultObj.length > 0){
var userObj = resultObj[0];
userObj.set("password", password);
return userObj.save();
} else {
response.error("User does not exist");
}
}).then(function () {
response.success("Password RESET DONE SUCCESSFULLY");
}, function (error) {
response.error("Error " + error);
});
});
and call that method from your app, like this
Map<String, Object> params = new HashMap<String, Object>();
params.put("password", password);
params.put("username", username);
ParseCloud.callFunctionInBackground("resetPassword", params, new FunctionCallback<String>() {
#Override
public void done(String response, ParseException e) {
if (e == null) {
...
} else {
..
}
}
});
This way you can reset user password using username or mobile number.

Categories

Resources