Live Queries subscription updates in Parse-server - websocket

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.

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()

Parse.com - setting up push notifications for single users

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.

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.

Updating existing Parse object in Cloud Code

I am using Parse for my backend and want to search for existing friend requests and update those instead of creating new ones (if there is already an existing one).
I thought I figured out how to do it but when I submit new friend requests they get created as new objects instead of updating the old one, even though I found an existing request.
Here is the code I am using:
Parse.Cloud.beforeSave("FriendRequest", function(request, response) {
//search for an existing friend request with the same "from" and "to"
var query = new Parse.Query("FriendRequest");
query.equalTo("from", request.object.get("from"))
.equalTo("to", request.object.get("to"));
query.find({
success: function(results) {
if(results.length > 0)
{
var result = results[0];
//the new request id is undefined as expected
console.log("request id: " + request.object.id);
//the result id is valid for an object in the db as expected
console.log("result id: " + results[0].id);
//set the id of the request to the id of the existing db object
request.object.id = results[0].id;
//the valid id is now in the request object id
console.log("request id: " + request.object.id);
//after response.success, the database shows a new entry
//with a different id
//instead of updating the existing entry
response.success();
}
}
});
});
There isn't a lot going on here. The query does come back successful with the correct entry in the database. I can confirm that I get the correct objectId for the existing item in the database. Any thoughts or ideas are appreciated!
You can't manually set the objectId of an object.
If you want beforeSave to NOT create a new object (which is what you're about to do when beforeSave is called), you need to manually update the existing object and then respond with a failure. If you respond with response.success(), the object will be saved normally.
In your code, you don't seem to make any changes to the existing object. All you really need to do is to return response.error (https://parse.com/docs/cloud_code_guide#functions-onsave)
Of course, you should also handle this in your code somehow. Either by alerting the user, or handling it silently.
However; why does your code attempt to save a new friend request if one already exist? Your app should know that one exists and disable the friend request button or whatever the UI offers.

HOW TO: Get real-time notifications in Laravel 4 using Iron.io MQ, Push Queues & AJAX

I've integrated ironMQ push queues in my Laravel 4 app for longer running processes. I have some views that perform a $.get that might take 30 seconds. I wanted to see what others are doing to easily get notified when ironMQ is done pushing back to an endpoint.
An example of what I will be doing with push queues mostly:
public function getCompletedTasks() {
$user = User::find(Auth::user()->id);
Queue::push(function($job) use ($user) {
$recent = new Recent;
$tasks = $recent->getCompletedTasks($user);
// append data from $tasks to DOM
// here's where I want to receive my notification
});
}
Here I am just getting tasks from an API that match data from user.
I know I can store the response data to a database and use AJAX long polling to constantly check for the data but it seems like too much work for most situations I will need to do this. I don't know much about websockets. What types of things have you guys done in these situations? And if you have any examples that would be very helpful. Thanks.
UPDATE: Solved the issue using Pusher. See my answer.
I was able to solve my problem with the help of Pusher. Here's what I did:
Setup my Iron MQ push queue as normal. In routes.php:
Route::post('queue/push', function() {
return Queue::marshal();
});
Installed pusher laravel package.
In my controller then I Queue::push my data. Inside the closure I trigger a new Pusher channel. This will obviously only trigger when the data has been returned from IronMQ.
public function getCompletedTasks() {
$user = User::find(Auth::user()->id);
Queue::push(function($job) use ($user) {
$recent = new Recent;
$tasks = $recent->getCompletedTasks($user);
$pusher = new Pusher('xxx', 'xxx', 'xxx');
$pusher->trigger('reports', 'get_completed_tasks', array('tasks' => $tasks));
$job->delete();
});
});
Next in my view I call my AJAX function with no callback since I won't be doing anything else just yet:
$.get('account/tasks/completed');
Next in my view I initialize Pusher, subscribe to the event and bind get_completed_tasks to the Pusher channel. Now we just wait for a response from Pusher which will then allow me to perform the latter part of my original AJAX request:
{{ HTML::script('//js.pusher.com/2.1/pusher.min.js') }}
<script>
var pusher = new Pusher('xxx');
var channel = pusher.subscribe('reports');
channel.bind('get_completed_tasks', function(data) {
// do something with the data returned
});
</script>
Once I used Pusher in my app, the rest was a breeze. Hope this helps someone!

Resources