Repository navigation
How to send push notifications from Swift ? #768
Description
Activity
- changed the title
[-]How to send push notification from Swift ?[/-][+]How to send push notifications from Swift ?[/+]on Mar 2, 2016 PFPushsince it talks to/pushendpoint and it's implemented should actually work on the latest version of the server. Do you see something that suggests that it's not?Aha, here is something we uncovered then.
You should be able to send a notification from CloudCode then.The client SDKs don't have an ability to use MasterKey just yet, though we could safely add it, but it exposes a bad programming practice, since you should never put a master key on the client.
You can host Cloud Code actually on Parse Server.
This wiki page describes how to migrate over your code from classic Parse, but overall - all you need is to place Cloud Code in thecloudfolder of your Parse Server on Heroku and it should automatically pick it up.Also, here are two good guides on how to get Push Notifications in Parse Server land working with Cloud Code:
Going to close out this issue, feel free to comment here or reopen it if you still having trouble sending push via Cloud Code.
@nlutsenko Do you have a guide for how to trigger cloud code push notifications from my swift iOS app?
Do I just paste this code in my main.js file then in swift call
PFCloud.callFunctionInBackground(<#T##function: String##String#>, withParameters: <#T##[NSObject : AnyObject]?#>)Yup, that would work just great as well. That repo tutorial is actually very very good.
@nlutsenko Hey im still abit(very) lost. This is previously how I sent pushes in my messaging app.
How could I rewrite this method using the cloud code part to send the push?func sendPushNotification(contact: PFUser) { let pushQuery = PFInstallation.query() pushQuery?.whereKey("user", equalTo: contact) let push = PFPush() push.setQuery(pushQuery) let pushDictionary = ["alert": PFUser.currentUser()!.valueForKey("name") as! String, "badge": "increment", "sound":""] push.setData(pushDictionary) push.sendPushInBackgroundWithBlock(nil) }
@nlutsenko Can I second @otymartin's comment about being lost.
So I successfully got to Step 4 "Send Push Notifications" in the Parse Push tutorial https://github.com/ParsePlatform/parse-server/wiki/Push and have notifications working in my app from 'curl'.
But that's where the tutorial seems to stop. I was hoping to request a notification directly from Swift code... Can you fill in the gap?
I have no experience in cloud code, but I'm guessing what's missing is that I need to set up a function in cloud code with the appropriate parameters that I need to pass it, and then I need to call this function to dispatch the notification, is that correct?
You could usw a Code like:
Parade.Cloud.define("SendPushToUser", function(request,response){
Parse.Push.send({useMasterKey: true},
{
Query: request.params.query
data: {
alert: request.params.message
}
},
{ success: function() {
// Push was successful
Response.success("push sent")
}, error: function(error) {
Response.error("push failed: " + error.message)
} });
});You call the cloud fund with the Parms ["query" : YourQuery,"message" :
Pushmessage]PS: I'm not sure about the location of useMasterKey... I haven't gotten to
the part of sending push notifications. Once I do I would post complete
cloud codes for sending to channels and specific users.
Am Samstag, 18. Juni 2016 schrieb Craig Grummitt :@nlutsenko https://github.com/nlutsenko Can I second @otymartin
https://github.com/otymartin's comment about being lost.So I successfully got to Step 4 "Send Push Notifications" in the Parse
Push tutorialhttps://github.com/ParsePlatform/parse-server/wiki/Push and
have notifications working in my app from 'curl'.But that's where the tutorial seems to stop. I was hoping to request a
notification directly from Swift code... Can you fill in the gap?I have no experience in cloud code, but I'm guessing what's missing is
that I need to set up a function in cloud code with the appropriate
parameters that I need to pass it, and then I need to call this function to
dispatch the notification, is that correct?—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#768 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/AQWahgiEDVoSUPyxd2ZoIkkH_wH4KLC2ks5qMx6YgaJpZM4HnjLo
.Thanks @hasso92 for your help. It was the push I needed to keep going, I had reached my input limit for the day!
The Cloud code function I ended up using had similarities to the CloudPath example:
// iOS push testing Parse.Cloud.define("iosPush", function(request, response) { var user = request.user; var params = request.params; var someKey = params.someKey var data = params.data var pushQuery = new Parse.Query(Parse.Installation); pushQuery.equalTo('deviceType', 'ios'); // targeting iOS devices only pushQuery.equalTo("someKey", someKey) Parse.Push.send({ where: pushQuery, // Set our Installation query data: data }, { success: function() { console.log("#### PUSH OK"); }, error: function(error) { console.log("#### PUSH ERROR" + error.message); }, useMasterKey: true}); response.success('success'); });I then called it from Swift using the PFCloud.callFunctionInBackground method:
let data = [ "badge" : "Increment", "alert" : "Some message", ] let request = [ "someKey" : someKey, "data" : data ] PFCloud.callFunctionInBackground("iosPush", withParameters: request as [NSObject : AnyObject])I go into this in more detail on my blog.
Reacted by michaelsalvadorhere is the cloud code function that I modified to fits your requirements
Parse.Cloud.define("iosPush", function(request, response) { var user = request.user; var params = request.params; var someKey = params.someKey var data = params.data var recipientUser = new Parse.User(); recipientUser.id = someKey; var pushQuery = new Parse.Query(Parse.Installation); pushQuery.equalTo('deviceType', 'ios'); // targeting iOS devices only pushQuery.equalTo("user", recipientUser); Parse.Push.send({ where: pushQuery, // Set our Installation query data: data }, { success: function() { console.log("#### PUSH OK"); }, error: function(error) { console.log("#### PUSH ERROR" + error.message); }, useMasterKey: true}); response.success('success'); });swift code
let data = [ "badge" : "Increment", "alert" : text, ] let request = [ "someKey" : self.incomingUser.objectId!, "data" : data ] PFCloud.callFunctionInBackground("iosPush", withParameters: request as [NSObject : AnyObject]) PFCloud.callFunctionInBackground("iosPush", withParameters: request as [NSObject : AnyObject], block: { (results:AnyObject?, error:NSError?) in if error == nil { print (results) } else { print (error) } })Reacted by StevenArmandLee, cubycode and michaelsalvadorhi,
i've tried your code too and it prints results: success, but my ios 10 device doesn't receive any push notification. if i use the Parse Push system from back4app.com, for example, i get the push notif., so that means that my .p12 certificates for APS are correct.
Any suggestion about this will be greatly appreciated@fvimagination make sure that you have enabled the push notification at the xcode and make sure you push it from iOS real device and the one receiving it also an iOS real device
@StevenArmandLee Push Notifications is enabled in Capabilities, but if i send a push from the iOS Simulator to a real device, it should work, right?
Also, if i send a push from the same real device, shouldn't i still receive it?fvimagination, I'm having the same issue. Did you ever figure out how to fix this?
ok so it's my certificate that has a problem, therefore I re-created the certificate.
@michaelsalvador that was my issue as well, now it works perfectly.
Can anyone post the proper code for Manifest.xml to configure an Android app for GCM push notifications? @StevenArmandLee @hasso92 @craiggrummitt@fvimagination So you're saying that after you recreated the development or production push certificate it sent to your device perfectly? Just to be clear
@michaelsalvador yes, exactly, the code posted from StevenArmand works perfectly on my side, with Parse Server hosted on back4app.com
Reacted by michaelsalvadorJust solved this same issue. Will attempt to help, just @ me.
@jbschaff best to document it here because others will experience the same problems and look for solutions.
Reacted by Jared SchafferWill need to modify
someKeyon client to target user 2 when user 1 performs action. My purpose is to send a notification to all followers of user 1 (which I haven't solved yet). However, just to get it working I was able to send the notification from user 1 to user 1.Swift code
let text = "\(PFUser.current()!.username!) followed you, or whatever you want to say here"; let data = [ "badge" : "Increment", "alert" : text, ] let request: [String : Any] = [ "someKey" : PFUser.current()!.objectId!, "data" : data ] print("sending push notification...") PFCloud.callFunction(inBackground: "pushToFollowers", withParameters: request as [NSObject : AnyObject], block: { (results:AnyObject?, error:NSError?) in print("push (String(describing: results!))") if error == nil { print (results!) } else { print (error!) } } as? PFIdResultBlock)Cloud code
Parse.Cloud.define("pushToFollowers", function (request, response) { console.log("Inside pushToFollowers"); var params = request.params; var user = request.user; var sessionToken = user.getSessionToken(); var someKey = request.someKey; var data = params.data; var recipientUser = new Parse.Query(Parse.User); recipientUser.equalTo("objectId", request.params.someKey); // Set our installation query var pushQuery = new Parse.Query(Parse.Installation); pushQuery.equalTo('deviceType', 'ios'); pushQuery.matchesQuery('user', recipientUser); pushQuery.find({ useMasterKey: true }).then(function(object) { response.success(object); console.log("pushQuery got " + object.length); }, function(error) { response.error(error); console.error("pushQuery find failed. error = " + error.message); }); // Send push notification to query Parse.Push.send({ where: pushQuery, data: data }, { useMasterKey: true }) .then(function() { // Push sent! console.log("#### push sent!"); }, function(error) { // There was a problem :( console.error("#### push error" + error.message); }); response.success('success, end of pushToFollowers') });Edit: Function to target all followers of User 1 is now solved.
Parse.Cloud.define("pushToFollowers", function (request, response) { console.log("Inside pushToFollowers"); var params = request.params; var user = request.user; var sessionToken = user.getSessionToken(); var someKey = request.someKey; var data = params.data; var recipientUser = new Parse.Query(Parse.User); recipientUser.equalTo('user', request.user.get('toUser')); recipientUser.find({ useMasterKey: true }).then(function(object) { response.success(object); console.log("recipientUser found this many: " + object.length); }, function(error) { response.error(error); console.error("recipientUser find failed. error = " + error.message); }); // Set our installation query var pushQuery = new Parse.Query(Parse.Installation); pushQuery.equalTo('deviceType', 'ios'); pushQuery.matchesQuery('user', recipientUser); pushQuery.notEqualTo('user', request.user); pushQuery.find({ useMasterKey: true }).then(function(object) { response.success(object); console.log("pushQuery found this many: " + object.length); }, function(error) { response.error(error); console.error("pushQuery find failed. error = " + error.message); }); // Send push notification to query Parse.Push.send({ where: pushQuery, data: data }, { useMasterKey: true }) .then(function() { // Push sent! console.log("#### push sent!"); }, function(error) { // There was a problem :( console.error("#### push error" + error.message); }); response.success('success, end of pushToFollowers') });
Since the PFPush class is not working anymore, how can I send a push notification from Swift or how can I call some cloud code to send a push notification to my users ?
Example : User_1 sends a friend request to User_2. I want User_2 to receive a notification on his device. I know I can do this with Javascript / PHP, but is it possible to do it from Swift directly without having some files hosted on a web server ?
I am actually using Heroku.
Thanks,
Axel