## Summary
expo-notifications
has no way to opt local (
scheduleNotificationAsync
) Android notifications into an explicit, app-authored notification group (
NotificationCompat.Builder.setGroup()
/
setGroupSummary()
). Neither
NotificationContentInput
nor the native Android builder (
ExpoNotificationBuilder.kt
/
BaseNotificationBuilder.kt
) call
setGroup
/
setGroupSummary
anywhere — this capability just doesn't exist yet.
## Problem
Any app that schedules 4+ local notifications into the same channel (a common pattern for reminder/recall-style apps) falls into Android's
implicit
auto-bundling fallback instead of a real, app-authored group. Per Android's own docs:
> If your app sends four or more notifications and doesn't specify a group, the system automatically groups them on Android 7.0 and higher. [...] Automatic grouping behavior might vary on some device types.
In practice, on several OEM skins this auto-bundled stack renders an expand chevron that doesn't reliably surface each notification's action buttons (
categoryIdentifier
actions) once expanded — the chevron is there, but expanding it doesn't visibly do anything, and the per-notification action buttons are gone. That's the documented risk of relying on Android's fallback instead of defining the group explicitly, and today there's no way in
expo-notifications
to do the latter:
  • NotificationContentInput
    has no
    groupKey
    /
    isGroupSummary
    /equivalent field.
  • The remote-push payload does support a
    group
    key, but that's the FCM path — it doesn't touch local scheduled notifications at all.
  • The native builder path (
    ArgumentsNotificationContentBuilder
    NotificationContent
    ExpoNotificationBuilder.build()
    ) never calls
    setGroup()
    /
    setGroupSummary()
    .
## Proposed solution
Add two optional, Android-only fields to
NotificationContentInput
:
```ts
type NotificationContentInput = {
// ...existing fields
/**
* Android notification group key. Notifications sharing the same groupKey are bundled
* together by the system under one app-authored group. Pair with a single
*
isGroupSummary: true
notification per groupKey.
* @platform android
*/
groupKey?: string;
/**
* Marks this notification as the group summary for
groupKey
.
* @platform android
*/
isGroupSummary?: boolean;
};
```
Wired straight through to
NotificationCompat.Builder.setGroup(groupKey)
/
.setGroupSummary(true)
in
ExpoNotificationBuilder.build()
.
Ideally, the module would also take care of posting/refreshing the group-summary notification itself at delivery/dismissal time (in
ExpoPresentationDelegate.presentNotification()
/
dismissNotifications()
), reusing each sibling notification's own already-authored title/text for the summary's
InboxStyle
lines. That avoids apps having to keep a JS-side summary in sync with what's actually in the tray, which is fragile — notifications can be delivered by an OS alarm while the app is killed, so there's no reliable JS-side hook to recompute a summary from.
## Why this matters
Grouping isn't cosmetic here — without it, apps that legitimately schedule several local notifications (reminders, recalls, chat-style updates) have no supported way to keep each one individually actionable once Android's own notification count threshold kicks in. Right now the only way to fix that is a native patch to
expo-notifications
itself.
## Reference implementation
I already have a working
patch-package
fix implementing the above (JS type + native builder wiring + delivery-time summary management in
ExpoPresentationDelegate.kt
), tested against
expo-notifications@57.0.7
— verified end-to-end against a fresh install. Happy to turn this into a PR if that's useful — let me know.
## Related
  • #28580 — grouping for
    push
    notifications (
    android.group
    in the FCM payload). Different code path; doesn't cover local
    scheduleNotificationAsync
    , which is what this request is about.
  • #10962, #31710, #36282 — Android action buttons missing in other contexts (background/killed state, remote push). Related symptom, different root cause.
Searched Canny and GitHub for existing
setGroup
/
setGroupSummary
/grouping requests before posting — didn't find one covering this specific gap.