Skip to content

fix(android): Improve push notification loading reliability and add diagnostic logging#6711

Merged
diegolmello merged 13 commits intodevelopfrom
fix.android-push-secured
Nov 27, 2025
Merged

fix(android): Improve push notification loading reliability and add diagnostic logging#6711
diegolmello merged 13 commits intodevelopfrom
fix.android-push-secured

Conversation

@diegolmello
Copy link
Member

@diegolmello diegolmello commented Oct 9, 2025

Proposed changes

This PR fixes critical bugs in Android push notification handling that caused "message-id-only" notifications to display placeholder text ("You have a new message") instead of loading the actual message content.

The issue was difficult to reproduce and only affected certain users. Investigation revealed multiple bugs:

  1. Missing callback calls when validation failed, causing the notification flow to hang
  2. Array index out of bounds in retry logic
  3. No HTTP timeouts allowing requests to hang indefinitely
  4. Poor error handling making debugging impossible

This PR also adds comprehensive production-safe diagnostic logging to help identify and resolve similar issues in the future.

Issue(s)

https://rocketchat.atlassian.net/browse/SUP-882

How to test or reproduce

Testing the fix:

  1. Configure a Rocket.Chat server to send message-id-only push notifications
  2. Receive a notification while app is in background
  3. Notification should display actual message content (not placeholder)

Verifying logs (debug build):

  1. Build a debug APK
  2. Run adb logcat | grep RocketChat
  3. Receive a notification
  4. Logs should show the full diagnostic flow without exposing sensitive data

Affected screens:

  • Push notifications (system tray)
  • All notification-related background processing

Screenshots

N/A - This is a backend notification handling fix with no UI changes

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • Improvement (non-breaking change which improves a current function)
  • New feature (non-breaking change which adds functionality)
  • Documentation update (if none of the other choices apply)

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works (if applicable)
  • I have added necessary documentation (if applicable)
  • Any dependent changes have been merged and published in downstream modules

Further comments

Technical Details:

Bug Fixes (LoadNotification.java):

  • Fixed early return to always call callback.call(null) ensuring proper flow continuation
  • Fixed array bounds check from RETRY_COUNT <= TIMEOUT.length to RETRY_COUNT < TIMEOUT.length - 1
  • Added HTTP timeouts (10s connect, 30s read/write) via OkHttpClient.Builder
  • Added null safety for response body, serverURL, and messageId
  • Separated exception handling for IOException, JsonSyntaxException, and generic exceptions

Logging (Production-Safe):

  • Added structured logging with appropriate levels (DEBUG/INFO/WARN/ERROR)
  • Verbose logs gated behind BuildConfig.DEBUG (debug builds only)
  • Production logs never expose: user IDs, auth tokens, or full URLs
  • URLs sanitized to show only protocol and host
  • Follows Android logging best practices

Files Changed:

  • LoadNotification.java - Core bug fixes and error handling
  • CustomPushNotification.java - Added flow logging
  • Ejson.java - Added debug-only verbose logging with BuildConfig guards

The logging addition makes future issues like this much easier to diagnose while maintaining security and following industry standards for production logging.

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced push notification stability with improved error handling and validation logic.
    • Added resilience for edge cases in notification processing and ID parsing.
    • Improved error recovery for notification delivery failures.
  • Chores

    • Strengthened internal notification processing with better timeouts and retry mechanisms.
    • Enhanced diagnostics and logging for improved troubleshooting.

✏️ Tip: You can customize this high-level summary in your review settings.

- Added detailed logging for notification loading process in LoadNotification.java.
- Implemented error handling for null or empty userId and userToken.
- Enhanced retry logic for network requests with clear logging of attempts and failures.
- Updated Ejson.java to include logging for token and userId retrieval.
- Improved fallback notification handling in CustomPushNotification.java with additional logging for failures.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 9, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

These changes enhance Android push notification processing with improved robustness through comprehensive error handling, null checks, thread-safe initialization, and expanded diagnostic logging across notification lifecycle stages.

Changes

Cohort / File(s) Summary
Notification Processing
android/app/src/main/java/chat/rocket/reactnative/notification/CustomPushNotification.java
Refactored notification processing flow with validation of notification IDs, React initialization waiting with timeout, and background thread handling. Added E2E decryption support with fallback for delayed React context. Enhanced error handling with null checks for NotificationManager and avatar loading. Modified reactApplicationContext from public static to public static volatile for thread safety. Added explicit processing stages (loadNotificationAndProcess, processNotification, showNotification) and ENABLE_VERBOSE_LOGS diagnostics.
MMKV & Data Access
android/app/src/main/java/chat/rocket/reactnative/notification/Ejson.java
Introduced thread-safe, lazy MMKV initialization with SecureKeystore-derived password. Enhanced getAvatarUri() with robust parameter validation and URI construction with format/size/token/uid. Strengthened token() and userId() methods with null handling, MMKV fallbacks, and debug diagnostic logging including available key introspection.
HTTP Request & Retry Logic
android/app/src/main/java/chat/rocket/reactnative/notification/LoadNotification.java
Added extensive input validation and error handling for ejson, serverURL, messageId, userId, and userToken. Configured OkHttpClient with explicit timeouts (connect: 10s, read: 30s, write: 30s). Replaced ad-hoc URL construction with HttpUrl.Builder and added retry mechanism with TIMEOUT array. Enhanced response handling with HTTP status validation, JSON parsing via Gson, and structure validation. Introduced handleRetryOrFailure() helper for retry management.
Utility & Defensive Error Handling
android/app/src/main/java/chat/rocket/reactnative/notification/NotificationHelper.java
New utility class with sanitizeUrl(String url) method for build-aware URL sanitization (returns original URL in DEBUG, "[workspace]" otherwise, "[null]" if null).
Notification Reply
android/app/src/main/java/chat/rocket/reactnative/notification/ReplyBroadcast.java
Added try-catch defensive error handling around Integer.parseInt() for notification ID parsing in onReceive(), with error logging on NumberFormatException.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • CustomPushNotification.java requires careful review of the new state machine-like processing stages, E2E decryption fallback logic, and thread-safety implications of the volatile field change
  • LoadNotification.java contains dense retry logic and multiple validation/parsing paths that need verification for correctness
  • Ejson.java introduces thread-safe lazy initialization patterns that should be validated for proper synchronization
  • Integration points between these files (how CustomPushNotification calls LoadNotification and Ejson) should be traced to ensure robustness

Possibly related PRs

Suggested reviewers

  • OtavioStasiak

Poem

🐰✨ Notifications now hop with care,
With timeouts, retries everywhere,
No null exceptions, threads align,
Each message decrypted, smooth and fine,
Rocket's robustness—a fluffy design! 🚀

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix.android-push-secured

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between bcd351f and 765acbb.

📒 Files selected for processing (5)
  • android/app/src/main/java/chat/rocket/reactnative/notification/CustomPushNotification.java (10 hunks)
  • android/app/src/main/java/chat/rocket/reactnative/notification/Ejson.java (4 hunks)
  • android/app/src/main/java/chat/rocket/reactnative/notification/LoadNotification.java (3 hunks)
  • android/app/src/main/java/chat/rocket/reactnative/notification/NotificationHelper.java (1 hunks)
  • android/app/src/main/java/chat/rocket/reactnative/notification/ReplyBroadcast.java (1 hunks)

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 and usage tips.

@diegolmello diegolmello temporarily deployed to experimental_android_build October 9, 2025 14:29 — with GitHub Actions Inactive
@diegolmello diegolmello had a problem deploying to experimental_ios_build October 9, 2025 14:29 — with GitHub Actions Error
@diegolmello diegolmello had a problem deploying to official_android_build October 9, 2025 14:29 — with GitHub Actions Error
@diegolmello diegolmello had a problem deploying to upload_experimental_android October 9, 2025 15:01 — with GitHub Actions Error
@github-actions
Copy link

github-actions bot commented Oct 9, 2025

Android Build Available

Rocket.Chat Experimental 4.65.0.107532

Internal App Sharing: https://play.google.com/apps/test/RQVpXLytHNc/ahAO29uNT_WZhhUi5TNV4tmGX1GR2QFqcHIvQXdxflAusqcJtIUJIV51K9uLFChkhR_6W5bnYKp535DUtnt0lmIRY_

Copy link
Contributor

@OtavioStasiak OtavioStasiak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

…ror handling

- Added verbose logging for notification processing and avatar URI generation in CustomPushNotification.java.
- Implemented checks for React initialization before processing notifications.
- Updated Ejson.java to ensure avatar URI generation handles null or empty values gracefully.
- Enhanced LoadNotification.java to log encryption fields in notifications.
- Improved overall error management and notification handling logic.
@diegolmello diegolmello force-pushed the fix.android-push-secured branch from 1063087 to 733c21f Compare October 31, 2025 18:12
@diegolmello diegolmello force-pushed the fix.android-push-secured branch from 733c21f to f2ef6db Compare October 31, 2025 18:14
@diegolmello diegolmello temporarily deployed to approve_e2e_testing October 31, 2025 18:14 — with GitHub Actions Inactive
@diegolmello diegolmello temporarily deployed to experimental_android_build October 31, 2025 18:19 — with GitHub Actions Inactive
@diegolmello diegolmello temporarily deployed to experimental_ios_build October 31, 2025 18:19 — with GitHub Actions Inactive
@github-actions
Copy link

iOS Build Available

Rocket.Chat Experimental 4.66.0.107615

@diegolmello diegolmello had a problem deploying to upload_experimental_android November 3, 2025 15:10 — with GitHub Actions Error
@github-actions
Copy link

github-actions bot commented Nov 3, 2025

iOS Build Available

Rocket.Chat Experimental 4.66.0.107619

@github-actions
Copy link

github-actions bot commented Nov 3, 2025

Android Build Available

Rocket.Chat Experimental 4.66.0.107618

Internal App Sharing: https://play.google.com/apps/test/RQVpXLytHNc/ahAO29uNTceCDXLl0n5KzB7McYH_xPCE7vnmVY3fr0bo0WwW_fYcqILHUCkhPXNwvGE45prdAr8Xz_W_RnJOhUFfvO

@diegolmello diegolmello temporarily deployed to approve_e2e_testing November 3, 2025 18:28 — with GitHub Actions Inactive
@diegolmello diegolmello temporarily deployed to experimental_android_build November 3, 2025 18:31 — with GitHub Actions Inactive
@diegolmello diegolmello temporarily deployed to experimental_ios_build November 3, 2025 18:31 — with GitHub Actions Inactive
@diegolmello diegolmello had a problem deploying to upload_experimental_android November 3, 2025 19:02 — with GitHub Actions Error
@github-actions
Copy link

github-actions bot commented Nov 3, 2025

Android Build Available

Rocket.Chat Experimental 4.66.0.107620

Internal App Sharing: https://play.google.com/apps/test/RQVpXLytHNc/ahAO29uNRfE-G-Ytsb5alGX8qbpjuuuaxJG396MHERdATYJodrY1VE3_9TkUs8OJpVe81zR3dSyCFHZ0SjxCHf0zhs

@diegolmello diegolmello had a problem deploying to official_android_build November 27, 2025 18:17 — with GitHub Actions Failure
@diegolmello diegolmello had a problem deploying to experimental_ios_build November 27, 2025 18:17 — with GitHub Actions Failure
@diegolmello diegolmello had a problem deploying to experimental_android_build November 27, 2025 18:17 — with GitHub Actions Failure
@diegolmello diegolmello marked this pull request as ready for review November 27, 2025 18:21
@diegolmello diegolmello merged commit 788cb8d into develop Nov 27, 2025
5 of 11 checks passed
@diegolmello diegolmello deleted the fix.android-push-secured branch November 27, 2025 18:23
@coderabbitai coderabbitai bot mentioned this pull request Dec 2, 2025
10 tasks
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