如何使用 Firebase 云消息设置图像?

Posted

技术标签:

【中文标题】如何使用 Firebase 云消息设置图像?【英文标题】:how to set image with firebase cloud messaging? 【发布时间】:2021-05-23 12:43:20 【问题描述】:

我正在尝试通过 Firebase 云消息发送推送通知,并成功发送仅针对文本的推送通知,但在发送带有图像的通知时遇到问题。我尝试了一些来自 medium 和 raywenderlich 的文档,但无法发送带有图像的通知。我在我的项目中添加了通知扩展并尝试了这段代码:

    var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?

override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) 
    self.contentHandler = contentHandler
    bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

    guard let bestAttemptContent = bestAttemptContent,
    let attachmentURLAsString = bestAttemptContent.userInfo["image"] as? String,
    let attachmentURL = URL(string: attachmentURLAsString) else
        return
    
    downloadImageFrom(url: attachmentURL)  (attachment) in
        if let attachment = attachment 
            bestAttemptContent.attachments = [attachment]
            contentHandler(bestAttemptContent)
        
    



private func downloadImageFrom(url: URL, with completionHandler: @escaping (UNNotificationAttachment?) -> Void)
    let task = URLSession.shared.downloadTask(with: url)  (downloadedUrl, response, error) in
        guard let downloadUrl = downloadedUrl else
            completionHandler(nil)
            return
        
        var urlPath = URL(fileURLWithPath: NSTemporaryDirectory())
        let uniqueURLEnding = ProcessInfo.processInfo.globallyUniqueString + ".jpg"
        urlPath = urlPath.appendingPathComponent(uniqueURLEnding)
        try? FileManager.default.moveItem(at: downloadUrl, to: urlPath)
        do
            let attachment = try UNNotificationAttachment(identifier: "picture", url: urlPath, options: nil)
            completionHandler(attachment)
        catch
            completionHandler(nil)
        
    
    task.resume()

但仍然没有显示图像,请注意:我正在尝试从 firebase 控制台发送图像。我不知道如何找出问题或解决问题。

【问题讨论】:

首先要做的是一些故障排除;添加一个断点,当应用程序接收到通知时,逐行检查变量,直到您看到不正确的内容。例如,可能接收到的 URL 格式错误;您只有在检查了代码后才会知道。您也没有错误处理;例如在downloadImageFrom 中,如果downloadUrl 为nil,则代码将静默失败,您将不知道为什么。你也忽略了可能的错误downloadTask(with: url) (downloadedUrl, response, error) 等等错误,你不会知道的。 【参考方案1】:

必须通过添加断点来检查您的问题,并且当应用接收到通知时,逐行检查变量,直到您看到不正确的地方。

我正在分享最适合我的代码。

var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?

override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void)  
    self.contentHandler = contentHandler
    bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)  


override func serviceExtensionTimeWillExpire() 
    // Called just before the extension will be terminated by the system.
    // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
    if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent 
        contentHandler(bestAttemptContent)
    

并为UNNotificationAttachment写一个扩展

extension UNNotificationAttachment 
static func saveImageToDisk(fileIdentifier: String, data: NSData, options: [NSObject : AnyObject]?) -> UNNotificationAttachment? 
    let fileManager = FileManager.default
    let folderName = ProcessInfo.processInfo.globallyUniqueString
    let folderURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(folderName, isDirectory: true)
    do 
        try fileManager.createDirectory(at: folderURL!, withIntermediateDirectories: true, attributes: nil)
        let fileURL = folderURL?.appendingPathComponent(fileIdentifier)
        try data.write(to: fileURL!, options: [])
        let attachment = try UNNotificationAttachment(identifier: fileIdentifier, url: fileURL!, options: options)
        return attachment
     catch let error 
        print("error \(error)")
    
    
    return nil
 

【讨论】:

添加后我可以使用firebase控制台发送图像吗?还是我需要使用邮递员或推送器? 您可以使用 firebase 控制台本身发送。不需要邮递员。 图像测试-3, AnyHashable("gcm.message_id"): 1621834465327725, AnyHashable("aps"): alert = body = "bla bla";标题=“图像测试-3”; ;徽章 = 0; “可变内容”= 1; , AnyHashable("google.c.a.e"): 1, AnyHashable("google.c.a.udt"): 0, AnyHashable("fcm_options"): image = "images.unsplash.com/photo-1589802829985-817e51171b92?ixlib=rb; 这是我收到的回复,但通知中没有显示任何图像 您能否向我推荐任何有助于我理解整个过程的文档或教程?

以上是关于如何使用 Firebase 云消息设置图像?的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 云消息传递通知图像定价

如何使用 Firebase 托管来托管图像?

iOS Swift 使用 Firebase 云消息发送丰富的推送通知

Firebase 云消息传递 - 如何向 APN 添加声音

使用 Flutter 测试 Firebase 云消息传递

以编程方式发送 Firebase 云消息?