Skip to content

fix(mobile): keep push data on Android app-drawn notifications - #2494

Merged
DoodleBears merged 2 commits into
mainfrom
claude/project-thread-9rg7zp
Oct 21, 2026
Merged

DoodleBears merged 2 commits into
mainfrom
claude/project-thread-9rg7zp

Conversation

@DoodleBears

@DoodleBears DoodleBears commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Vain · project thread

Why

The phone check of #2491 (result) confirmed that an unread DM is no longer cleared, but it found another problem. The notifications for a secret-input request and an approval that had already been handled were never dismissed, not even after the app was opened.

Cause: #2485 added RequestsTrigger, which is neither a FirebaseNotificationTrigger nor a SchedulableNotificationTrigger nor a ChannelAwareTrigger. Expo's NotificationSerializer.toBundle(NotificationRequest) only fills content.data/dataString for those three kinds of trigger. As a result, the notification objects JS gets back from getPresentedNotificationsAsync() carry no data, so parsePushData returns undefined and push-session.reflect() can't match any resolved request. Tapping a notification goes through the same serialization, so taps can't route by data either.

Change outline

  • ConversationHandlingDelegate: the rebuilt request now uses Expo's own ChannelAwareTrigger("requests"). That still pins the notification to the requests channel, and the serializer passes our data JSON back to JS as dataString.
  • Remove RequestsTrigger.

Verification

  • CI compiles the Kotlin module.
  • Not yet done: a phone check that handled requests are dismissed from the shade and that tapping a notification jumps to the right place.

Generated by Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Android Bot notifications now disappear from the notification shade after being handled.
    • Tapping a Bot notification now opens the correct conversation or request.
    • Rebuilt request notifications now consistently use the requests channel and provide their trigger details to JavaScript.
  • Documentation
    • Added release documentation describing the updated Android notification behavior in English and Chinese.

RequestsTrigger was neither a Firebase, schedulable nor channel-aware trigger,
so Expo's NotificationSerializer gave JS no content.data for those
notifications. Resolved requests were never dismissed from the shade, and taps
could not route. The rebuilt request now uses Expo's ChannelAwareTrigger on the
requests channel.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrtPca5pD72Gdx4CFkQdNi
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrtPca5pD72Gdx4CFkQdNi
@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 851ed239-e924-42f4-9bd1-8a138d80bb81
📥 Commits

Reviewing files that changed from the base of the PR and between 4ab1554 and b71823e.

📒 Files selected for processing: 2
  • apps/mobile/modules/conversation-notifications/android/src/main/java/expo/modules/conversationnotifications/ConversationNotificationsService.kt
  • changes/2494-android-push-data.md

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.

📝 Walkthrough

Android conversation notification rebuilding now uses ChannelAwareTrigger with the "requests" channel instead of a custom Parcelable wrapper. The changelog describes handled-notification dismissal and navigation to the corresponding conversation or request when tapped.

Changes: Android conversation notifications

Layer / File(s) Summary
Channel-aware notification rebuilding
apps/mobile/modules/conversation-notifications/android/src/main/java/expo/modules/conversationnotifications/ConversationNotificationsService.kt, changes/2494-android-push-data.md
The service rebuilds notifications with ChannelAwareTrigger("requests") and removes the custom Parcelable trigger wrapper. Its documentation describes trigger data exposed to JavaScript. The English and Chinese changelog entries describe dismissal after request handling and navigation when a notification is tapped.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related issues

Merge Risk: ⚪ Minimal · up to b7182

No actionable merge-blocking risk remains; runtime phone validation is still advisable for the documented notification interactions.

Pre-merge checks: Passed 3 · Failed 2

Failed Failed checks: 2 warnings

Check name Status Explanation Resolution
Description check Warning The description explains the cause and implementation, but it omits the required Special things to note section, merge-risk details, CI test-plan mode, and complete verification results. Add the required template sections. State merge risk, blast radius, rollback approach, and review focus. Record the exact CI test-plan mode and any updated rule. List automated checks, runtime checks, visual evidence, human QA, and unrun ch…
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 1 files. (1 skipped: 1 … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 3 passed
Check name Status Explanation
Title check Passed The title clearly identifies the Android mobile push-data fix and matches the primary change.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Resolution

Add the required template sections. State merge risk, blast radius, rollback approach, and review focus. Record the exact CI test-plan mode and any updated rule. List automated checks, runtime checks, visual evidence, human QA, and unrun checks. Rename or expand the Why section to include the required issue or discussion link information.

Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 1 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@DoodleBears
DoodleBears merged commit 4227b25 into main Oct 21, 2026
11 checks passed
DoodleBears added a commit that referenced this pull request Oct 21, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Copy link
Copy Markdown
Contributor Author

Android phone result (b71823e, the same code as merged main 4227b25): PASS for removing handled request notifications (Xiaomi, Android 16 / HyperOS 3, store build plus isolated QA Host at the same commit, battery saver unrestricted and autostart on, app in the background the whole time)

Evidence: 2494-android-push/phone-b71823e6 (commit 986ed0b): shade-after-resolve-and-open.png, notification-dismissal.md

Step Result
Mira DM reply, left unread Stays, including after opening the app
Nova secret-input request, submitted The notification is removed in the background
secret_cli approval ("允许这次 / 拒绝"), denied via the CLI The notification is removed in the background
Open the app, then return home Only the reply notifications remain, and no handled request comes back

The two identical Mira notifications in the shade are two real messages with different message IDs, not a duplicate notification.

Not covered in this run: tapping a DM, group or approval notification to check that it opens the right screen. That goes in the next run.


Generated by Claude Code

Copy link
Copy Markdown
Contributor Author

Android phone result: notification taps and actions PASS (Xiaomi, Android 16 / HyperOS 3, store build installed over the existing app from main 77ddca9, isolated QA Host at the same commit, app in the background before every tap)

Evidence: 2494-android-push/phone-tap (commit b48f6b9), notification-taps.md

Action Files Result
Tap Mira DM reply 1-dm-notification-opens-dm.png Opens the Mira DM
Tap Lumi reply in #QA group 2-group-reply-opens-channel.png Opens the #QA group channel
Tap Nova approval 0-shade-approval-notification.png, 3-approval-opens-request.png Opens the Nova DM on the pending approval card (gh --version)
"拒绝" button (Echo approval) 4-deny-button-rejected.png Host records rejected, the card shows "已拒绝", the Bot replies QA-SECRET-REFUSED, and the notification is removed
"允许这次" button (Nova approval) 5-allow-button-allowed-once.png Host records allowed-once, the command exits 0, the Bot replies QA-SECRET-OK, and the notification is removed

Both action buttons bring the app to the foreground (opensAppToForeground: true).

Notes:

  1. On HyperOS the action buttons only appear after the notification is expanded.
  2. Opening a chat clears every notification for that chat, including a still-pending approval. The request stays pending in the app and on the Host, but the phone no longer shows a reminder. This happened on the first deny attempt, so that step was redone with a new approval. If a pending approval notification should survive opening the chat, this needs a change.

All Android push screenshots for this series (#2397, #2465, #2483, #2485, #2491, #2494):


Generated by Claude Code

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