Parse.com - setting up push notifications for single users - parse-platform

I'm working on a hybrid app using Ionic framework with Parse as a back end and I'm struggling to set up push notifications for single users. I'm sending the notifications through Parse's Cloud Code, and I have sending push notifications to all users working okay using the following;
Parse.Cloud.afterSave(
'_User',
function(request, response) {
Parse.Cloud.useMasterKey();
var installationQuery = new Parse.Query(Parse.Installation);
Parse.Push.send(
{
where: installationQuery,
data: {
alert: 'Test notification'
}
}, {
success: function () {
// Push was successful
},
error: function (error) {
// Push failed
}
}
);
}
);
Currently, when a user registers an entry is made into the Installation class (using phonegap-parse-plugin), adding their user ID as a channel. I did this with the intention of adding the channel as a query constraint when determining which users to push notifications to, but adding query.contains('channels', 'user-' + request.user.id); to the above doesn't push any notifications (but reports success in Cloud Code).
I've also read about adding the user as a pointer to the installation class, but that would mean a device could only have one user.
What is the best way to allow me to send push notifications to a single user via Cloud Code? Thank you!

Can you see the results of the Installation query where you add the constraint;
query.contains('channels', 'user-' + request.user.id);
The problem might be the empty result. Check it. One of suggestion to singe push single target is just use the user id. Save the user id in installation table and send push notification based on query constraint where equal to. Hope this helps.
Regards.

Related

ReactiveCrud, how can I delay for a moment without blocking IO before deleting data

So suppose I have created an api for booking hotel room by making a ticket and then I will use the information from the ticket (ex. size, bed etc.) to find available room, but if it could not find any available room I will need to delete this ticket later. So for a better user experience I don't want to suddenly delete the ticket, but I want to change the ticket status to be reject or something else and then delete it after 30second. So here what I have tried.
val ticket = ticketRepostiory
.findById(request.ticketId)
.map { it.copy(status = TicketStatus.REJECT) } // mapping new status
.flatMap { ticketRepostiory.save(it) } // save
.then(Mono.delay(Duration.ofSeconds(30))) // display to user for a 30s.
.flatMap { ticketRepostiory.deleteById(request.ticketId) } // delete it
.block()
notificationService.notify(...etc) // notification service notify status
But I found the problems that this code has blocking the other code for 30s (suppose another user wants to create a new ticket it won't create or save any data to db until 30s.) So how can I delete the data after 30s without blocking other request
So I fixed it now by using .subscribe() method instead of .block()

Live Queries subscription updates in Parse-server

Is it possible to get subscription alerts for live queries on a single client instead of everyone. I am using the following code to get update alerts for the object 'obj' on class 'class-name'. But the alert message comes on every client( i.e every instance of running app).
let query_add = new Parse.Query("class-name");
let subscription = query_add.subscribe();
subscription.on('update', (obj) => {
alert('object updated');
});
How can I modify this to notify only the single client.

Parse Cloud Code on Heroku User Query

I am trying to access properties located on the User object for the current user in a cloud code function. The current user is passed to the cloud code function and available at request.user. The Cloud Code is deployed to Heroku using parse-cloud-express.
When the request first arrives, it does not contain the user data other than the id.
So I tried performing a fetch to get the latest data:
Parse.Cloud.define("functionName", function (request, response) {
request.user.fetch().then(function (user) {
console.log(util.inspect(user));
});
});
But it outputs the same data and does not seem to include the User object's properties.
2015-12-15T01:19:08.830880+00:00 app[web.1]: { _objCount: 1, className: '_User', id: 'dKqZMSRgDc' }
I also tried performing a query on the user id, but receive the same result.
var userQuery = new Parse.Query(Parse.User);
userQuery.get(request.user.id).then(function (user) {
console.log(util.inspect(user));
});
How do I get the properties of the User object?
The problem was not with getting data for the User object, but the way I was logging it. It seems that the data is not available from the object itself, so the output from util.inspect was correct, but does not include any properties. (I'm guessing the internals of the Parse framework manages this in another way.)
I replaced with console.log(user.toJSON()) and can now see the expected data for the user.

Parse Cloud Code to send push notification to group of other users

I have an app where one user can invite other users to join an event by push notification. Let's say when creating an event, the user add other users to this event, then save the event to Parse.
So basically I have an array of user_id and I will call a function from cloud code to push notification to those Id, after saving the event.
1)Will the following Cloud code work?
Parse.Cloud.afterSave( "Event", function(request) {
//Get value from Ticket Object
var ids = request.object.get("inviteeIds");
//Set push query
var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.containedIn("objectId",ids);
//Send Push message
Parse.Push.send({
where: pushQuery,
data: {
alert: "New Event Added",
sound: "default"
}
},{
success: function(){
response.success('true');
},
error: function (error) {
response.error(error);
}
});
});
I am not sure if the containedIn function exist or not:
pushQuery.containedIn("objectId",ids);
When I search I only find documentation about equalTo function, e.g:
query.equalTo('injuryReports', true);
2) I also read about Channel, but I still not understand how to apply it in my situation. From the documentation:
Devices start by subscribing to one or more channels, and
notifications can later be sent to these subscribers.
In my case how can I create a Channel and then add ids of friends who I want to invite to this Channel?
If possible, I would like to use Cloud Code rather than pushing from mobile device.
1)Will the following Cloud code work?
Why don't you try it and see for yourself, then come back with the errors, if any? Anyway, there's no response in afterSave. It will return a success regardless of what happens in it.
Otherwise it may work. Try running it.
I am not sure if the containedIn function exist or not:
Parse.Query.containedIn
2) I also read about Channel, but I still not understand how to apply it in my situation
Basically you subscribe to a particular channel in the client. Like this (Android)
ParsePush.subscribeInBackground("channelName");
Then in the Cloud
Parse.Push.send({
channels: channelList,
data: {
// etc
}
});
Obviously you'll need to know the channels you want to target.
You can subscribe multiple users to the same channel (for example you can have a dedicated channel for a particular event) or you can have one channel per user (for example you can name it something like channel_<userId> and only subscribe that user to it). Up to you what you need or what you want.
One last thing...
So basically I have an array of user_id
Keep in mind that objects stored in the database have a limited size. If your object gets too big and has too much data, you won't be able to add any more to it.

Saving objects in Cloud Code function uses master key instead of user key

I have a Cloud Code function that is being called by users. In that function, I create a new object, "Invitation", which triggers a before_save handler when saving.
Since a user is running the Cloud Code function, I would expect request.user in the before_save function to be the same, but it appears to be saving the Invitation object as master, resulting in request.user being null.
Parse.Cloud.define("sendInvite", function(request, response) {
var invitation = new Invitation();
invitation.save().then(function(invitation){
response.success();
}, function(error){
response.error(error);
});
});
Parse.Cloud.beforeSave("Invitation", function(request, response) {
var sender = request.user;
// sender is null, since master key is being used...
});
This doesn't seem like correct behaviour – the cloud code function shouldn't default to executing using the master key unless explicitly told to do so.
Any thoughts?
The issue was that Parse.Cloud.useMasterKey() was used outside of a function in one of our requires for Parse Hosting (require(cloud/app.js)).
The two cases when CloudCode uses the master key are when the CloudCode calls Parse.Cloud.useMasterKey() or when the CloudCode was invoked by a caller which uses the master key. Check whether sendInvites is being called from an environment which uses the master key.

Resources