How to send actionable notifications to iOS with FireBase?
Asked Answered
S

3

16

We are currently evaluating Firebase as a future push notification service. Is there a way to send actionable notifications to iOS devices? At the moment we use parse to send pushes, we set the "category" parameter in the payload and the additional actions on the notifications are working. We tried to set this parameter in the firebase console or via the firebase rest api, but the notification actions are not working, it seems the payload is somehow different then iOS expects.

Stopover answered 25/8, 2016 at 6:1 Comment(0)
S
33

Thanks Malik for the answer. FCM seems to translate the android specific "click_action" property to the iOS specific "category" property.

We send firebase push notifications via their REST API, which can be easily used for testing with postman.

Here is the REST version:

POST https://fcm.googleapis.com/fcm/send

Headers:

  • Authorization: key=YOUR_FIREBASE_SERVER_KEY
  • Content-Type: application/json

Body:

{ "notification": {
    "text": "YOUR_PUSH_TEXT",
    "click_action":"YOUR_IOS_ACTIONABLE_NOTIFICATION_CATEGORY"
  },
  "to" : "YOUR_PUSH_TOKEN",
  "data": {
    "YOUR_CUSTOM_DATA": "DATA"
  }
}
Stopover answered 1/9, 2016 at 12:8 Comment(1)
Please change the "text" in "notification" field into "title" and "body". I tried several times and it never work, until I made the change.Eisk
P
14

Currently categories not supported in FCM console but still if you want to test you can use curl post call and test. You can add category to your payload from your server and use FCM api to push notification to iOS.

curl --header "Authorization: key=<YOUR_SERVER_KEY>" --header Content-  Type:"application/json" https://fcm.googleapis.com/fcm/send  -d "{\"to\":\"Device Token\",\"priority\":\"high\",\"notification\": {\"title\": \"Shift Alert\",\"text\": \"Would you like to accept  shift today 11:30 to 13:30  \",\"click_action\":\"INVITE_CATEGORY\"}}"

Authorization: key=YOUR_SERVER_KEY Make sure this is the server key, whose value is available in your Firebase project console under Project Settings > Cloud Messaging. Android, iOS, and browser keys are rejected by FCM.

INVITE_CATEGORY = Your category you using in your code

below is response dictionary you will get on action tap:

{
aps =     {
    alert =         {
        body = "Would you like to accept shift today 11:30 to 13:30  ";
        title = "Shift Alert";
    };
    category = "INVITE_CATEGORY";
};
"gcm.message_id" = "0:12233487r927r923r7329";
}
Peacoat answered 30/8, 2016 at 9:42 Comment(1)
there are two wrong spaces in the request in "Content- Type", here the correct version: curl --header "Authorization: key=<YOUR_SERVER_KEY>" --header Content- Type:"application/json" https://fcm.googleapis.com/fcm/send -d "{\"to\":\"Device Token\",\"priority\":\"high\",\"notification\": {\"title\": \"Shift Alert\",\"text\": \"Would you like to accept shift today 11:30 to 13:30 \",\"click_action\":\"INVITE_CATEGORY\"}}"Stopover
P
4

I created a simple JS method for my local pc to send push notification with category. I'm using Node.

function sendFirebaseNotification(title, body, postId, postUrl, topic) {

  var fbAdmin = require('firebase-admin');
  var serviceAccount = require('./your_credential_file.json'); //download from firebase admin page and specify in your local machine
  var app = fbAdmin.initializeApp({
      credential: fbAdmin.credential.cert(serviceAccount)
  });

  var message = {
    apns: {
      payload: {
        aps: {
            alert: {
              title: title,
              body: body
            },
            category: "VIEW_NOTIFICATION" //your ios category
        },
        id: postId, //extra data
        title: title, //extra data
        url: postUrl //extra data
      }
    },
    topic: topic //your ios app should subscribe to this topic (or you can use a specific token here).
  };

  // Send above message
  fbAdmin.messaging().send(message)
    .then((response) => {
      // Response is a message ID string.
      console.log('Successfully sent message:', response);
      process.exit();
    })
    .catch((error) => {
      console.log('Error sending message:', error);
      process.exit();
    });
}

Simple call

sendFirebaseNotification(title, description, id, url, topic);

IOS handle:

//Call when application loaded
func registerNotification(_ application: UIApplication) {
    //Firebase callback
    Messaging.messaging().delegate = self
    Messaging.messaging().subscribe(toTopic: YOUR_TOPIC_NAME) { error in
      print("Subscribed to notification topic")
    }

    //IOS Notification (ios 10 and above)
    UNUserNotificationCenter.current().delegate = self
    UNUserNotificationCenter.current().requestAuthorization(
                                   options: [.alert, .badge, .sound],
                                   completionHandler: {_, _ in })
    application.registerForRemoteNotifications()

    //Add custom actions
    let acceptAction = UNNotificationAction(identifier: "view_now",
                                            title: "Xem ngay",
                                            options: .foreground)

    let skipAction = UNNotificationAction(identifier: "skip",
                                            title: "Bỏ qua",
                                            options: .foreground)

    // Define the notification type
    let viewCategory =
          UNNotificationCategory(identifier: "VIEW_NOTIFICATION", //category name
          actions: [acceptAction, skipAction],
          intentIdentifiers: [],
          hiddenPreviewsBodyPlaceholder: "",
          options: .customDismissAction)

    // Register the notification type.
    let notificationCenter = UNUserNotificationCenter.current()
    notificationCenter.setNotificationCategories([viewCategory])
}


func viewNotification(_ userInfo: [AnyHashable : Any]) {
    //handle extra data
    let id = (userInfo["id"] as? String) ?? ""
    let title = (userInfo["title"] as? String) ?? ""
    let url = userInfo["url"] as? String

    NotificationService.shared.viewNotification(id, title: title, url: url)
}

//MARK: UNUserNotificationCenterDelegate
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    completionHandler(.alert)
}

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

    // if user tap or response to not "skip" action we can handle here 
    let userInfo = response.notification.request.content.userInfo
    if response.actionIdentifier != "skip" {
        viewNotification(userInfo)
    }

    // Always call the completion handler when done.
    completionHandler()

}
Phylloquinone answered 24/2, 2020 at 7:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.