5

I would be very thankful for help with Push Notifications. My app has a chat where users can send text messages directly to each other. But without Push Notifications it doesn't make much sense. It is all set up on Firebase. How could I send Push Notifications from a specific device to a specific device? I did try Firebase Notifications and OneSignal due to a recommendation on Stackoverflow. But I am only able to trigger the notifications from Firebase or OneSignal directly and not from a specific device to a specific device.

Does someone has experience with this?

NilsBerni
  • 83
  • 2
  • 13

3 Answers3

8

If your data is being stored in Firebease I would use Cloud Messaging for Push notifications as well. There are multiple ways to achieve this messaging notification functions, I will resume the one I think is the easiest.

Assuming you are using FCM and you have configured your app for it.

First of all you need to store the token of the users device, this would be stored as a string with each of the users info:

let token = Messaging.messaging().fcmToken

So in your Firebase DB, in each of your users object data you would have a key storing a string with the token, if you want the user to receive notifications in multiple devices, you must store the multiple tokens of the user using an array of strings, or even an array of objects and store the device type, etc. Thats your choice and your needs.

The ideal push notification environment is usually composed by a middle server that receive the request and manage and send the notification to the corresponding users, in this case you can skip this and send the not directly from your app, using FCM POST request service:

Example of how to build a FCM POST request to send a notification:

let url = URL(string: "https://fcm.googleapis.com/fcm/send")!
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("key=--HERE-GOES-YOUR-API-KEY--", forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"

Here you put all not data, read the docs to understand all the keys and variables that you can send, yo would need to make a previous firebase request in which you get the device tokens.

var notData: [String: Any] = [
    "to" : "HERE YOU PUT THE DEVICE TOKEN(s)",
        "notification": [
          title : "not title",
          body  : "not body",
          icon  : "not icon"
        ],
        "data": [
          //More notification data.
      ]
]

And then you send the post request, It will return an object if the notification was succeed and more data.

request.httpBody = notData.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
    guard let data = data, error == nil else {                                                 // check for fundamental networking error
        print("error=\(error)")
        return
    }

    if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           // check for http errors
        print("statusCode should be 200, but is \(httpStatus.statusCode)")
        print("response = \(response)")
    }

    let responseString = String(data: data, encoding: .utf8)
    print("responseString = \(responseString)")
}
task.resume() 

I've been using this same solution for a mobile native app and a react web app and it works like a charm.

j3141592653589793238
  • 1,810
  • 2
  • 16
  • 38
Karlo A. López
  • 2,548
  • 3
  • 29
  • 56
  • When you put: "to" : "HERE YOU PUT THE DEVICE TOKEN(s)", how do you seperate multiple device tokens? Do i need to put one token per notification or can I put multiple tokens separated by something like a comma? – chickenparm Mar 25 '18 at 23:03
  • The body is in JSON fromat, so you would put multiple device tokens as follows: `["token1","token2","token3","token4","token5"]` – Karlo A. López Mar 26 '18 at 01:25
  • 2
    *firebaser here* The approach you outline may technically work, but introduces a big security risk. This code requires that you put your FCM Server Key into the application (`--HERE-GOES-YOUR-API-KEY--`). As its name implies, this key should only be used on a server, or otherwise trusted environment. By embedding this key in the app, a malicious user may get it, and then can send notifications to all your users on your behalf. – Frank van Puffelen Nov 17 '18 at 15:25
  • @FrankvanPuffelen Appreciate a lot this observation, I stopped using this way of pushing nots some moths ago, now I use firebase functions as a backend alternative and its great! – Karlo A. López Nov 21 '18 at 17:49
  • @KarloA.López is it possible to send message to topics – Swift Sharp Feb 11 '19 at 07:46
  • Adding up on @KarloA.López answer, which solved the same problem I had with device to device pushes: one parameter you must pass is `"content_available": true,`in the dictionary or else `didReceiveRemoteNotification` on receiving app won't be triggered and you won't be able to use 'userInfo'. Just had this problem..you can check my question at https://stackoverflow.com/questions/56376255/push-notifications-are-delivered-but-didreceiveremotenotification-is-never-calle/56382289#56382289 – Vincenzo May 30 '19 at 16:54
4

In Swift 4, everything that Karlo posted above works fine, except for the data(using:) function is not longer available.

That will need to be something like this:

request.httpBody = try? JSONSerialization.data(withJSONObject: notData, options: [])

Once I made that change everything compiled and worked beautifully.

-1

You can target push notifications to a specific device easily. There's a tutorial given for that specific purpose here (https://firebase.google.com/docs/cloud-messaging/ios/first-message).

Now you can follow the below steps:

  1. When the 'user' sends a message to 'other user', you can send the information of 'other user' to the server.
  2. From server, you can send the push notification to the 'other user'
KrishnaCA
  • 5,615
  • 1
  • 21
  • 31