Can you set thread-id with FCM notifications for ios
Asked Answered
O

4

2

Firebase FCM messages support tag for Android which causes a new notification to replace the previous one with the older one with the same tag. Is there any way to do the same for ios?

This answer suggest using thread-id in the data payload. But it didn't work for me.

Odontology answered 10/4, 2018 at 16:6 Comment(0)
L
5

There is no thread-id FCM payload key in Legacy FCM HTTP Server protocol. The workaround is to use iOS Notification Service Extension. Send the grouping identifier as "thread-id" key in FCM data payload and let the service extension read the "thread-id" key and set it to the notification content's threadIdentifier property.

class NotificationService: UNNotificationServiceExtension {
    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
        let userInfo: [AnyHashable : Any] = (bestAttemptContent?.userInfo)!  
        if let apsInfo = userInfo["aps"] as? [AnyHashable: Any], let bestAttemptContent = bestAttemptContent  {                
            //add thread-id to group notification.
            let patientId = userInfo["thread-id"] as! String
            bestAttemptContent.threadIdentifier = patientId
            contentHandler(bestAttemptContent)
        }
    }
}
Lingo answered 10/10, 2018 at 19:28 Comment(1)
Can you pls explain where I should add this code? I'm using Ionic/Cordova.Odontology
G
3

Yes, you can set thread-id with FCM, but it serves to group notifications. What you actually need to replace old notifications by new ones is apns-collapse-id

Use the same thread-id to visually group multiple notifications together. Multiple notifications with the same thread-id are grouped and appear as a stack. Tapping on the stack expands all notifications with the most recent one being on top.

There's a collapseKey option which can be used to skip sending outdated notifications. If the device didn't receive a bunch of notifications and there's a newer one with the same key - only the latest will be pushed. It seems this would also work to replace old notifications on Android, but not on iOS.

As per delivery options there's an apple specific key: apns-collapse-id

What's a collapsible message

A collapsible message is a message that may be replaced by a new message if it has yet to be delivered to the device.

Quoted from: Non-collapsible and collapsible messages

Setting apns-collapse-id

apns-collapse-id can be set using the lower level messaging APIs - send, sendAll and sendMulticast, where you can specify an apns key

It's set in the apns.headers

const payload = {
 tokens: [/*...*/],
 data: {/*...*/},
 notification: {
   title: 'My Title',
   body: 'My Content',
 },
 apns: {
   headers: {
     'apns-collapse-id': doc.id,
   },
   payload: {
     aps: {
       sound: 'default',
     },
   },
 },
};

admin.messaging().sendMulticast(payload);

Setting thread-id

threadId can be set using the lower level messaging APIs - send, sendAll and sendMulticast, where you can specify an apns key

It's set in the apns.payload.aps:

const payload = {
 tokens: [/*...*/],
 data: {/*...*/},
 notification: {
   title: 'My Title',
   body: 'My Content',
 },
 apns: {
   payload: {
     aps: {
       threadId: doc.id,
       sound: 'default',
     },
   },
 },
};

admin.messaging().sendMulticast(payload);

threadId behavior while offline

For me there are 2 cases:

  1. Sending a few notifications results in the latest being received when the device regains connectivity

  2. Be offline with existing (non dismissed) notification(s) for a given threadId. Regaining connectivity would add the latest notification to the top of the stack

Setting collapseKey

Higher level messaging APIs like sendToDeivce cannot tweak apns directly but can specify options

One of those options is options.collapseKey

const tokens = [/*...*/];

const payload = {
 data: {/*...*/},
 notification: {
   title: 'My Title',
   body: 'My Content',
   sound: 'default',
 },
};

const options = {
  collapseKey: doc.id,
}

const response = await admin.messaging().sendToDevice(
  tokens,
  payload,
  options,
);
Gosselin answered 1/3, 2022 at 13:5 Comment(0)
D
2

As I mentioned in my answer that you linked:

However, there is currently no parameter counterpart for thread-id in FCM.

The workaround I mentioned is putting the thread-id in the data payload as a custom key value pair wasn't tested (I haven't dabbled with iOS that much so it was a long shot). But logically, if you're able to get the value of the data payload, you should be able to use the value as needed.

Alas, there still isn't any native way to set the thread-id parameter in the iOS payload. The only supported parameters are what is mentioned in the FCM docs.

Dominations answered 11/4, 2018 at 16:44 Comment(1)
You can set thread-id on the data payload and it will come thru just fine.Cyprinodont
D
0

FCM's HTTP v1 API should support thread-id. Check out the APNS field in https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages

Drucie answered 20/6, 2018 at 22:18 Comment(2)
Can you give an example where to place the thread-id to make this work? I tried it this way, but didn't work: "apns": {"payload": {"thread-id": "1234" }, },Essa
Should be treated as a data payload: "payload": { "aps": { "alert": { "body" : "Do you know FCM supports watchOS now?", "title" : "Hello watch!", }, }, "thread-id": "1234", },Drucie

© 2022 - 2024 — McMap. All rights reserved.