Skip to content

fix(ios): reliably load Communication Notification avatars - #66

Closed
izetmolla wants to merge 1 commit into
marcocrupi:mainfrom
izetmolla:fix/ios-communication-notification-avatars
Closed

fix(ios): reliably load Communication Notification avatars#66
izetmolla wants to merge 1 commit into
marcocrupi:mainfrom
izetmolla:fix/ios-communication-notification-avatars

Conversation

@izetmolla

Copy link
Copy Markdown

Summary

Fixes iOS Communication Notifications where sender/group avatars often fail to appear as the lock-screen circular avatar (especially after NSE disk caching of file:// URLs).

Why this belongs in NotifeeCore

INSendMessageIntent avatar handling lives in ios/NotifeeCore/NotifeeCoreUtil.m. The bridge cannot fix intent image persistence — this must load image bytes natively.

Changes

  1. inImageFromCommunicationAvatarString: — resolve HTTPS / file:// / absolute / bundle paths, load bytes, build INImage via imageWithImageData: (fall back to remote imageWithURL: only for HTTPS).
  2. [intent setImage:avatar forParameterNamed:@"sender"] — required for the circular avatar + app-icon badge layout.
  3. customIdentifier: sender[@"id"] — stable person identity for the intent.
  4. Docs + types — Communication Notifications examples on the iOS Appearance page; JSDoc notes on avatar URL forms.

Before / after

Before After
INImage imageWithURL: on NSE file:// cache URLs often fails while iOS persists the intent image (URL-encoded name + .png) Image data is embedded via imageWithImageData:
Sender avatar not set on the intent parameter setImage:forParameterNamed:@"sender" applied when avatar resolves
Group avatars used initWithString: + imageWithURL: only Same resilient loader as sender avatars

Examples

Direct message (HTTPS — preferred for NSE):

await notifee.displayNotification({
  title: 'Maya Chen',
  body: 'Can you review the PR when you have a minute?',
  ios: {
    communicationInfo: {
      conversationId: 'dm-maya-chen',
      body: 'Can you review the PR when you have a minute?',
      sender: {
        id: 'user_maya',
        displayName: 'Maya Chen',
        avatar: 'https://cdn.example.com/avatars/maya.png',
      },
    },
  },
});

Group:

await notifee.displayNotification({
  title: 'Design Sync',
  body: 'Omar: Shipping the new empty states today.',
  ios: {
    communicationInfo: {
      conversationId: 'channel-design-sync',
      body: 'Shipping the new empty states today.',
      groupName: 'Design Sync',
      groupAvatar: 'https://cdn.example.com/groups/design-sync.png',
      sender: {
        id: 'user_omar',
        displayName: 'Omar',
        avatar: 'https://cdn.example.com/avatars/omar.png',
      },
    },
  },
});

Remote (server SDK):

import { buildNotifyKitPayload } from 'react-native-notify-kit/server';

const message = buildNotifyKitPayload({
  token: deviceToken,
  notification: {
    title: 'Maya Chen',
    body: 'Can you review the PR when you have a minute?',
    ios: {
      communicationInfo: {
        conversationId: 'dm-maya-chen',
        body: 'Can you review the PR when you have a minute?',
        sender: {
          id: 'user_maya',
          displayName: 'Maya Chen',
          avatar: 'https://cdn.example.com/avatars/maya.png',
        },
      },
    },
  },
});

Test plan

  • iOS 15+ physical device, Communication Notifications entitlement enabled
  • Foreground displayNotification with HTTPS sender.avatar → circular avatar + app badge on lock screen / Notification Center
  • Same with local file:// avatar (simulates NSE cache path) → avatar still renders
  • Group notification with groupName + groupAvatar → group presentation + images
  • Background/killed FCM/APNs via NSE + communicationInfo in Notify Kit options → avatar still applied
  • Missing/invalid avatar URL → notification still displays without crashing

Verified in production via a local patch on react-native-notify-kit@10.5.0 (Expo SDK 57 / RN New Architecture).

Made with Cursor

Prefer INImage imageWithImageData from downloaded/local bytes over
imageWithURL on file:// cache paths, set the sender intent image for
lock-screen circular avatars, and document usage examples.

Co-authored-by: Cursor <cursoragent@cursor.com>
@izetmolla
izetmolla force-pushed the fix/ios-communication-notification-avatars branch from b276051 to cf26d7f Compare August 13, 2026 17:09
@marcocrupi

Copy link
Copy Markdown
Owner

Hi @izetmolla, thanks for taking the time to investigate this and submit the PR.

I reviewed the issue and the proposed implementation in depth. The investigation confirmed that there are real problems in the current Communication Notification avatar handling, particularly around local file:// avatar resolution and the existing group avatar path.

However, I’m not going to merge PR #66 in its current form. Some parts of the proposed solution go beyond the confirmed root cause, and there are a few areas I’m not comfortable shipping as-is, especially the synchronous remote image loading inside the Notification Service Extension, the additional sender intent image assignment, and the customIdentifier behavior change.

I’m going to take the underlying issue forward and implement a more narrowly scoped fix in the library, with dedicated runtime validation on iOS before releasing it.

Your report and patch were still very useful in identifying the problem, so thank you for bringing this to my attention and for contributing to the project.

@marcocrupi marcocrupi closed this Aug 13, 2026
@izetmolla
izetmolla deleted the fix/ios-communication-notification-avatars branch August 13, 2026 23:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants