Skip to content

feat: Implement 'Mark as Read' action for push notifications …#6867

Open
DSingh0304 wants to merge 14 commits into
RocketChat:developfrom
DSingh0304:feature/mark-as-read
Open

feat: Implement 'Mark as Read' action for push notifications …#6867
DSingh0304 wants to merge 14 commits into
RocketChat:developfrom
DSingh0304:feature/mark-as-read

Conversation

@DSingh0304

@DSingh0304 DSingh0304 commented Dec 28, 2025

Copy link
Copy Markdown

Proposed changes

This PR implements a "Mark as Read" quick action button for push notifications on both iOS and Android platforms. This feature allows users to mark messages/rooms as read directly from a push notification without opening the app, providing a convenient way to manage notifications.

Implementation Details:

  • Added new notification action MARK_AS_READ_ACTION alongside the existing Reply action
  • Calls the existing POST /api/v1/subscriptions.read API endpoint (available since Rocket.Chat server v0.61.0)
  • Notification is dismissed after successful API call
  • Follows the same pattern as the existing Reply notification action

Platforms:

  • ✅ iOS (13+)
  • ✅ Android (API 24+)

Issue(s)

Closes #6842

How to test or reproduce

Prerequisites:

  • Rocket.Chat server (v0.61.0+) with push notifications configured
  • Physical device or production build (debug builds may have FCM token registration limitations)

Testing Steps:

  1. Build and install the app on a device
  2. Login to your Rocket.Chat account
  3. Grant notification permissions when prompted
  4. Send a message to yourself from another device/browser (or have someone send you a message)
  5. Close/minimize the app (notification only appears when app is backgrounded)
  6. Wait for notification to appear
  7. Pull down/expand the notification to see action buttons
  8. Verify you see both:
    • "Reply" button (existing)
    • "Mark as read" button (NEW) ✨
  9. Tap "Mark as read"
  10. Expected result:
    • Notification dismisses
    • Room shows as read when you open the app (no unread badge)

Note on Testing:

Due to Firebase configuration limitations in development builds, full end-to-end push notification testing requires production Firebase credentials. The implementation follows the existing Reply action pattern and uses the established subscriptions.read API endpoint.

Screenshots

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

Implementation Approach:

This feature was implemented by following the existing Reply notification action pattern:

Files Modified/Created (8 total):

Common (2 files):

  • app/i18n/locales/en.json - Added "Mark_as_read" translation
  • app/lib/notifications/push.ts - Registered MARK_AS_READ_ACTION notification action

iOS (3 files):

  • ios/Shared/RocketChat/API/Requests/MarkAsRead.swift - NEW: API request definition
  • ios/Shared/RocketChat/RocketChat.swift - Added markAsRead() helper method
  • ios/ReplyNotification.swift - Added handleMarkAsReadAction() handler

Android (3 files):

  • android/app/src/main/java/.../MarkAsReadBroadcast.java - NEW: Broadcast receiver
  • android/app/src/main/AndroidManifest.xml - Registered broadcast receiver
  • android/app/src/main/java/.../CustomPushNotification.java - Added notification action button

API Endpoint:

Uses the existing POST /api/v1/subscriptions.read endpoint which:

  • Requires rid (room ID) parameter
  • Is already used internally by the app
  • Available since Rocket.Chat server v0.61.0
  • No server-side changes required

Testing Limitations:

Full push notification testing requires production Firebase credentials which are not available in development builds. This is a known limitation discussed in the community (reference: community conversation). The code follows established patterns and compiles successfully on both platforms.

Why This Approach:

  1. Consistency - Mirrors the existing Reply action implementation
  2. No breaking changes - Purely additive feature
  3. Minimal server impact - Uses existing API endpoint
  4. User convenience - Common use case in many messaging apps

Summary by CodeRabbit

  • New Features

    • Added a "Mark as read" notification action on iOS and Android, allowing messages to be marked read from the notification and clearing the related system notification on success.
  • Improvements

    • Notifications better handle app/React initialization delays, decrypt and process E2E messages more reliably, and fetch avatars with timeouts and fallbacks.
    • Improved logging and stability around notification processing.
  • Localization

    • Added English label for the "Mark as read" action.

@coderabbitai

coderabbitai Bot commented Dec 28, 2025

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a "Mark as read" quick action to push notifications across Android and iOS: manifest and broadcast receiver on Android, notification wiring and avatar/loading adjustments, native iOS action handling and API request, shared iOS API wrapper and RocketChat method, push config update, and English localization entry. Action POSTs to /api/v1/subscriptions.read and dismisses notification on success.

Changes

Cohort / File(s) Summary
Android Manifest
android/app/src/main/AndroidManifest.xml
Declare new broadcast receiver chat.rocket.reactnative.notification.MarkAsReadBroadcast (android:enabled="true", android:exported="false").
Android Notification Logic
android/app/src/main/java/chat/rocket/reactnative/notification/CustomPushNotification.java
Wait-for-React initialization path, improved logging, avatar fetch timeout/fallback, load-full-message path, add notificationMarkAsRead() and inject "Mark as read" action into full notifications with API-level PendingIntent handling.
Android Receiver
android/app/src/main/java/chat/rocket/reactnative/notification/MarkAsReadBroadcast.java
New BroadcastReceiver using goAsync(); parses payload, POSTs /api/v1/subscriptions.read with auth headers, clears local messages and cancels notification on success; handles errors and ensures PendingResult.finish().
iOS Notification Handling
ios/ReplyNotification.swift
Handle MARK_AS_READ_ACTION via new handleMarkAsReadAction(...): extract payload, call RocketChat.markAsRead, manage background task and completion.
iOS API Layer
ios/Shared/RocketChat/API/Requests/MarkAsRead.swift, ios/Shared/RocketChat/RocketChat.swift
Add MarkAsReadRequest, MarkAsReadBody, MarkAsReadResponse, and RocketChat.markAsRead(rid:completion:) to POST /api/v1/subscriptions.read and surface response.
JS Push Config & Localization
app/lib/notifications/push.ts, app/i18n/locales/en.json
Add MARK_AS_READ_ACTION to MESSAGE category (iOS) and new localization key Mark_as_read: "Mark as read".

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant OS as Notification System
    participant App
    participant Server

    User->>OS: Tap "Mark as read" action
    OS->>App: Deliver intent / UNNotificationResponse

    rect rgba(220,235,245,0.5)
    Note over App: Extract payload (rid, serverURL, auth tokens)
    App->>App: Validate payload & auth
    end

    rect rgba(245,235,220,0.5)
    Note over App: Send API request
    App->>Server: POST /api/v1/subscriptions.read { rid } (with auth headers)
    end

    alt success
        Server-->>App: { success: true }
        App->>App: Clear local unread state / cache
        App->>OS: Cancel/dismiss notification
    else failure
        Server-->>App: error / non-200
        App->>App: Log error (leave notification)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 A flick of whiskers, a tiny tap,
Mark as read — I bridge the gap,
From Android intent to Swift's small plea,
One hop, one POST, notification free,
I nibble crumbs of code and smile with glee.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: implementing a 'Mark as Read' action for push notifications across platforms.
Linked Issues check ✅ Passed The PR successfully implements all core requirements from #6842: adds Mark as Read action for iOS 13+ and Android API 24+, integrates with subscriptions.read API, implements native handlers following Reply pattern, adds i18n string, and handles both foreground and background states.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing the Mark as Read notification action feature; no unrelated modifications detected across iOS, Android, and localization files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (2)
android/app/src/main/java/chat/rocket/reactnative/notification/CustomPushNotification.java (1)

659-689: Consider externalizing the action label for localization.

The method correctly implements the Mark as Read action following the same pattern as notificationReply. However, the label is hardcoded as "Mark as read" instead of loading from Android string resources, which prevents localization.

🔎 Suggested improvement for localization

If you want to support localization similar to the iOS implementation, consider:

  1. Add to android/app/src/main/res/values/strings.xml:
<string name="mark_as_read">Mark as read</string>
  1. Update the method:
-        String label = "Mark as read";
+        String label = mContext.getString(R.string.mark_as_read);

Alternatively, if localization isn't needed on Android (the label won't be translated), the current hardcoded approach is acceptable.

ios/ReplyNotification.swift (1)

125-145: Consider adding error handling for mark-as-read failures.

The implementation correctly extracts the payload and performs the mark-as-read operation with proper background task management. However, unlike handleReplyAction (lines 113-120), this method doesn't handle or notify the user about failures.

🔎 Suggested improvement for consistency

To match the error handling pattern in handleReplyAction:

     rocketchat.markAsRead(rid: rid) { response in
       DispatchQueue.main.async {
+        defer {
+          UIApplication.shared.endBackgroundTask(backgroundTask)
+          completionHandler()
+        }
+
+        guard let response = response, response.success else {
+          // Optionally show failure notification
+          let content = UNMutableNotificationContent()
+          content.body = "Failed to mark as read."
+          let request = UNNotificationRequest(identifier: "markAsReadFailure", content: content, trigger: nil)
+          UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
+          return
+        }
-        UIApplication.shared.endBackgroundTask(backgroundTask)
-        completionHandler()
       }
     }

This also addresses the SwiftLint warning about the unused response parameter.

📜 Review details

Configuration used: Organization 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 0d13c14 and b2fd8db.

📒 Files selected for processing (8)
  • android/app/src/main/AndroidManifest.xml
  • android/app/src/main/java/chat/rocket/reactnative/notification/CustomPushNotification.java
  • android/app/src/main/java/chat/rocket/reactnative/notification/MarkAsReadBroadcast.java
  • app/i18n/locales/en.json
  • app/lib/notifications/push.ts
  • ios/ReplyNotification.swift
  • ios/Shared/RocketChat/API/Requests/MarkAsRead.swift
  • ios/Shared/RocketChat/RocketChat.swift
🧰 Additional context used
🧬 Code graph analysis (4)
ios/ReplyNotification.swift (3)
ios/NotificationService/NotificationService.swift (1)
  • didReceive (9-73)
ios/Shared/Extensions/String+Extensions.swift (1)
  • removeTrailingSlash (25-31)
ios/Shared/RocketChat/RocketChat.swift (1)
  • markAsRead (84-95)
android/app/src/main/java/chat/rocket/reactnative/notification/CustomPushNotification.java (3)
android/app/src/main/java/chat/rocket/reactnative/notification/VideoConfBroadcast.kt (1)
  • TAG (14-73)
android/app/src/main/java/chat/rocket/reactnative/notification/VideoConfNotification.kt (2)
  • context (21-210)
  • createNotificationChannel (54-77)
android/app/src/main/java/chat/rocket/reactnative/notification/MarkAsReadBroadcast.java (1)
  • MarkAsReadBroadcast (22-86)
android/app/src/main/java/chat/rocket/reactnative/notification/MarkAsReadBroadcast.java (1)
android/app/src/main/java/chat/rocket/reactnative/notification/CustomPushNotification.java (1)
  • CustomPushNotification (48-721)
ios/Shared/RocketChat/RocketChat.swift (4)
ios/Shared/RocketChat/API/API.swift (1)
  • fetch (54-91)
ios/Shared/RocketChat/API/Request.swift (1)
  • request (45-72)
ios/Shared/RocketChat/Database.swift (1)
  • readRoomEncrypted (117-125)
ios/Shared/RocketChat/Encryption.swift (2)
  • encryptContent (212-269)
  • decryptContent (175-210)
🪛 SwiftLint (0.57.0)
ios/ReplyNotification.swift

[Warning] 139-139: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)

ios/Shared/RocketChat/RocketChat.swift

[Error] 25-25: @escaping must have a trailing space before the associated type

(attribute_name_spacing)


[Error] 39-39: @escaping must have a trailing space before the associated type

(attribute_name_spacing)


[Warning] 34-34: Avoid using unneeded break statements

(unneeded_break_in_switch)


[Error] 84-84: @escaping must have a trailing space before the associated type

(attribute_name_spacing)


[Warning] 71-71: Avoid using unneeded break statements

(unneeded_break_in_switch)


[Warning] 92-92: Avoid using unneeded break statements

(unneeded_break_in_switch)

🔇 Additional comments (7)
android/app/src/main/java/chat/rocket/reactnative/notification/MarkAsReadBroadcast.java (1)

22-43: LGTM!

The onReceive implementation correctly extracts notification data, validates the notification ID format, and delegates to the markAsRead method. Error handling for invalid notification IDs is appropriate.

app/i18n/locales/en.json (1)

502-502: LGTM!

The localization entry follows the existing naming convention and is properly placed in alphabetical order.

app/lib/notifications/push.ts (1)

91-110: LGTM! Properly implements iOS notification action.

The MARK_AS_READ_ACTION correctly mirrors the existing REPLY_ACTION pattern, with appropriate configuration:

  • Uses localized button title via I18n.t('Mark_as_read')
  • Sets opensAppToForeground: false to handle the action in the background
  • Properly registered in the MESSAGE category alongside existing actions
android/app/src/main/AndroidManifest.xml (1)

95-98: LGTM! Receiver declaration is properly configured.

The receiver configuration is correct:

  • android:exported="false" properly restricts access to internal app components only (security best practice)
  • No intent-filter needed since it's triggered by direct PendingIntent from the notification action
  • Logical placement between similar notification receivers
android/app/src/main/java/chat/rocket/reactnative/notification/CustomPushNotification.java (1)

446-446: LGTM! Action properly integrated into notification flow.

The notificationMarkAsRead call is correctly placed alongside notificationReply, ensuring the Mark as Read action appears only on full notifications (not on fallback message-id-only placeholders).

ios/ReplyNotification.swift (1)

44-48: LGTM! Action handler properly registered.

The MARK_AS_READ_ACTION is correctly intercepted and handled natively before forwarding to the original delegate, following the same pattern as REPLY_ACTION.

ios/Shared/RocketChat/API/Requests/MarkAsRead.swift (1)

11-34: LGTM! API request implementation follows established patterns.

The implementation correctly follows the Request/Response pattern used throughout the iOS codebase:

  • MarkAsReadBody properly encodes the required rid parameter
  • MarkAsReadResponse conforms to the Response protocol
  • MarkAsReadRequest uses the correct HTTP POST method and endpoint path
  • Body encoding uses JSONEncoder consistently with other requests

Comment thread ios/Shared/RocketChat/RocketChat.swift Outdated
…edentials, and a memory monitor, while refactoring Android notification handling and updating Firebase configuration.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
android/app/src/main/java/chat/rocket/reactnative/notification/MarkAsReadBroadcast.java (2)

25-25: Configure timeouts for OkHttpClient.

While the static instance addresses the reuse concern from previous reviews, the client lacks timeout configuration. Network operations without timeouts can hang indefinitely, particularly on poor connections or when the server is unresponsive.

🔎 Proposed timeout configuration
-    private static final OkHttpClient client = new OkHttpClient();
+    private static final OkHttpClient client = new OkHttpClient.Builder()
+            .connectTimeout(10, TimeUnit.SECONDS)
+            .readTimeout(10, TimeUnit.SECONDS)
+            .writeTimeout(10, TimeUnit.SECONDS)
+            .build();

You'll also need to add the import:

import java.util.concurrent.TimeUnit;

56-56: Prefer Gson for JSON construction.

Manual string formatting is fragile—if rid contains quotes or backslashes, the JSON will be malformed. Using Gson ensures proper escaping and is more maintainable.

🔎 Proposed refactor
+        // Create a simple wrapper class or use a Map
+        java.util.Map<String, String> payload = new java.util.HashMap<>();
+        payload.put("rid", rid);
+        String json = new Gson().toJson(payload);
-        String json = String.format("{\"rid\":\"%s\"}", rid);

         RequestBody body = RequestBody.create(JSON, json);
📜 Review details

Configuration used: Organization 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 b2fd8db and e487fe4.

📒 Files selected for processing (2)
  • android/app/src/main/java/chat/rocket/reactnative/notification/MarkAsReadBroadcast.java
  • ios/Shared/RocketChat/RocketChat.swift
🚧 Files skipped from review as they are similar to previous changes (1)
  • ios/Shared/RocketChat/RocketChat.swift
🔇 Additional comments (2)
android/app/src/main/java/chat/rocket/reactnative/notification/MarkAsReadBroadcast.java (2)

60-61: No action needed. The ejson.token() and ejson.userId() methods already validate their inputs and return non-null values (returning empty strings as fallback when credentials are missing), with appropriate error logging. The code at lines 60-61 is safe from null reference exceptions.

Likely an incorrect or invalid review comment.


77-78: No action needed. CustomPushNotification.clearMessages(notId) is thread-safe because it performs an atomic remove() operation on a ConcurrentHashMap, which is designed for concurrent access.

Likely an incorrect or invalid review comment.

…n, and improve Android notification async handling.
@diegolmello

Copy link
Copy Markdown
Member

@DSingh0304 Thanks for your contribution!
It may take a while to review, since we're just starting the year, but we'll do it eventually 🙏🏼

@DSingh0304 DSingh0304 had a problem deploying to experimental_android_build January 5, 2026 13:12 — with GitHub Actions Failure
@DSingh0304 DSingh0304 had a problem deploying to experimental_ios_build January 5, 2026 13:12 — with GitHub Actions Failure
@DSingh0304 DSingh0304 had a problem deploying to official_android_build January 5, 2026 13:12 — with GitHub Actions Failure
@DSingh0304

Copy link
Copy Markdown
Author

@DSingh0304 Thanks for your contribution! It may take a while to review, since we're just starting the year, but we'll do it eventually 🙏🏼

Yes Sure !!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
android/app/src/main/java/chat/rocket/reactnative/notification/CustomPushNotification.java (2)

160-167: ⚠️ Potential issue | 🔴 Critical

Remove the duplicate message-id-only check (compile error).

Two consecutive if statements open the same block, leaving the first one unclosed.

🧹 Proposed fix
-        if (receivedEjson != null && receivedEjson.notificationType != null
-                && receivedEjson.notificationType.equals("message-id-only")) {
-        
-        if (receivedEjson != null && receivedEjson.notificationType != null && receivedEjson.notificationType.equals("message-id-only")) {
+        if (receivedEjson != null && receivedEjson.notificationType != null
+                && receivedEjson.notificationType.equals("message-id-only")) {

241-301: ⚠️ Potential issue | 🔴 Critical

Conflicting E2E implementations are interleaved (duplicate variable/braces).

The current block mixes the old and new flows, redeclares decrypted, and leaves mismatched braces. Please consolidate to a single strategy and ensure success/fallback paths call showNotification.

🧹 Proposed consolidation (fast path + async fallback)
-        // Check if React context is immediately available
-        if (reactApplicationContext != null) {
-            // Fast path: decrypt immediately
-            String decrypted = Encryption.shared.decryptMessage(ejson, reactApplicationContext);
-
-            if (decrypted != null) {
-                bundle.putString("message", decrypted);
-        // Decrypt immediately using regular Android Context (mContext)
-        // This works without React Native initialization
-        String decrypted = Encryption.shared.decryptMessage(ejson, mContext);
-        
-        if (decrypted != null) {
-            bundle.putString("message", decrypted);
-            synchronized(this) {
-                mBundle = bundle;
-            }
-            return;
-        }
+        if (reactApplicationContext != null) {
+            String decrypted = Encryption.shared.decryptMessage(ejson, reactApplicationContext);
+            if (decrypted != null) {
+                bundle.putString("message", decrypted);
+                synchronized (this) {
+                    mBundle = bundle;
+                }
+                showNotification(bundle, ejson, notId);
+                return;
+            }
+        }

         // Slow path: wait for React context asynchronously
         Log.i(TAG, "Waiting for React context to decrypt E2E notification");

         E2ENotificationProcessor processor = new E2ENotificationProcessor(
                 // Context provider
                 () -> reactApplicationContext,

                 // Callback
                 new E2ENotificationProcessor.NotificationCallback() {
                     `@Override`
                     public void onDecryptionComplete(Bundle decryptedBundle, Ejson decryptedEjson,
                             String notificationId) {
                         mBundle = decryptedBundle;
                         Ejson finalEjson = safeFromJson(decryptedBundle.getString("ejson", "{}"), Ejson.class);
                         showNotification(decryptedBundle, finalEjson, notificationId);
                     }

                     `@Override`
                     public void onDecryptionFailed(Bundle originalBundle, Ejson originalEjson, String notificationId) {
                         Log.w(TAG, "E2E decryption failed for notification");
+                        originalBundle.putString("message", "Encrypted message");
+                        synchronized (CustomPushNotification.this) {
+                            mBundle = originalBundle;
+                        }
+                        showNotification(originalBundle, originalEjson, notificationId);
                     }

                     `@Override`
                     public void onTimeout(Bundle originalBundle, Ejson originalEjson, String notificationId) {
                         Log.w(TAG, "Timeout waiting for React context for E2E notification");
+                        originalBundle.putString("message", "Encrypted message");
+                        synchronized (CustomPushNotification.this) {
+                            mBundle = originalBundle;
+                        }
+                        showNotification(originalBundle, originalEjson, notificationId);
                     }
                 });

         processor.processAsync(bundle, ejson, notId);
-            showNotification(bundle, ejson, notId);
-        } else {
-            Log.w(TAG, "E2E decryption failed for notification, showing fallback notification");
-            // Show fallback notification so user knows a message arrived
-            // Use a placeholder message since we can't decrypt
-            bundle.putString("message", "Encrypted message");
-            synchronized(this) {
-                mBundle = bundle;
-            }
-            showNotification(bundle, ejson, notId);
-        }
🤖 Fix all issues with AI agents
In
`@android/app/src/main/java/chat/rocket/reactnative/notification/CustomPushNotification.java`:
- Around line 495-528: The getAvatar method contains an unreachable final return
calling NotificationHelper.fetchAvatarBitmap because both the try block and its
catch already return; remove that dead code (the final "return
NotificationHelper.fetchAvatarBitmap(mContext, uri, largeIcon());") or refactor
so the method returns once (e.g., assign avatar in try/catch and have a single
final return), ensuring references to getAvatar, largeIcon, and
NotificationHelper.fetchAvatarBitmap are updated/removed accordingly so the code
compiles.
- Around line 73-78: The method isReactInitialized() references an undeclared
reactApplicationContext; declare a class-level field named
reactApplicationContext (type ReactApplicationContext) as volatile, import
com.facebook.react.bridge.ReactApplicationContext, and ensure it is populated
when the React instance is created (e.g., set it from your
ReactNativeHost/ReactInstanceManager or during initialization in the class
constructor or an init method). Make reads/writes thread-safe by keeping the
volatile modifier and update any places that previously accessed a local/react
context to use this new field so isReactInitialized() returns a valid check
against the populated context.

@CLAassistant

CLAassistant commented Mar 26, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ DSingh0304
❌ Deep


Deep seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

…Bitmap` instead of direct Glide usage with timeout.
@DSingh0304 DSingh0304 force-pushed the feature/mark-as-read branch from 5634c1d to 3f598e8 Compare March 26, 2026 11:41
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.

feature: Add "Mark as Read" action button to push notifications

3 participants