使用Firebase iOS Swift从特定设备向特定设备推送通知

5
我希望你能帮助我处理推送通知。我的应用程序有一个聊天功能,用户可以直接向彼此发送文本消息。但是没有推送通知就没有多大意义。它已经在Firebase上设置好了。我如何从特定设备向另一个特定设备发送推送通知?我尝试过Firebase通知和OneSignal,因为Stackoverflow上的建议。但是我只能直接从Firebase或OneSignal触发通知,而无法从特定设备向另一个特定设备发送通知。
有人有相关经验吗?
3个回答

8
如果您的数据存储在Firebase中,我建议您也使用Cloud Messaging来进行推送通知。有多种方法可以实现此消息通知功能,我将介绍我认为最简单的一种。
假设您正在使用FCM并已经为其配置了应用程序
首先,您需要存储用户设备的令牌,这将作为每个用户信息的字符串存储:
let token = Messaging.messaging().fcmToken

在Firebase数据库中,每个用户对象数据中都会有一个键存储令牌字符串,如果您希望用户在多个设备上接收通知,则必须使用字符串数组或甚至是对象数组存储用户的多个令牌,并存储设备类型等。这取决于您的选择和需求。
理想的推送通知环境通常由一个中间服务器组成,该服务器接收请求并管理并将通知发送给相应的用户,在这种情况下,您可以跳过此步骤并直接从您的应用程序发送通知,使用FCM POST request service
构建FCM POST请求以发送通知的示例:
let url = URL(string: "https://fcm.googleapis.com/fcm/send")!
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("key=--HERE-GOES-YOUR-API-KEY--", forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"

在此处放置所有非数据内容,请阅读文档以了解所有密钥和变量,您需要进行先前的Firebase请求,以获取设备令牌。
var notData: [String: Any] = [
    "to" : "HERE YOU PUT THE DEVICE TOKEN(s)",
        "notification": [
          title : "not title",
          body  : "not body",
          icon  : "not icon"
        ],
        "data": [
          //More notification data.
      ]
]

然后您发送POST请求,如果通知成功并返回更多数据,则会返回一个对象。

request.httpBody = notData.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
    guard let data = data, error == nil else {                                                 // check for fundamental networking error
        print("error=\(error)")
        return
    }

    if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           // check for http errors
        print("statusCode should be 200, but is \(httpStatus.statusCode)")
        print("response = \(response)")
    }

    let responseString = String(data: data, encoding: .utf8)
    print("responseString = \(responseString)")
}
task.resume() 

我已经在移动本地应用程序和React Web应用程序中使用了相同的解决方案,它的效果非常好。


当您输入:"to":"在这里放置设备令牌(s)"时,如何分隔多个设备令牌?我需要每个通知放一个令牌还是可以放置由逗号等符号分隔的多个令牌? - chickenparm
正文以JSON格式呈现,因此您可以将多个设备令牌放置如下:["token1","token2","token3","token4","token5"] - Karlo A. López
2
Firebase在此 您所概述的方法在技术上可能有效,但会引入巨大的安全风险。该代码要求您将FCM服务器密钥放入应用程序中(--HERE-GOES-YOUR-API-KEY--)。正如其名称所示,此密钥应仅在服务器或其他受信任的环境中使用。通过将此密钥嵌入应用程序中,恶意用户可能会获取它,然后可以代表您向所有用户发送通知。 - Frank van Puffelen
@FrankvanPuffelen 非常感谢您的观察,我几个月前就停止使用这种推送方式了,现在我使用 Firebase 函数作为后端替代方案,效果非常好! - Karlo A. López
@KarloA.López,是否可以向主题发送消息? - Swift Sharp
在@KarloA.López的答案基础上,解决了我遇到的设备推送问题:必须在字典中传递一个参数"content_available": true,否则接收应用程序的didReceiveRemoteNotification不会被触发,您将无法使用'userInfo'。我刚刚遇到了这个问题..您可以在https://stackoverflow.com/questions/56376255/push-notifications-are-delivered-but-didreceiveremotenotification-is-never-calle/56382289#56382289查看我的问题。 - Vincenzo

4
在Swift 4中,Karlo以上发布的所有内容都可以正常工作,除了data(using :)函数不再可用。需要像这样进行更改:
request.httpBody = try? JSONSerialization.data(withJSONObject: notData, options: [])

我进行了那个更改后,所有内容都编译并且美妙地工作了。


-1

您可以轻松地将推送通知定向到特定设备。这里提供了一个专门用于此目的的教程(https://firebase.google.com/docs/cloud-messaging/ios/first-message)。

现在,您可以按照以下步骤操作:

  1. 当“用户”向“其他用户”发送消息时,您可以将“其他用户”的信息发送到服务器。
  2. 从服务器,您可以向“其他用户”发送推送通知。

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