send push notification to device directly from a device swift 3 - ios

Is there any way to send push notification from a device to device directly using https://fcm.googleapis.com/fcm/send.
My code:
func sendPushNotification(toUser: String, message: String) {
let urlString = "https://fcm.googleapis.com/fcm/send"
let url = NSURL(string: urlString)!
let paramString = "to="
let request = NSMutableURLRequest(url: url as URL)
request.httpMethod = "POST"
request.httpBody = paramString.data(using: String.Encoding.utf8)!
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in
do {
if let jsonData = data {
if let jsonDataDict = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions.allowFragments) as? [String: AnyObject] {
NSLog("Received data:\n\(jsonDataDict))")
}
}
} catch let err as NSError {
print(err.debugDescription)
}
}
task.resume()
}

let paramString = ["to" : FCM_ID/UDID, "notification" : ["title" : NOTIFICATION_TITLE, "body" : NOTIFICATION_BODY], "data" : ["user" : USER_ID, "image" : IMAGE_URL, "extrainfo" : ANY_STRING]]
just replace your line with this one and push notification should deliver.
Read more about it here... https://firebase.google.com/docs/cloud-messaging/server

Old post but it's worth to add to accepted solution as it can be helping others. You can check my post Push Notifications are delivered but didReceiveRemoteNotification is never called Swift or here didReceiveRemoteNotification function doesn't called with FCM notification server.
You must have "content_available": truein your notification definition or push notification service(with underscore) or your didReceiveRemoteNotification won't be called and you won't be able to use userInfo.

Related

iOS : FCM Notification - Send push notification to multiple users at once?

The following function is used to send a notification to a user. How to send a notification to a multiple user at once?
func sendPushNotification(to token: String, title: String, body: String) {
let urlString = "https://fcm.googleapis.com/fcm/send"
let url = NSURL(string: urlString)!
let paramString: [String : Any] = ["to" : token,
"notification" : ["title" : title, "body" : body],
"data" : ["user" : "test_id"]
]
let request = NSMutableURLRequest(url: url as URL)
request.httpMethod = "POST"
request.httpBody = try? JSONSerialization.data(withJSONObject:paramString, options: [.prettyPrinted])
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("key=SERVER-KEY", forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in
do {
if let jsonData = data {
if let jsonDataDict = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions.allowFragments) as? [String: AnyObject] {
NSLog("Received data:\n\(jsonDataDict))")
}
}
} catch let err as NSError {
print(err.debugDescription)
}
}
task.resume()
}
You can send push notification to multiple users by adding multiple tokens.
Here receiverToken is multiple user's FCM tokens.
class func sendMultiple(title:String,message:String,receiverToken : [String]) -> ()
{
var postParams : [String : Any] = [:]
postParams = ["registration_ids":receiverToken,
"notification":[
"title":title,
"sound":"default",
"body":message],
"data":[
],
"apns":[
"headers":[
"apns-priority":"10"],
"payload":[
"headers":[
"category":"NEW_MESSAGE_CATEGORY"]]]
]
print(postParams)
var request = URLRequest(url: URL.init(string: "https://fcm.googleapis.com/fcm/send")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(String(format:"key=%#", "YOUR_SERVER_KEY"), forHTTPHeaderField: "Authorization")
request.httpBody = try! JSONSerialization.data(withJSONObject: postParams, options: [])
URLSession.shared.dataTask(with: request, completionHandler:
{ (responseData, response, responseError) -> Void in
}).resume();
}
Please make sure to replace the "YOUR_SERVER_KEY" with your sever key

how to schedule push notifications sent between users for iOS

so far I was able to send notifications from userA to UserB using url and json but I couldn't figure a way to schedule a time for the notification to be sent and I would like to repeat it every week or a month according to the user's needs, this is the code I have so far :
func sendNotification(to token: String, title: String, body: String) {
let urlString = "https://fcm.googleapis.com/fcm/send"
let url = NSURL(string: urlString)!
let paramString: [String : Any] = ["to" : token,
"notification" : ["title" : title, "body" : body],
"data" : ["user" : "test_id"]
]
let request = NSMutableURLRequest(url: url as URL)
request.httpMethod = "POST"
request.httpBody = try? JSONSerialization.data(withJSONObject:paramString, options: [.prettyPrinted])
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("key=\(legacyServerKey)", forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in
do {
if let jsonData = data {
if let jsonDataDict = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions.allowFragments) as? [String: AnyObject] {
NSLog("Received data:\n\(jsonDataDict))")
}
}
} catch let err as NSError {
print(err.debugDescription)
}
}
task.resume()
}
how can I send the notification at a specific time and how can I repeat it ?
I haven't tried it, you can schedule LocalNotifications for a specific time and date, on receiving of localnotification you can do it by enabling background mode.

iOS: Sending push notification to firebase services via url request

I'm building an test app to send push notifications here is my code:
static func sendRequestPush(){
let json: [String: Any] = ["to": "key",
"priority": "high",
"notification": ["body":"Hello1", "title":"Hello world","sound":"default"]]
let urlStr:String = "https://fcm.googleapis.com/fcm/send"
let url = URL(string:urlStr)
let jsonData = try? JSONSerialization.data(withJSONObject: json)
var request = URLRequest(url: url!)
request.httpMethod = "POST"
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON)
}
}
task.resume()
}
The problem is I don't get any response from googleapis neither the push notification. I get the push notification from dash board but not from my code.
Any of you knows what I'm doing wrong?
I'll really appreciate your help.
Try the below code, It works like charm :)
func sendRequestPush() {
// create the request
let url = URL(string: "https://fcm.googleapis.com/fcm/send")
let request = NSMutableURLRequest(url: url!)
request.httpMethod = "POST"
request.setValue("key=putYourLegacyServerKeyHere", forHTTPHeaderField: "authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let parameters = ["to": "putYourFCMToken",
"priority": "high",
"notification": ["body":"Hello1", "title":"Hello world","sound":"default"]] as [String : Any]
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) // pass dictionary to nsdata object and set it as request body
} catch let error {
print(error.localizedDescription)
}
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let dataTask = session.dataTask(with: request as URLRequest) { data,response,error in
let httpResponse = response as? HTTPURLResponse
if (error != nil) {
print(error!)
} else {
print(httpResponse!)
}
guard let responseData = data else {
print("Error: did not receive data")
return
}
do {
guard let responseDictionary = try JSONSerialization.jsonObject(with: responseData, options: [])
as? [String: Any] else {
print("error trying to convert data to JSON")
return
}
print("The responseDictionary is: " + responseDictionary.description)
} catch {
print("error trying to convert data to JSON")
return
}
DispatchQueue.main.async {
//Update your UI here
}
}
dataTask.resume()
}
"putYourLegacyServerKeyHere" change this according to your key that you can get in FCM Console
"putYourFCMToken" change this with the fcm token you got in didReceiveRegistrationToken (FCM Delegate)

My url is not responding

Hi there I'm trying to make a post request so I made a class, a simple class to test the url but is not responding, I mean I can use other url different to the url that I suppose to use and It's responding so the request it's ok what is not working is the url. The weird thing is that in postman the url is working the server response ok. I also enable the app transport security allow arbitrary load to yes and still not working could you have any idea why is this? Thanks in advance.
Here is my code
#IBAction func buton(_ sender: Any) {
let parameters: [String : Any] = ["acceptPrivacyNotice": true,
"name": "xxxx xxxx",
"email":"xxx#mail.com",
"password": "qwerty2012",
"passwordConfirm": "qwerty2012",
"deviceID": "",
"isProvider": false,
"idTypeProvider":1 ]
guard let url = URL(string: "https://www.apps-sellcom-dev.com/Engie/api/account/register") else {return}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("YOURAPIKEY==", forHTTPHeaderField: "Authorization")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else {
return
}
request.httpBody = httpBody
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print("Response",response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
} catch {
print(error)
}
}
}.resume()
}
The certificate of the domain is about to expire, so I guess thats why the URL wasn't found.
I enabled the app transport security and set the URL in the info.plist using LSApplicationQueriesSchemes, and now I'm getting a response from the server.

FCM unable receive push notification after app ugrade

I am using FCM for my app. In first build I have successfully added firebase. Then I have upgraded app to new version and it doesn't receive any push notification.
Even firebase server call retruns proper device data, i.e. whether the device is registered or not. Here is the code:
func getUserTopicSubscribeWithToken() {
print("getUserTopicSubscribeWithToken")
var token = ""
if Messaging.messaging().fcmToken != nil {
token = Messaging.messaging().fcmToken!
}
let urlString = "https://iid.googleapis.com/iid/info/\(token)?details=true"
let url = URL(string: urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!)
var request = URLRequest(url: url!)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("key=\(serverKey)", forHTTPHeaderField: "Authorization")
let session = URLSession.shared
session.dataTask(with: request) {data, response, err in
print("Entered the completionHandler")
if (data != nil && err == nil) {
if let topics = String.init(data: data!, encoding: .utf8) {
print("topics :: \(topics)")
let cleanResult = topics.replacingOccurrences(of: "\\", with: "")
if let dict = JSONResultHelper.convertToDictionary(text: cleanResult) {
print("dict :: \(dict)")
if let allTopics = dict["rel"] as? [String:Any] {
print("allTopics :: \(allTopics)")
if let values = allTopics["topics"] as? [String:Any] {
print("values :: \(values)")
for key in values.keys {
AppDelegate.sharedInstance.moduleManager().apiModule?.subscribeToChannel(channelName: key)
}
}
}
}
}
}
}.resume()
}
This call gives me fcm details as expected.
I have also tried to send notification to single device using fcm token, but It didn't work.
Please Note:
It is working perfectly fine on fresh install but not on upgraded one.

Resources