简体   繁体   中英

In iOS Firebase Cloud Messaging (FCM), send APNS to topic but other than sender from iphone

Subscribe a topic to send APNS to all the devices :

//subscribe to topic to send message to multiple device
Messaging.messaging().subscribe(toTopic: "alldevices")

Note : 'all devices' is name of topic where all the subcribed devices will get APNS

Send APNS to all devices programatically through topic like given below :

func sendPushMessage(todoItem:TodoItem, isAdded:Bool = true) {

    let url = URL(string: "https://fcm.googleapis.com/fcm/send")!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    let strKey:String = "Here FCM Server Key"
    request.setValue("key=\(strKey)", forHTTPHeaderField: "Authorization")

    var message:String = ""
    if isAdded {
        message = "Todo with title '\(todoItem.title)' added"
    }
    else{
        message = "Todo with title '\(todoItem.title)' removed"
    }

    let dictData = ["to":"/topics/alldevices","priority":"high","notification":["body":message,"title":"Community","badge":"1"]] as [String : Any]

    do {
        let jsonData = try JSONSerialization.data(withJSONObject: dictData, options: .prettyPrinted)
        // here "jsonData" is the dictionary encoded in JSON data

        request.httpBody = jsonData

        let task = URLSession.shared.dataTask(with: request, completionHandler: { (responseData: Data?, response: URLResponse?, error: Error?) in

            let strData :String = String(data: responseData!, encoding: String.Encoding.utf8)!
            print("data : \(strData)")
            NSLog("\(String(describing: response) )")
        })
        task.resume()

    } catch {
        print(error.localizedDescription)
    }
}

Problem here is sender (user using app) also gets APNS as sender is too subscribed to topic 'alldevices'. But technically sender doesn't need APNS as sender himself generated APNS for all other devices

Note : we don't have separate server to send or manage APNS. FCM sole here manages APNS for us.

I don't think you can do this via the API. Perhaps via the notification section of your Firebase console using 'user audience(s)', but that obviously won't solve your issue. Perhaps this might be achievable in the future when/if the Firebase API starts supporting user audiences.

One thing you could look into is sending a 'data' message, instead of a 'display' message.

This would send a 'silent' notification to all other users, and once received the client phone would then decide if the notification needs to be displayed.

For example, your firebase post would change to use the 'data' object, instead of the 'notification' object

{
  "to": "/topics/alldevices",
  "content_available": true,
  "data": {
    "sender": "{{this_phones_uuid}}"
  },
  "priority": "high"
}

Where 'sender' is a unique identifier you've created and stored on the users phone.

When receiving the notification you would only display a notification if the 'sender' value does not equal the UUID stored on the phone.

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        if let sender = userInfo["sender"] as? String {
            if sender != {{your_stored_uuid}} {
                let notification = UNMutableNotificationContent()
                notification.title = "title"
                notification.body = "body"
                let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 1, repeats: false)
                let request = UNNotificationRequest.init(identifier: "todo", content: notification, trigger: trigger)
                UNUserNotificationCenter.current().add(request)
            }
        }
    }

You might want to look into reliability before using this method as silent notifications can be throttled by the OS, and sometimes not even delivered.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM