Vincenzo
Vincenzo

Reputation: 6388

Push notification Localization are displayed in the sending device language, not in the receiving one. Swift

I am translating my app and I'm having an issue with remote notifications. Following documentation

Storing Localized Content in Your App Bundle

If you use a consistent set of messages for your notifications, you can store localized versions of the message text in your app bundle and use the loc-key and loc-args keys in your payload to specify which message to display. The loc-key and loc-args keys define the message content of the notification. When present, the local system searches the app’s Localizable.strings files for a key string matching the value in loc-key. It then uses the corresponding value from the strings file as the basis for the message text, replacing any placeholder values with the strings specified by the loc-args key. (You can also specify a title string for the notification using the title-loc-key and title-loc-args keys.)

I have NSLocalizedString for title, subtitle and body. The problem is that when I send the notification from a English set device, I get an English remote notification on an Italian set device. I'm storing all Localized key:value pair in the Localizable.string file so as I understood it to work, on receiving the notification the values from the current device language should be taken from the Localizable.string file and get displayed. I do the same for all the alert pups and it works perfectly there, but on remote notifications it keeps the language of the sending device. I'm using FCM for the remote notifications, so I might miss to pass some value in the payload. Can you see something missing in the payload? Many thanks.

static func sendPushNotification(to receiverToken: String, title: String, subtitle: String, body: String) {
        print("PushNotifications.sendPushNotification Started")
        let serverKey = firebaseServerKey
        let url = NSURL(string: "https://fcm.googleapis.com/fcm/send")

        let postParams: [String : Any] = [
            "to": receiverToken,
            "mutable_content": true,
            "content_available": true,
            "priority": "high",
            "notification": [
                //                    "badge" : 1, sendig the badge number, will cause aglitch
                // receiving device localized parameters
                "title_loc_key" : title,
                "subtitle_loc_key" : subtitle,
                "body_loc_key" : body,
                "sound" : true, // or specify audio name to play
            ],
            "data" : [
                "data": "ciao",
            ]
        ]

        let request = NSMutableURLRequest(url: url! as URL)
        request.httpMethod = "POST"
        request.setValue("key=\(serverKey)", forHTTPHeaderField: "Authorization")
        request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")

        do {
            //                request.httpBody = try JSONSerialization.data(withJSONObject: postParams, options: JSONSerialization.WritingOptions())
            request.httpBody = try JSONSerialization.data(withJSONObject: postParams, options: [.prettyPrinted]) // working
            print("My paramaters: \(postParams)")
        } catch {
            print("Caught an error: \(error)")
        }

        let task = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in
            if let realResponse = response as? HTTPURLResponse {
                if realResponse.statusCode != 200 {
                    print("Not a 200 response")
                }
            }




            if let posData = data {
                if let postString = String(data: posData, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) as String? {
                    print("POST: \(postString)")
                }
            }
        }

        task.resume()
    }

This is the function calling:

PushNotifications.sendPushNotification(to: customerFcmToken, title: String(format: NSLocalizedString( "ORDER_DELETED_PUSH_TITLE", comment: ""), orderId), subtitle: String(format: NSLocalizedString( "ORDER_DELETED_PUSH_SUBTITLE", comment: ""), UserDetails.fullName!), body: String(format: NSLocalizedString("ORDER_DELETED_PUSH_BODY", comment: "") , customerName))

Upvotes: 2

Views: 2924

Answers (2)

Vincenzo
Vincenzo

Reputation: 6388

I post an answer so to make a good recap for others stumbling upon this. Main problem, as stated in the accepted answer, was that I was passing a "localised" String instead of a "reference" String for Localisation to get values from proper Localizable.string file. As my Localizable.string strings have a format, loc-argsare also needed to be passed with the payload in order to swap placeholders for values. I had them in %1@, %2@, etc etc form but the correct form is a plain and simple %@. So after modifications the code is:

static func sendPushNotification(to receiverToken: String, title: String, titleArgs: [String], subtitle: String, subtitleArgs: [String], body: String, bodyArgs: [String]) {
        print("PushNotifications.sendPushNotification Started")
        let serverKey = firebaseServerKey
        let url = NSURL(string: "https://fcm.googleapis.com/fcm/send")

        let postParams: [String : Any] = [
            "to": receiverToken,
            "mutable_content": true,
            "content_available": true,
            "priority": "high",
            "notification": [
                //                    "badge" : 1, sendig the badge number, will cause aglitch
                // receiving device localized parameters
                "title_loc_key" : title,
                "title_loc_args" : titleArgs,
                "subtitle_loc_key" : subtitle,
                "subtitle_loc_args" : subtitleArgs,
                "body_loc_key" : body,
                "body_loc_args" : bodyArgs,
                "sound" : true, // or specify audio name to play
            ],
            "data" : [
                "data": "ciao",
            ]
        ]

        let request = NSMutableURLRequest(url: url! as URL)
        request.httpMethod = "POST"
        request.setValue("key=\(serverKey)", forHTTPHeaderField: "Authorization")
        request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")

        do {
            //                request.httpBody = try JSONSerialization.data(withJSONObject: postParams, options: JSONSerialization.WritingOptions())
            request.httpBody = try JSONSerialization.data(withJSONObject: postParams, options: [.prettyPrinted]) // working
            print("My paramaters: \(postParams)")
        } catch {
            print("Caught an error: \(error)")
        }

        let task = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in
            if let realResponse = response as? HTTPURLResponse {
                if realResponse.statusCode != 200 {
                    print("Not a 200 response")
                }
            }

            if let posData = data {
                if let postString = String(data: posData, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) as String? {
                    print("POST: \(postString)")
                }
            }
        }

        task.resume()
    }

and it's called as :

PushNotifications.sendPushNotification(to: customerFcmToken, title: "BOOKING_DELETED_PUSH_TITLE", titleArgs: [self.bookingId], subtitle: "BOOKING_DELETED_PUSH_SUBTITLE", subtitleArgs: [UserDetails.fullName!], body: "BOOKING_DELETED_PUSH_BODY", bodyArgs: [customerName])

Thank you again.

Upvotes: 0

m1sh0
m1sh0

Reputation: 2351

I got it you calling

PushNotifications.sendPushNotification(to: customerFcmToken, title: String(format: NSLocalizedString( "ORDER_DELETED_PUSH_TITLE", comment: ""), orderId), subtitle: String(format: NSLocalizedString( "ORDER_DELETED_PUSH_SUBTITLE", comment: ""), UserDetails.fullName!), body: String(format: NSLocalizedString("ORDER_DELETED_PUSH_BODY", comment: "") , customerName))

And you are doing the localization, instead of sending the keys for localization.

Upvotes: 3

Related Questions