4

I want to use the data payload in a firebase cloud messaging to present an image in the notification. The image is specified as an url to a website where the image is hosted.

It appears as what I want to do is to add the image as an attachment, see row 8 below. There are however no image present, other than the application icon.

const notification = new firebase.notifications.Notification()
        .setNotificationId("notification_id")
        .setTitle(notification.data.title)
        .setBody(notification.data.body)
        .setData({ url: notification.data.url })
        .ios.setLaunchImage(notification.data.icon)
        .android.setBigPicture(notification.data.icon)
        .ios.addAttachment("some_id", notification.data.icon, {});

The problem is that there are no error messages that can help me. The notification displays with the title and body as expected, but no image is present. From what I can read of the documentation what I want to do is possible.

Axenu
  • 116
  • 1
  • 5

1 Answers1

1

The short answer is that react-native on iOS does not support "rich push notifications" i.e. notifications with images.

The longer answer is that it is rather simple to add support for an image to a react-native project if you add a little swift code.

Work around:

Open your xcode project and go to "editor"->"Add Target...". Select the "Application Extension" named "Notification Service Extension".

You can name it whatever you want but make sure that the correct project is selected if you are using CocoaPods.

Once it is created replace the content of override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) with:

      self.contentHandler = contentHandler
      bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
      
      // get the variables that is needed later.
      guard let bestAttemptContent = bestAttemptContent,
        let attachmentURLAsString = bestAttemptContent.userInfo["icon"] as? String, 
      // "icon" is the key for the image url in the notification. It 
      // could be named whatever you want.
        let attachmentURL = URL(string: attachmentURLAsString) else {
          return
      }
      
      // call a custom function to download the image before attaching
      // it to the notification and presenting it.
      downloadImageFrom(url: attachmentURL) { (attachment) in
        if let attachment = attachment {
          bestAttemptContent.attachments = [attachment]
          contentHandler(bestAttemptContent)
        }
        
      }

Then the downloadImageFrom function needs to be created:

  private func downloadImageFrom(url: URL, with completionHandler: @escaping (UNNotificationAttachment?) -> Void) {
    let task = URLSession.shared.downloadTask(with: url) { (downloadedUrl, response, error) in
      
      //verify that a url exists.
      guard let downloadedUrl = downloadedUrl else {
        completionHandler(nil)
        return
      }
      
      // create a local unique filepath.
      var urlPath = URL(fileURLWithPath: NSTemporaryDirectory())
      let uniqueURLEnding = ProcessInfo.processInfo.globallyUniqueString + ".png"
      urlPath = urlPath.appendingPathComponent(uniqueURLEnding)
      
      // fetch the image from the url
      try? FileManager.default.moveItem(at: downloadedUrl, to: urlPath)
      
      // if successful, return the image as an attachment.
      do {
        let attachment = try UNNotificationAttachment(identifier: "picture", url: urlPath, options: nil)
        completionHandler(attachment)
      } catch {
        completionHandler(nil)
      }
    }
    task.resume()
  }

When you build the application it will use this code instead for loading notifications.

When sending the notification you have to remember to include the "icon" value. An example of what is needed to send a notification:

    "notification": {
        "body": "body",
        "title": "title"
        "mutable_content": true // this row is required for the notification to work!
    },
    "data": {
        "icon":"https://pusher.com/static_logos/320x320.png", // change to your image url.
    },
Community
  • 1
  • 1
Axenu
  • 116
  • 1
  • 5