Firebase静默apns通知

t2a7ltrp  于 2023-11-21  发布在  其他
关注(0)|答案(6)|浏览(159)

有没有一种方法可以使用谷歌的firebase发送一个无声的APNS?似乎如果应用程序在后台,它总是会向用户显示一个通知。
谢谢?

r9f1avp5

r9f1avp51#

您可以使用FCM服务器API https://firebase.google.com/docs/cloud-messaging/http-server-ref发送静默APNS消息
特别需要用途:

*data字段:

此参数指定消息负载的自定义键值对。
例如,对于data:{“score”:“3x 1”}:
在iOS上,如果消息是通过APNS发送的,则表示自定义数据字段。如果是通过FCM连接服务器发送的,则表示为AppDelegate应用程序中的键值字典:didReceiveRemoteNotification:。
键不应该是保留字(“from”或任何以“google”或“gcm”开头的字)。不要使用此表中定义的任何字(如collapse_key)。
建议使用字符串类型的值。您必须将对象或其他非字符串数据类型(例如,整数或布尔值)中的值转换为字符串

*content_available字段:

在iOS上,使用此字段表示APNS负载中的可用内容。当发送通知或消息时,此字段设置为true,将唤醒非活动的客户端应用。在Android上,默认情况下,数据消息会唤醒应用。在Chrome上,目前不支持。
完整文档:https://firebase.google.com/docs/cloud-messaging/http-server-ref#downstream-http-messages-json

sigwle7e

sigwle7e2#

对于使用FCM服务器的真正静默通知(前台和后台),请使用以下字段:

"to" : "[token]",
"content_available": true,
"priority": "high",
"data" : {
  "key1" : "abc",
  "key2" : 123
}

字符串

**注意:**请确保您在FCM中使用的是“content_available”而不是“content-available”。它已转换为APNS,否则无法正常接收。这种差异已经让我困惑了一段时间。
**更新:**大家好,请注意,这个答案是针对早期版本的FCM的,这里的答案已经过时了。请参考下面的更新答案(https://stackoverflow.com/a/56165642/2300589)以及Google的迁移文档:https://firebase.google.com/docs/cloud-messaging/migrate-v1

oyxsuwqo

oyxsuwqo3#

我在我的博客上详细解释了这个主题。http://blog.boxstory.com/2017/01/how-to-send-silent-push-notification-in.html

**关键点为:“content_available:true”

这是JSON示例

{
    "to" : "<device>",
    "priority": "normal",
    "content_available": true, <-- this key is converted to 'content-available:1'
    "notification" : {
      "body" : "noti body",
      "title" : "noti title",
      "link": "noti link "
    }
}

字符串
注意事项:如果发送了上面的示例JSON,则用户将看到通知。如果不希望用户看到推送通知,请使用下面的命令。

{
  "to": "<device>",
  "priority": "normal",
  "content_available": true <-- this key is converted to 'content-available:1'
}

qyyhg6bp

qyyhg6bp4#

对于那些不使用Legacy HTTP的人,如其他答案所示,使用最新的v1 HTTP protocol,我终于找到了发送无声通知的正确方法。
使用firebase-admin的NodeJS示例:

const message = {
      apns: {
        payload: {
          aps: {
            "content-available": 1,
            alert: ""
          }
        }
      },
      token: "[token here - note that you can also replace the token field with `topic` or `condition` depending on your targeting]"
    };

    admin
      .messaging()
      .send(message)
      .then(response => {
        // Response is a message ID string.
        console.log("Successfully sent message:", response);
      })
      .catch(error => {
        console.log("Error sending message:", error);
      });

字符串
说明:

  • 看起来apns中的有效负载没有被v1 HTTP protocol中的Firebase转换,所以你需要原始的"content-available": 1
  • alert: ""也是必要的。如果你尝试使用Pusher之类的东西发送静默通知,你会发现只有content-available不能触发它。相反,添加额外的字段,如soundalert可以使它工作。参见Silent Push Notification in iOS 7 does not work。由于Firebase禁止空声音,我们可以为此使用空警报。
9rnv2umw

9rnv2umw5#

其他解决方案不适合我.我想要一个解决方案,发送数据消息到iOS和Android.
从我的测试中,我发现当我的iOS应用程序在后台时,可靠地发送数据消息的唯一方法是包含一个空的通知有效载荷。
此外,正如其他答案所提到的,您需要包含content_availablepriority
要使用curl命令进行测试,您需要FCM server key和应用程序中的FCM令牌。
示例curl命令仅适用于iOS。(可靠的数据消息,无可见通知)

curl -X POST \
  https://fcm.googleapis.com/fcm/send \
  -H 'authorization: key=server_key_here' \
  -H 'content-type: application/json' \
  -d '{
  "to": "fcm_token_here", 
  "priority": "high",
  "content_available": true,
  "notification": {
    "empty": "body"
  },
  "data": {
    "key1": "this_is_a_test",
    "key2": "abc",
    "key3": "123456",
  }
}'

字符串
将上面的server_key_herefcm_token_here替换为您自己的。
当应用程序处于后台并且不应显示UI消息时,应调用AppDelegate类中的以下方法。

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                 fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    //get data from userInfo

    completionHandler(UIBackgroundFetchResult.newData)
}


下面是如何使用云函数和 typescript 发送到主题来实现这一点。

const payload = {
    notification: {
        empty: "message"
    },
    data: {
        key1: "some_value",
        key2: "another_value",
        key3: "one_more"
    }
}

const options = {
    priority: "high",
    contentAvailable: true //wakes up iOS
}

return admin.messaging().sendToTopic("my_topic", payload, options)
    .then(response => {
        console.log(`Log some stuff`)
    })
    .catch(error => {
        console.log(error);
    });


以上似乎一直适用于iOS,有时也适用于Android。我得出的结论是,我的后端需要在发送推送通知之前确定平台才能最有效。

xuo3flqw

xuo3flqw6#

我需要向主题发送预定的通知。上面的方法对我来说都不太管用,但我最终得到了应用委托application(application:didReceiveRemoteNotification:fetchCompletionHandler:)的一致调用。下面是我在index.js云函数文件中完成的操作的完整示例(请注意,您需要"apns-push-type": "background""apns-priority": "5"头,以及aps对象中的"content-available": 1条目):

const admin = require("firebase-admin");
const functions = require("firebase-functions");

exports.sendBackgroundFetchNotification = functions.pubsub.schedule("every 1 hours").onRun((context) => {
  const message = {
    data: {},
    apns: {
      headers: {
        "apns-push-type": "background",
        "apns-priority": "5",
      },
      payload: {
        aps: {
          "content-available": 1,
          "alert": {},
        },
      },
    },
    topic: "[Topic_Name_Here]",
  };

  return admin
    .messaging()
    .send(message)
    .then(response => {
      // Response is a message ID string.
      console.log("Successfully sent message:", response);
      return null;
    })
    .catch(error => {
      console.log("Error sending message:", error);
      return null;
    });
});

字符串
如果你不想等待函数在部署后触发,只需进入Google云控制台函数部分(https://console.cloud.google.com/functions/list)并单击函数名称,然后单击“测试”,最后单击“测试函数”。
值得注意的是,这段代码使用了FCM较新的HTTP v1协议,该协议允许您基于Apple的规范构建消息对象(下面有有用的链接)。
https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messageshttps://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apnshttps://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification

相关问题