How to pass the user object that triggered the push notification - ios

I have saved all the user's location in the installation object. And i have another object named locationObject which gets updated when the current user sends his current location.When it does, the cloud code compares his current location with all the other saved locations and send push notifications to the users who are nearby.This is my code to generate push notifications.
Parse.Cloud.afterSave("locationObject", function (request) {
var geoPoint = request.object.get("myCurrentLocation");
var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.near("significantLocationUpdate", geoPoint);
pushQuery.limit(100);
Parse.Push.send({
where: pushQuery,
data: {
alert: "some user is nearby"
}
}, {
success: function() {
console.log("push was successful");
},
error: function(error) {
console.log("sending push failed")// Handle error
}
});
});
Now, my question is, how can i pass along the user object that triggered the push notification along with his current location to the the users i am sending push notification to?

You can add additional data to the push. For example:
data: {
alert: "some user is nearby",
user: [user objectId],
latitude: [user latitude],
longitude: [user longitude]
}

Related

Query Session class with cloud code Parse

I am trying to send a push notification using a user's id. I have already tested sending with installationId, querying the _Installation class, but i would like to query the session class of the user pointer, to then turn around and query the installation class.
My problem is lying in the restrictions of querying the session class. I have successfully used createWithoutData() found here, and I know it is working because i can output that user. However, even after using the master key found here, the results are always empty.
The general practise for sending Push Notification to specific user is that you will store pointer to User in Installation class... for example when user register do this
Swift
if let installation = PFInstallation.current() {
installation["user_id"] = PFUser.current()!
installation.saveInBackground()
}
Cloudcode
var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.equalTo('user_id', tarUser);
pushQuery.exists("deviceToken");
pushQuery.limit(1); // in case there are more Installation with the user ID, use only the latest
pushQuery.descending("createdAt");
Parse.Push.send({
where: pushQuery, // Set our Installation query
data: {
alert: "Some push text"
}
}, {
success: function() {
// Push was successful
response.success();
},
error: function(error) {
console.error("Got an error " + error.code + " : " + error);
response.error(error);
},
useMasterKey: true
});
if I remember correctly you have to query the pointer in Cloud code with pointer structure, like this
var tarUser = {
__type: 'Pointer',
className: '_User',
objectId: 'insertObjectIDHere'
};

Parse Cloud Code Push Notifications

I have a Class "Storybaord" and there are two instances of when to send a Push Notification.
A user likes a post - [postObject addUniqueObject: [PFUser currentUser] forKey:#"likes"];
A user comments on a post - [postObject addUniqueObject: self.comment forKey:#"comments"];
In my cloud code I use Parse.Cloud.afterSave but I am unsure of how to distinguish between the two, and also determine if they even happen, because there are other occasions of saving the postObject without needing to send a push.
Cloud Code:
Parse.Cloud.afterSave("Storyboard", function(request){
var user = Parse.User.current();
var postUser = request.object.get('userId');
var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.equalTo ('userId', postUser);
Parse.Push.send({
where: pushQuery,
data: {
alert: "Liked Your Post"
}
}, {
success: function(){
},
error: function(){
}
});
});
If your insistent on sending the push via cloud code, all you have to do is set a conditional statement client-side and act accordingly, that way you can opt to send or not according to your needs, since you mentioned something about selectively sending pushing:
if (self.likeButton.isSelected) {
[PFCloud callFunctionInBackground:#"alertAuthor" withParameters:#{#"message", [NSString stringWithFormat:#"%# liked your post!", [PFUser currentUser].username]}
}
if (self.commentEntered) {
[PFCloud callFunctionInBackground:#"alertAuthor" withParameters:#{#"message", [NSString stringWithFormat:#"%# commented on your post!", [PFUser currentUser].username]}
}
And simply send a push using the parameters via cloud code:
Parse.Cloud.define("alertAuthor", function(request,response){
var query = new Parse.Query(Parse.User);
var message = request.params.message;
query.equalTo('username', 'postUser');
Parse.Push.send({
where: query,
data : {
alert: message,
badge: "Increment",
sound: "",
}
}, {
success: function() {
//Success
},
error: function(error) {
//Oops
}
});
});

Parse: Dynamic datas in push notification

Notification Using Parse from Server.
I have to send different message for a set of users
like,
you got 1st rank - to User A
you got 2nd rank - to User B
you got 3rd rank - to User C
In Parse, i have save the rank details for each users like
device_id userA rank1
device_id userB rank2
device_id userc rank3
While pushing the message, i have the send the message with the rank value
url = 'https://api.parse.com/1/push'
message = 'you got Xth rank'
data = {:data => message}.to_json
HTTParty.post(url,:body => data)
I can able to send the static message with the above code.
But how to send the message with dynamic values from parse database of respective record.
Looping through users and sending them push one by one may be the solution to your problem, Here is an example code in JS
var installationQuery = new Parse.Query(Parse.Installation);
installationQuery.each(
function(result) {
var tempQuery = new Parse.Query(Parse.Installation);
tempQuery.equalTo("username", result.get('username'));
// Send push notification to query
Parse.Push.send({
where: tempQuery,
//
data: {
alert: "Hey "+result.get('name')+" your Rank ."+ result.get('rank')
}
}, {
success: function() {
response.success("Pushed to "+result.get('name'));
},
error: function(error) {
// Handle error
response.success("Error in push to"+result.get('name'));
}
});
},
{
success: function(result) {
console.log("push sent to all users.");
response.success();
},
error: function() {
} }
);
And if your data for ranks isn't in installation e.g. it's in Users Table then your first query would be on Users table and in function on each to send push you second query will remain on installation table.
Any query?

Push Notification Not Arriving from Parse Cloud Code

I wrote a simple job to try sending a push notification to myself. Here's the code:
Parse.Cloud.job("testPush", function(request, status) {
Parse.Cloud.useMasterKey();
var installationQuery = new Parse.Query(Parse.Installation);
installationQuery.equalTo("user", "6t1JIuNqe1"); // I triple checked - this is the value of my user in the installation table.
Parse.Push.send({
where: installationQuery,
data: {
alert: "Test"
},
}, {
success: function() {
console.log("The Push Test Worked!");
status.success("All done with the push test!");
}, error: function(error) {
console.error("Something bad happened " + error);
status.error("Something bad happened during the Parse test...");
}
});
});
Although it logs in Parse that the job was run successfully, I never see a notification appear on my iPhone. I checked in Settings - it's all set up properly there (notifications are allowed to appear and should appear as banners, they should show up in notification center, they should show up on my lock screen). And yet the notification never appears.
What more do I need to check? What am I missing?
Pointer field should work with an instance.
Try replacing installationQuery.equalTo("user", "6t1JIuNqe1"); with the following:
var user = new Parse.User();
user.id = '6t1JIuNqe1';
installationQuery.equalTo('user', user);

Parse iOS SDK - Login using Mobile phone verification code like Watsapp

How to implement login mechanism with mobile verification code.
SignUp (New User with New Mobile Number)
I can able to do this for signup user by generating a random password after verifying code send to his mobile number.
Login (Existing User with Mobile Number)
But don't knows how to implement this. I cant use changepassword method because it works only for an already logged in user.
Setting the Current User
Saw this Method in Parse Documentation. Can I use this method. If yes, how can I get session token.
[PFUser becomeInBackground:#"session-token-here" block:^(PFUser *user, NSError *error) {
if (error) {
// The token could not be validated.
} else {
// The current user is now set to user.
}
}];
Successfully changed the password without login calling cloud code from ios and then logged in with a new password.
iOS Code
[PFCloud callFunctionInBackground:#"assignPasswordToUser" withParameters:#{#"username":[self generateUsername],#"password":loginModel.verficationCode} block:^(id object, NSError *error) {
if(!error)
{
NSLog(#"Assign New Password Success");
[self doLogin];
}else{
NSLog(#"Assign New Password Failed");
[self handError:error];
}
}];
Cloud Code
Parse.Cloud.define("assignPasswordToUser", function(request, response){
Parse.Cloud.useMasterKey();
var query = new Parse.Query(Parse.User);
query.equalTo("username", request.params.username);
query.first({
success: function(theUser){
var newPassword = request.params.password;
console.log("New Password: " + newPassword);
console.log("set: " + theUser.set("password", newPassword));
theUser.save(null,{
success: function(theUser){
// The user was saved correctly
response.success(1);
},
error: function(SMLogin, error){
response.error("save failure");
}
});
},
error: function(error){
response.error("error");
}
});
});
Assuming your wanted to allow something like registering a new device by scanning a QR Code or something shown on an existing device, you could do that without having to change the password as follows:
User class extra properties:
loginValidation: String
loginValidationExpiry: DateTime
You would use something like a 1 or 2 minute expiry to make things safer, making sure you create the Date using server-time in a Cloud Function. You could generate a guid/uuid for the code and create the QR code on an existing authenticated platform.
On the new device after reading the QR Code you could call this cloud function:
Parse.Cloud.define("validateLoginCode", function(request, response) {
Parse.Could.useMasterKey();
var username = request.params.username;
var validationCode = request.params.validationCode;
var query = new Parse.Query(Parse.User);
query.equalTo("username", username);
query.equalTo("loginValidation", validationCode);
query.first({
success: function(user) {
if (user) {
var expiry = user.get("loginValidationExpiry");
var now = new Date();
if (expiry > now) {
// code is valid, get token, only valid because
// we got user with master key
response.success({ token: user.getSessionToken() });
} else {
response.error("code expired");
}
} else {
response.error("invalid user/code");
}
},
error: function(error) {
response.error("error");
}
});
});
You could now use becomeInBackground:block: method in your calling code.

Resources