Firebase无声apns通知

roi*_*erg 24 push-notification apple-push-notifications firebase silentpush firebase-cloud-messaging

有没有办法使用google的firebase发送静音APNS?似乎如果应用程序在后台,它将始终向用户显示通知.

谢谢?

Die*_*ini 36

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

特别需要使用:

  • 数据字段:

此参数指定消息的有效内容的自定义键值对.

例如,使用数据:{"score":"3x1"}:

在iOS上,如果消息是通过APNS发送的,则表示自定义数据字段.如果它是通过FCM连接服务器发送的,它将在AppDelegate应用程序中表示为键值字典:didReceiveRemoteNotification:.

密钥不应该是保留字("from"或任何以"google"或"gcm"开头的单词).不要使用此表中定义的任何单词(例如collapse_key).

建议使用字符串类型中的值.您必须将对象或其他非字符串数据类型(例如,整数或布尔值)中的值转换为字符串

  • 内容提供领域:

在iOS上,使用此字段表示APNS有效内容中可用的内容.发送通知或消息并将其设置为true时,将唤醒非活动的客户端应用程序.在Android上,数据消息默认唤醒应用程序.在Chrome上,目前不支持.

完整文档:https: //firebase.google.com/docs/cloud-messaging/http-server-ref#downstream-http-messages-json

  • 嗨,我有一个类似的场景,但需要稍作修改,比如当我收到推送通知时,应用程序应该在后台激活并执行中给出的任务,(如用户的位置更新代码),-(无效)应用程序:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo ,但我的应用程序在用户点击通知之前不会激活。那么,当应用程序处于后台时,我将如何完成这项工作?有人知道解决方案吗? (2认同)
  • @Moxarth 即使我也在为同样的问题苦苦挣扎。你能解决这个问题吗? (2认同)

c0d*_*ded 30

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

"to" : "[token]",
"content_available": true,
"priority": "high",
"data" : {
  "key1" : "abc",
  "key2" : 123
}
Run Code Online (Sandbox Code Playgroud)

注意:确保在FCM 中使用"content_available" 而非 "content-available".它已转换为APNS,否则将无法正确接收.差异使我绊倒了一段时间.


小智 10

我在博客上详细解释了这个主题. 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 "
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:如果发送了上述示例JSON,则该通知将对用户可见.使用下面如果您不希望用户看到推送通知.

{
  "to": "<device>",
  "priority": "normal",
  "content_available": true <-- this key is converted to 'content-available:1'
}
Run Code Online (Sandbox Code Playgroud)

  • 不要在通知内发送正文,标题,链接,否则用户将收到可见的通知.如果要发送完全静默通知,请在通知中添加一些自定义参数或将其保留为空.你可以参考这个链接,/sf/ask/3343917951/#47811722. (3认同)
  • 始终欢迎指向潜在解决方案的链接,但请[在链接周围添加上下文](http://meta.stackexchange.com/a/8259),以便您的其他用户了解它是什么以及为什么它在那里。始终引用重要链接中最相关的部分,以防目标站点无法访问或永久离线。请考虑到,仅仅一个到外部站点的链接是[为什么以及如何删除某些答案?](http://stackoverflow.com/help/deleted-answers)的一个可能原因。 (2认同)

Rui*_*ing 7

对于那些不使用Legacy HTTP其他答案中所示并使用最新的人v1 HTTP protocol,我终于找到了发送静默通知的正确方法。

NodeJS 示例使用firebase-admin

    const message = {
      apns: {
        payload: {
          aps: {
            "content-available": 1,
            alert: ""
          }
        }
      }
    };

    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);
      });
Run Code Online (Sandbox Code Playgroud)

解释:

  • 似乎apnsFirebase 中的有效载荷没有被转换,v1 HTTP protocol所以你需要原始"content-available": 1的。
  • alert: ""也是必要的。如果您曾尝试使用类似 的方式发送静默通知Pusher,您会发现只能content-available触发它。相反,添加额外的字段,例如soundalert可以使其工作。请参阅iOS 7 中的静默推送通知不起作用。由于 Firebase 禁止空声音,我们可以为此使用空警报。


Mar*_*ark 5

其他解决方案对我不起作用。我想要一个能够向 iOS 和 Android 发送数据消息的解决方案。

根据我的测试,我发现当我的 iOS 应用程序在后台时可靠地发送数据消息的唯一方法是包含一个空的通知负载。

另外,正如其他答案所提到的,您需要包含content_availablepriority

要使用curl命令对此进行测试,您需要FCM服务器密钥和应用程序中的FCM令牌。

仅适用于 iOS 的示例curl 命令。(可靠的数据消息,无可见通知)

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",
  }
}'
Run Code Online (Sandbox Code Playgroud)

server_key_herefcm_token_here以上替换为您自己的。

AppDelegate当应用程序在后台且不应该显示任何 UI 消息时,应调用类中的以下方法。

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

    completionHandler(UIBackgroundFetchResult.newData)
}
Run Code Online (Sandbox Code Playgroud)

下面介绍了如何使用云函数和打字稿发送到主题来执行此操作。

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);
    });
Run Code Online (Sandbox Code Playgroud)

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