While building the push notifications feature for our iOS Chat app, we’ve encountered the need to send device to device push notifications in Swift with Firebase. Until a while ago, this was not even possible without running your own server, but fortunately, Google Cloud Messaging platform has evolved tremendously within the last year, and now sending app-to-app push notifications directly from Swift is totally doable.

Broadcasting remote push notifications from Firebase Console UI is straightforward since it only involves a few clicks on a nice GUI. But mobile apps are more complicated than that – in many cases, you need to notify a specific user about actions that were triggered by other users. A few concrete examples where we are using device to device push notifications in our Swift app templates:

  • Receiving a chat message from a different user
  • Receiving a follow or a friend request from a different user
  • Getting a new match on a dating app

Assuming you have configured your app to register and accept push notifications, and have access to the recipient’s FCM token, here’s the code snippet that will do the magic for you:

import UIKit

class PushNotificationSender {
    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()
    }
}

As you can see, you need the FCM token of the recipient, to specify what device to send the notification to. Additionally, make sure you replace SERVER-KEY with your own FCM server key, available in your Firebase Console.

After you add the class above to your Xcode project, sending a device to device push notification in Swift with Firebase is as easy as:

let sender = PushNotificationSender()
sender.sendPushNotification(to: "token", title: "Notification title", body: "Notification body")

As a side note, you can obtain that token using Firebase Messaging SDK, but in order to expose it to a different user, you’ll need to store it in a database somehow (do you have an “users” table maybe?). This is where Firebase Firestore comes into play. We have published a Github repo, that does all of this for you: generating FCM token, storing it into Firestore, retrieving it from Firestore and sending app to app push notifications. Please give us a star on Github if you find our Swift project helpful.

As a pro-tip, make sure you test your code on a real physical¬†device since push notifications to simulators don’t work.

Happy coding!


Leave a Reply

Your email address will not be published. Required fields are marked *