如何使用FireBase向iOS发送可操作通知?

16

我们目前正在评估Firebase作为未来的推送通知服务。是否有一种方法发送可操作的通知到iOS设备?目前,我们使用Parse发送推送通知,我们在负载中设置“category”参数,并且通知上的其他操作都有效。我们尝试在Firebase控制台或通过Firebase REST API中设置此参数,但通知操作不起作用,似乎负载与iOS期望的不同。

3个回答

32

感谢Malik的答案。FCM似乎将安卓特定的“click_action”属性翻译成了iOS特定的“category”属性。

我们通过他们的REST API发送Firebase推送通知,这可以很容易地在Postman上进行测试。

这是REST版本:

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"
  }
}

请将“通知”字段中的“文本”更改为“标题”和“正文”。我尝试了几次,但一直无法成功,直到我进行了更改。 - Terry Windwalker

14

目前在FCM控制台中不支持分类,但是如果您想进行测试,可以使用curl post调用进行测试。您可以从服务器向有效载荷添加类别,并使用FCM API向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\"}}"

授权: key=YOUR_SERVER_KEY 请确保这是服务器密钥,其值在 Firebase 项目控制台下的项目设置 > 云消息传递中可用。FCM 将拒绝 Android、iOS 和浏览器密钥。

INVITE_CATEGORY = 您在代码中使用的类别

以下是您在操作点击时将获得的响应词典:

{
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";
}

2
在"Content-Type"请求中有两个错误的空格,这里是正确的版本: 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\"}}" - simsimmal

3

我为我的本地PC创建了一个简单的JS方法,用于发送带有类别的推送通知。我正在使用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();
    });
}

简单调用

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

IOS 处理:

//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()

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接