Skip to content

Conversation

@ucswift
Copy link
Member

@ucswift ucswift commented Nov 10, 2025

Summary by CodeRabbit

  • New Features

    • Enhanced push notification service with improved support for iOS and Android, including better handling across foreground, background, and app-launch states.
  • Improvements

    • Updated badge management for improved reliability.
  • Documentation

    • Added comprehensive documentation for push notification service refactor.
  • Tests

    • Updated and expanded test coverage for notification handlers and registration flows.

@coderabbitai
Copy link

coderabbitai bot commented Nov 10, 2025

Walkthrough

The PR refactors the push notification service from Expo Notifications to Firebase Cloud Messaging (FCM) with Notifee. Changes include package updates, new comprehensive documentation, service implementation migration using FCM for messaging and Notifee for Android channel management, corresponding test suite refactoring, and badge management updates.

Changes

Cohort / File(s) Summary
Documentation
docs/push-notification-fcm-refactor.md
New documentation file detailing complete refactor of push notification service to use FCM and Notifee, including package changes, service architecture, message handling types, token management, lifecycle management, event-driven integration, and migration notes.
Badge Management
src/app/_layout.tsx
Replaces Expo Notifications badge call with Notifee setBadgeCount(0) and updates error handling type annotation.
Component Formatting
src/components/calls/dispatch-selection-modal.tsx
Formatting reflow of dynamic className strings; logic remains unchanged.
Push Notification Service
src/services/push-notification.ts
Migrates from Expo Notifications to Notifee and Firebase Messaging. Adds new listeners (onMessage, onNotificationOpenedApp, setBackgroundMessageHandler), updates permission handling to use Firebase/Notifee, reworks token retrieval to Firebase Messaging, and implements event-driven modal handling based on eventCode.
Push Notification Tests
src/services/__tests__/push-notification.test.ts
Complete test refactor replacing Expo Notifications mocks with Firebase Messaging and Notifee mocks. Adds suites for registration flow, permission states, token retrieval, and Android channel creation. Reworks test helpers and lifecycle management.

Sequence Diagram

sequenceDiagram
    participant App as App Lifecycle
    participant Notifee as Notifee
    participant FCM as Firebase Messaging
    participant Service as Push Notification<br/>Service
    participant Modal as Push Modal<br/>Store

    App->>Service: initialize()
    Service->>Notifee: createChannel(Android)
    Service->>FCM: onMessage(listener)
    Service->>FCM: onNotificationOpenedApp(listener)
    Service->>FCM: setBackgroundMessageHandler()
    Service->>FCM: getInitialNotification()
    
    rect rgb(200, 220, 255)
    Note over FCM,Service: Foreground: Message Received
    FCM->>Service: onMessage(remoteMessage)
    Service->>Service: handleRemoteMessage()
    alt eventCode present
        Service->>Modal: emit(eventCode)
    end
    end
    
    rect rgb(220, 200, 255)
    Note over FCM,Service: Background: User Taps Notification
    FCM->>Service: onNotificationOpenedApp()
    Service->>Service: handleNotificationTap()
    alt eventCode present
        Service->>Modal: emit(eventCode)
    end
    end
    
    rect rgb(200, 255, 220)
    Note over FCM,Service: Token Management
    Service->>FCM: requestPermission()
    FCM-->>Service: AuthorizationStatus
    Service->>FCM: getToken()
    FCM-->>Service: token
    Service->>Service: registerToken(backend)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

  • src/services/push-notification.ts: Extensive service refactor with new listener architecture (onMessage, onNotificationOpenedApp, setBackgroundMessageHandler), permission handling changes, and event-driven modal integration requiring careful validation of message flow, error handling, and state management.
  • src/services/tests/push-notification.test.ts: Complete test scaffolding replacement with new mock structures for Firebase Messaging and Notifee; multiple new test suites for registration, permission states, and platform-specific channel creation require verification of test coverage and mock behavior alignment.
  • docs/push-notification-fcm-refactor.md: Comprehensive documentation with detailed architecture, integration points, and migration guidance; review should validate accuracy of described flows, channel limits, and platform-specific feature descriptions.

Possibly related PRs

  • RE1-T88 Trying to use FCM for APNS #181: Modifies push-notification.ts to switch push token retrieval from Expo to Firebase messaging().getToken(), directly overlapping with token management refactoring in this PR.
  • RE1-T88 Fixing build #182: Modifies push-notification.ts to remove sendTestNotification from the hook API, addressing related changes to the push notification service public interface.

Poem

🐰 From Expo's nest to Firebase we bound,
Notifee channels, tokens newly found,
FCM whispers through the morning air,
Event codes hop with modal flair,
Push notifications, refactored with care! 📬✨

Pre-merge checks and finishing touches

✅ Passed checks (3 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 objective of the changeset: removing expo-notifications and integrating Firebase Cloud Messaging (FCM). The title is specific, concise, and directly relates to the primary refactor across multiple files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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 develop

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 834139e and 244b237.

📒 Files selected for processing (5)
  • docs/push-notification-fcm-refactor.md (1 hunks)
  • src/app/_layout.tsx (2 hunks)
  • src/components/calls/dispatch-selection-modal.tsx (4 hunks)
  • src/services/__tests__/push-notification.test.ts (15 hunks)
  • src/services/push-notification.ts (8 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Write concise, type-safe TypeScript code
Use camelCase for variable and function names (e.g., isFetchingData, handleUserInput)
Use TypeScript for all components, favoring interfaces for props and state
Avoid using any; strive for precise types
Use Expo SecureStore for sensitive data
Use zustand for state management
Use react-query for data fetching and caching
Use react-i18next for internationalization
Use react-native-mmkv for local storage
Use axios for API requests

**/*.{ts,tsx}: Write concise, type-safe TypeScript code
Use camelCase for variable and function names
Use TypeScript for all components, favoring interfaces for props and state
Avoid using any; strive for precise types
Use React Navigation for handling navigation and deep linking
Handle errors gracefully and provide user feedback
Use Expo's SecureStore for sensitive data
Use zustand for state management
Use react-query for data fetching
Use react-i18next for internationalization
Use react-native-mmkv for local storage
Use axios for API requests

Files:

  • src/app/_layout.tsx
  • src/components/calls/dispatch-selection-modal.tsx
  • src/services/__tests__/push-notification.test.ts
  • src/services/push-notification.ts
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use functional components and hooks over class components
Use PascalCase for React component names (e.g., UserProfile, ChatScreen)
Utilize React.FC for defining functional components with props
Minimize useEffect, useState, and heavy computations inside render
Use React.memo() for components with static props to prevent unnecessary re-renders
Optimize FlatList with removeClippedSubviews, maxToRenderPerBatch, windowSize
Use getItemLayout for FlatList when items have consistent size
Avoid anonymous functions in renderItem or event handlers to prevent re-renders
Use gluestack-ui for styling; if no component exists in src/components/ui, style via StyleSheet.create or styled-components
Optimize images using react-native-fast-image
Use React Navigation for navigation and deep linking with best practices
Wrap all user-facing text in t() from react-i18next
Use react-hook-form for form handling
Use @rnmapbox/maps for maps or vehicle navigation
Use lucide-react-native for icons directly in markup; do not use the gluestack-ui icon component
Use the conditional operator (?:) for conditional rendering instead of &&

**/*.tsx: Use functional components and hooks over class components
Use PascalCase for component names
Utilize React.FC for defining functional components with props
Minimize useEffect/useState and heavy computations inside render
Use React.memo for components with static props to prevent unnecessary re-renders
Optimize FlatList with removeClippedSubviews, maxToRenderPerBatch, and windowSize
Use getItemLayout for FlatList when items have consistent size
Avoid anonymous functions in renderItem or event handlers
Optimize image handling using react-native-fast-image
Wrap all user-facing text in t() from react-i18next
Ensure support for dark mode and light mode
Ensure the app is accessible following WCAG for mobile
Use react-hook-form for form handling
Use @rnmapbox/maps for maps and navigation
Use lucide-react-native for icons directly in markup; do not us...

Files:

  • src/app/_layout.tsx
  • src/components/calls/dispatch-selection-modal.tsx
**/*

📄 CodeRabbit inference engine (.cursorrules)

Directory and file names should be lowercase and hyphenated (e.g., user-profile, chat-screen)

Files:

  • src/app/_layout.tsx
  • src/components/calls/dispatch-selection-modal.tsx
  • src/services/__tests__/push-notification.test.ts
  • docs/push-notification-fcm-refactor.md
  • src/services/push-notification.ts
{components/ui/**/*.{ts,tsx},**/*.tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use gluestack-ui consistently; if no component exists in components/ui, style via StyleSheet.create or styled-components

Files:

  • src/app/_layout.tsx
  • src/components/calls/dispatch-selection-modal.tsx
**/*.{test.ts,test.tsx,spec.ts,spec.tsx}

📄 CodeRabbit inference engine (.cursorrules)

Create and use Jest tests to validate all generated components

Files:

  • src/services/__tests__/push-notification.test.ts
**/__tests__/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

Generate tests for all components, services, and logic; ensure tests run without errors

Files:

  • src/services/__tests__/push-notification.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Create and use Jest tests for all generated components

Files:

  • src/services/__tests__/push-notification.test.ts
🧠 Learnings (5)
📚 Learning: 2025-08-12T03:33:40.238Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .cursorrules:0-0
Timestamp: 2025-08-12T03:33:40.238Z
Learning: Applies to **/*.tsx : Use React Navigation for navigation and deep linking with best practices

Applied to files:

  • src/app/_layout.tsx
📚 Learning: 2025-08-12T03:34:25.992Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-12T03:34:25.992Z
Learning: Applies to **/*.tsx : Use rnmapbox/maps for maps and navigation

Applied to files:

  • src/app/_layout.tsx
📚 Learning: 2025-08-12T03:34:25.992Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-12T03:34:25.992Z
Learning: Applies to **/*.{ts,tsx} : Use React Navigation for handling navigation and deep linking

Applied to files:

  • src/app/_layout.tsx
📚 Learning: 2025-08-12T03:34:25.992Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-12T03:34:25.992Z
Learning: Applies to **/*.tsx : Use functional components and hooks over class components

Applied to files:

  • src/components/calls/dispatch-selection-modal.tsx
📚 Learning: 2025-08-12T03:33:40.238Z
Learnt from: CR
Repo: Resgrid/Unit PR: 0
File: .cursorrules:0-0
Timestamp: 2025-08-12T03:33:40.238Z
Learning: Applies to **/*.tsx : Use the conditional operator (?:) for conditional rendering instead of &&

Applied to files:

  • src/components/calls/dispatch-selection-modal.tsx
🧬 Code graph analysis (3)
src/app/_layout.tsx (1)
src/lib/logging/index.tsx (2)
  • logger (80-80)
  • error (74-76)
src/services/__tests__/push-notification.test.ts (2)
src/stores/push-notification/store.ts (1)
  • usePushNotificationModalStore (32-104)
src/services/push-notification.ts (1)
  • pushNotificationService (282-282)
src/services/push-notification.ts (3)
__mocks__/@notifee/react-native.ts (1)
  • AndroidImportance (1-8)
src/lib/logging/index.tsx (1)
  • logger (80-80)
src/stores/push-notification/store.ts (1)
  • usePushNotificationModalStore (32-104)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
src/components/calls/dispatch-selection-modal.tsx (1)

124-126: LGTM on formatting refactor—improves readability without functional changes.

The className template literals split across multiple lines maintain identical ternary logic while improving code readability. All checkbox styling patterns remain consistent. Component implementation follows all coding guidelines: proper TypeScript typing, camelCase naming, gluestack-ui components, lucide-react-native icons, react-i18next translations, and consistent dark-mode support via colorScheme.

Also applies to: 151-153, 178-180, 205-207


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.

@ucswift
Copy link
Member Author

ucswift commented Nov 10, 2025

Approve

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

This PR is approved.

@ucswift ucswift merged commit 8f359b3 into master Nov 10, 2025
13 of 14 checks passed
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