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

How to send actionable notifications to iOS with FireBase?

我们目前正在评估 Firebase 作为未来的推送通知服务。 有没有办法向 iOS 设备发送可操作的通知? 在我们使用 parse 发送推送的那一刻,我们在有效负载中设置了 "category" 参数,通知上的其他操作正在运行。 我们尝试在 firebase 控制台或通过 firebase rest api 设置此参数,但通知操作不起作用,似乎有效载荷与 iOS 预期的有所不同。

当前 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 项目控制台中可用。 Android、iOS 和浏览器密钥被 FCM 拒绝。

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

感谢 Malik 的回答。 FCM 似乎将 android 特定的 "click_action" 属性 翻译成 iOS 特定的 "category" 属性.

我们通过他们的 REST API 发送 firebase 推送通知,这可以很容易地用于邮递员的测试。

这是 REST 版本:

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

Headers:

  • 授权: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"
  }
}

我为我的本地电脑创建了一个简单的 JS 方法来发送带有类别的推送通知。我正在使用节点。

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

}