FirebasePushNotificationPlugin icon indicating copy to clipboard operation
FirebasePushNotificationPlugin copied to clipboard

How to receive an image notification?

Open yongsinchen opened this issue 5 years ago • 2 comments

My server-side firebase admin able to send a notification with image url, but when receiving the notification there are no image displayed but i cant see the fcmoptions has come with the image url.

yongsinchen avatar Oct 08 '19 08:10 yongsinchen

I struggled with this for several days on iOS before I was able to get it working correctly. For iOS, in order to get an image to show, you need to create a Notification Service Extension. Frirebase sets the data packet mutable so that the extension can modify the notification before it is displayed. A word of warning, debugging the service extension is a bit cumbersome. If your extension crashes (unknowingly), it will push out the origin notification, and you might be stuck wondering why your extension is not working.

Here is my implementation to extract the image from the Firebase packet and display it. Hope it helps anyone who might be stuck.

public override void DidReceiveNotificationRequest(UNNotificationRequest request, Action<UNNotificationContent> contentHandler)
{
    try
    {
        ContentHandler = contentHandler;
        BestAttemptContent = (UNMutableNotificationContent)request.Content.MutableCopy();

        string image = request.Content.UserInfo.ValueForKeyPath(new NSString("fcm_options.image"))?.ToString();
        if (string.IsNullOrWhiteSpace(image))
        {
            ContentHandler(BestAttemptContent);
            return;
        }

        var url = NSUrl.FromString(image);
        var task = NSUrlSession.SharedSession.CreateDownloadTask(url, (tempFile, response, error) =>
        {
            if (error != null || tempFile == null)
            {
                ContentHandler(BestAttemptContent);
                return;
            }

            var cache = NSSearchPath.GetDirectories(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomain.User, true);
            if (cache == null || cache.Length == 0)
            {
                ContentHandler(BestAttemptContent);
                return;
            }

            var cachesFolder = cache[0];
            var filename = System.IO.Path.GetFileName(image);
            var cacheFile = System.IO.Path.Combine(cachesFolder, filename);
            var attachmentURL = NSUrl.CreateFileUrl(cacheFile, false, null);

            NSError err = null;
            NSFileManager.DefaultManager.Move(tempFile, attachmentURL, out err);
            if (err != null)
            {
                ContentHandler(BestAttemptContent);
                return;
            }

            UNNotificationAttachmentOptions options = null;
            var attachment = UNNotificationAttachment.FromIdentifier("push-attachment", attachmentURL, options, out err);
            if (attachment != null)
            {
                BestAttemptContent.Attachments = new UNNotificationAttachment[] { attachment };
            }

            ContentHandler(BestAttemptContent);
        });

        task.Resume();
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.ToString());
    }
}

dczaretsky avatar Apr 20 '20 19:04 dczaretsky

Thanks for sharing @dczaretsky! Did you have to upload another APN Certificate in the Firebase Cloud Messaging iOS app configuration section for the additional Bundle ID name: com.MyAppName.MyAppNameServiceExtension ?

Wildcard Bundle IDs don't work with APN Certs: https://stackoverflow.com/a/20473316/676980

steffes avatar Jul 20 '20 18:07 steffes