# Handling notifications with image
To enable incoming FCM Notifications to display images from the FCM payload on Apple devices, you need to add an additional notification service extension.
# Step 1 - Create a Notification Service Extension
Open Runner.xcodeproj
located in ios directory.
- In Xcode, navigate to: File > New > Target...
- A modal will appear with a list of potential targets. Scroll down or use the search function to find and select "Notification Service Extension". Click Next.
- Provide a product name (e.g., ImageNotification for consistency), set your team, set the language to Swift, and click Finish.
- Activate the scheme by selecting Activate.
# Step 2 - Add the Target to the Podfile
Ensure your new extension can access the Firebase/Messaging pod by updating the Podfile:
- Open the Podfile: ios/Podfile
- Scroll to the bottom and add the following:
target 'ImageNotification' do
use_frameworks!
pod 'Firebase/Messaging'
end
- Run
pod install
from the ios directory to install or update your pods.
WARNING
If you see any warnings related to google services while installing pods, try to add pod 'GoogleUtilities'
to the target.
target 'ImageNotification' do
use_frameworks!
pod 'GoogleUtilities'
pod 'Firebase/Messaging'
end
# Step 3 - Implement the Extension Helper
Now, ensure everything is set up correctly by invoking the extension helper:
- Open
NotificationService.swift
Replace the existing code with the following (you may customize the notification as needed):
import UserNotifications
import UIKit
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(
_ request: UNNotificationRequest,
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
) {
self.contentHandler = contentHandler
self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let fcmOptions = request.content.userInfo["fcm_options"] as? [String: Any],
let imageURLString = fcmOptions["image"] as? String,
let imageURL = URL(string: imageURLString) {
self.downloadImage(from: imageURL) { attachment in
if let attachment = attachment {
self.bestAttemptContent?.attachments = [attachment]
}
self.contentHandler?(self.bestAttemptContent ?? request.content)
}
} else {
self.contentHandler?(self.bestAttemptContent ?? request.content)
}
}
override func serviceExtensionTimeWillExpire() {
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
private func downloadImage(from url: URL, completion: @escaping (UNNotificationAttachment?) -> Void) {
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
completion(nil)
return
}
let tmpDirectory = URL(fileURLWithPath: NSTemporaryDirectory())
let tmpFile = tmpDirectory.appendingPathComponent(UUID().uuidString + ".jpg")
do {
try data.write(to: tmpFile)
let attachment = try UNNotificationAttachment(identifier: "", url: tmpFile, options: nil)
completion(attachment)
} catch {
completion(nil)
}
}.resume()
}
}
Your device can now display images in notifications by specifying the image
option in your FCM payload. Note that there is a 300KB maximum image size limit enforced by the device.