iosflutterpush-notification

Why is the image not appearing in iOS push notifications using Firebase Cloud Messaging?


I’m implementing push notifications with an image in my iOS app using Firebase Cloud Messaging (FCM). I've created a custom NotificationServiceExtension to handle the image download and attachment. However, the image is not showing in the notification.

Here is the code I’m using:

NotificationService.swift::

import UIKit
import UserNotifications
import FirebaseMessaging

class NotificationService: UNNotificationServiceExtension {
    private var contentHandler: ((UNNotificationContent) -> Void)?
    private var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)defer {
            contentHandler(bestAttemptContent ?? request.content)
        }
guard let attachment = request.attachment else {
            return
        }
bestAttemptContent?.attachments = [attachment]
    }
override func serviceExtensionTimeWillExpire() {
        if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}

extension UNNotificationRequest {
    var attachment: UNNotificationAttachment? {
        guard let attachmentURL = content.userInfo["image"] as? String,
              let imageData = try? Data(contentsOf: URL(string: attachmentURL)!) else {
            return nil
        }
        return try? UNNotificationAttachment(data: imageData, options: nil)
    }
}

extension UNNotificationAttachment {
    convenience init(data: Data, options: [NSObject: AnyObject]?) throws {
        let fileManager = FileManager.default
        let temporaryFolderName = ProcessInfo.processInfo.globallyUniqueString
        let temporaryFolderURL = URL(fileURLWithPath: NSTemporaryDirectory())
            .appendingPathComponent(temporaryFolderName, isDirectory: true)
        try fileManager.createDirectory(at: temporaryFolderURL, withIntermediateDirectories: true, attributes: nil)
        
        let imageFileIdentifier = UUID().uuidString + ".jpg"
        let fileURL = temporaryFolderURL.appendingPathComponent(imageFileIdentifier)
        try data.write(to: fileURL)
        try self.init(identifier: imageFileIdentifier, url: fileURL, options: options)
    }
}

FCM Payload Here’s the payload I’m sending from the server:

message = messaging.Message(
    data=convert_to_firebase_compatible(data),
    token=registration_id,
    android=messaging.AndroidConfig(
        priority='high',
        ttl=ttl
    ),
    notification=messaging.Notification(
        title=data.get('title', 'ABC'),
        body=data.get('message', ''),
        image=data.get('image_url', '')
    ),
    apns=messaging.APNSConfig(
        headers={
            'apns-priority': '10',
        },
        payload=messaging.APNSPayload(
            aps=messaging.Aps(
                sound='default',
                mutable_content='1'
            ),
        ),
        fcm_options=messaging.APNSFCMOptions(
            image=data.get('image_url', '')
        )
    ),
)

Issue:

Steps Taken:

Questions:

  1. Am I missing any steps in setting up the NotificationServiceExtension to handle images?
  2. Is the FCM payload correctly structured for sending images in iOS notifications?
  3. Do I need to configure anything else for APNs or FCM to support images in notifications?

Solution

  • In FCM payload you are using key as image_url but in your UNNotificationRequest extension you are using wrong key image.

    Change the key to image_url:

    guard let attachmentURL = content.userInfo["image_url"] as? String,
                  let imageData = try? Data(contentsOf: URL(string: attachmentURL)!) else {
                return nil
            }