T4B_Chat/FCM_NOTIFICATION_IMPLEMENTATION_GUIDE.md

13 KiB

FCM Notification Module Implementation Guide

This document contains all the changes made to implement Firebase Cloud Messaging (FCM) notifications in the T4B_Chat React Native app. Use this guide to replicate the implementation in your production project.

📦 Package Dependencies Added

package.json Dependencies

{
  "dependencies": {
    "@react-native-firebase/app": "^23.4.0",
    "@react-native-firebase/messaging": "^23.4.0",
    "@react-native-cookies/cookies": "^6.2.0",
    "react-native-device-info": "^10.11.0",
    "react-native-permissions": "^5.2.4",
    "react-native-push-notification": "^8.1.1"
  }
}

Installation Commands

npm install @react-native-firebase/app @react-native-firebase/messaging
npm install @react-native-cookies/cookies
npm install react-native-device-info
npm install react-native-permissions
npm install react-native-push-notification

🔧 Android Configuration

1. Root build.gradle (android/build.gradle)

buildscript {
    ext {
        buildToolsVersion = "35.0.0"
        minSdkVersion = 24
        compileSdkVersion = 35
        targetSdkVersion = 35
        ndkVersion = "27.1.12297006"
        kotlinVersion = "2.0.21"
    }
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath("com.android.tools.build:gradle")
        classpath("com.facebook.react:react-native-gradle-plugin")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
        classpath("com.google.gms:google-services:4.3.15")  // ← ADD THIS
    }
}

2. App build.gradle (android/app/build.gradle)

apply plugin: "com.android.application"
apply plugin: "org.jetbrains.kotlin.android"
apply plugin: "com.facebook.react"
apply plugin: 'com.google.gms.google-services'  // ← ADD THIS

android {
    // ... existing config ...
    
    // Fix for react-native-push-notification duplicate classes
    configurations.all {
        exclude group: 'com.android.support', module: 'support-compat'
        exclude group: 'com.android.support', module: 'support-annotations'
    }
    
    defaultConfig {
        applicationId "com.t4b_chat"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0"
    }
}

dependencies {
    implementation("com.facebook.react:react-android")
    
    // AndroidX dependencies for react-native-push-notification compatibility
    implementation 'androidx.core:core:1.16.0'
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.11.0'
    
    // ... rest of dependencies ...
}

3. AndroidManifest.xml (android/app/src/main/AndroidManifest.xml)

<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>  <!-- ← ADD THIS -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />  <!-- ← ADD THIS -->
    <uses-permission android:name="android.permission.VIBRATE" />  <!-- ← ADD THIS -->

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:allowBackup="false"
      android:theme="@style/AppTheme"
      android:supportsRtl="true">
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
        android:launchMode="singleTask"
        android:windowSoftInputMode="adjustResize"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>

      <!-- FCM Service -->  <!-- ← ADD THIS ENTIRE SERVICE BLOCK -->
      <service
        android:name="com.google.firebase.messaging.FirebaseMessagingService"
        android:exported="false">
        <intent-filter>
          <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
      </service>
    </application>
</manifest>

4. Google Services Configuration

  • Add google-services.json file to android/app/ directory
  • This file comes from your Firebase project console

📱 iOS Configuration

1. Podfile (ios/Podfile)

# Resolve react_native_pods.rb with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
  'require.resolve(
    "react-native/scripts/react_native_pods.rb",
    {paths: [process.argv[1]]},
  )', __dir__]).strip

platform :ios, min_ios_version_supported
prepare_react_native_project!

linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
  Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
  use_frameworks! :linkage => linkage.to_sym
end

target 'T4B_Chat' do
  config = use_native_modules!

  use_react_native!(
    :path => config[:reactNativePath],
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

  post_install do |installer|
    react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false,
    )
  end
end

2. iOS Google Services Configuration

  • Add GoogleService-Info.plist to your iOS project
  • This file comes from your Firebase project console

📁 New Utility Files Created

1. utilities/permissionUtils.ts

Complete permission management utility for handling notification permissions across platforms.

Key functions:

  • needsNotificationPermission() - Check if device needs explicit permission
  • requestNotificationPermission() - Request notification permission
  • checkNotificationPermission() - Check current permission status
  • showPermissionExplanation() - Show user-friendly explanation dialog
  • showSettingsDialog() - Direct user to app settings

2. utilities/notificationUtils.ts

Complete notification management utility for handling local notifications.

Key functions:

  • createNotificationChannel() - Create Android notification channel
  • configureNotificationSettings() - Configure push notification settings
  • showLocalNotification() - Display local notifications
  • shouldShowCustomNotification() - Determine when to show notifications
  • testNotification() - Test notification function
  • cancelAllNotifications() - Cancel all pending notifications

🔄 App.tsx Changes

Key Imports Added

import messaging, { FirebaseMessagingTypes, AuthorizationStatus } from '@react-native-firebase/messaging';
import { getApp } from '@react-native-firebase/app';
import { 
  requestNotificationPermission, 
  checkNotificationPermission, 
  needsNotificationPermission,
  showPermissionExplanation,
  showSettingsDialog,
  PermissionResult
} from './utilities/permissionUtils';
import { RESULTS } from 'react-native-permissions';
import { 
  showLocalNotification, 
  createNotificationChannel, 
  configureNotificationSettings,
  shouldShowCustomNotification,
  testNotification
} from './utilities/notificationUtils';
import PushNotification from 'react-native-push-notification';

Key Features Implemented

  1. App State Tracking

    • Tracks app state changes to avoid duplicate notifications
    • Uses AppState.addEventListener for state monitoring
  2. FCM Message Handling

    • onMessage listener for foreground messages
    • getInitialNotification for app launch from notification
    • onNotificationOpenedApp for background notification taps
  3. Permission Management

    • Comprehensive permission checking and requesting
    • Platform-specific permission handling (Android 13+ vs older versions)
    • User-friendly permission explanation dialogs
  4. Token Management

    • FCM token retrieval and refresh handling
    • Token sending to backend (commented out - needs implementation)
  5. Notification Display

    • Custom notification display when app is active
    • Fallback to system notifications when app is backgrounded
    • Test notification functionality for debugging
  6. Firebase Warning Suppression

    • Temporary suppression of Firebase deprecation warnings

🚀 Setup Instructions for Production

1. Install Dependencies

npm install @react-native-firebase/app @react-native-firebase/messaging
npm install react-native-permissions
npm install react-native-push-notification

2. Firebase Project Setup

  1. Create Firebase project at https://console.firebase.google.com
  2. Add Android app with package name matching your applicationId
  3. Add iOS app with bundle identifier
  4. Download configuration files:
    • google-services.json for Android
    • GoogleService-Info.plist for iOS

3. Android Setup

  1. Add Google Services plugin to build.gradle files
  2. Add permissions to AndroidManifest.xml
  3. Add FCM service to AndroidManifest.xml
  4. Add AndroidX dependencies for compatibility

4. iOS Setup

  1. Add GoogleService-Info.plist to Xcode project
  2. Run cd ios && pod install
  3. Enable Push Notifications capability in Xcode

5. Code Integration

  1. Copy both utility files to your project
  2. Integrate App.tsx changes
  3. Update package.json dependencies
  4. Test notification functionality

🧪 Testing

Test Notification Function

The implementation includes a test notification function accessible via:

  • URL navigation to test-notification endpoint
  • Global function global.testNotification() in development
  • Console logging for debugging

Debug Features

  • Comprehensive console logging throughout the notification flow
  • Permission status logging
  • FCM token logging
  • App state change logging

🔗 Backend Integration

FCM Token Registration

The app automatically sends FCM tokens to your Odoo backend using the following endpoint:

Endpoint: POST https://your-odoo.com/fcm/register

Headers:

{
  "Content-Type": "application/json",
  "Cookie": "session_id=YOUR_SESSION_COOKIE"
}

Request Body:

{
  "token": "FCM_TOKEN_STRING",
  "device_name": "iPhone 12",
  "device_type": "ios",
  "app_version": "1.0.0",
  "os_version": "15.0"
}

Device Information Collection

The implementation automatically collects device information using react-native-device-info:

  • device_name: Device model name (e.g., "iPhone 12", "Samsung Galaxy S21")
  • device_type: Platform ("ios" or "android")
  • app_version: App version from package.json
  • os_version: Operating system version

Session Management

Native Cookie Extraction: The implementation uses @react-native-cookies/cookies to automatically extract session cookies from the native cookie store. The getWebViewCookies() function:

  1. Accesses native cookie store using @react-native-cookies/cookies library
  2. Retrieves all cookies for the Odoo domain
  3. Filters and extracts session_id from available cookies
  4. Updates automatically every 30 seconds to keep cookies fresh
  5. Validates cookies before sending FCM token registration

The system automatically handles session management without manual intervention and is much more reliable than JavaScript injection methods.

Token Refresh Handling

The app automatically handles FCM token refresh and sends updated tokens to the backend whenever they change.

⚠️ Important Notes

  1. Backend Integration: The sendTokenToBackend() function is implemented and automatically sends FCM tokens to your Odoo backend at /fcm/register endpoint.

  2. Session Management: The implementation automatically extracts session cookies from the WebView, so no manual session management is required.

  3. Device Information: The implementation uses react-native-device-info to automatically collect device information (device name, type, app version, OS version).

  4. Firebase Warnings: Temporary warning suppression is in place until Firebase v22+ is stable.

  5. Permission Handling: The implementation handles Android 13+ permission requirements automatically.

  6. Production Considerations:

    • Update signing configuration for release builds
    • Test on both Android and iOS devices
    • Verify notification delivery in all app states
    • Ensure WebView loads and user can log in to extract session cookies

📋 Checklist for Production Migration

  • Install all required npm packages
  • Add Google Services configuration files
  • Update Android build.gradle files
  • Update AndroidManifest.xml with permissions and FCM service
  • Copy utility files (permissionUtils.ts, notificationUtils.ts)
  • Integrate App.tsx changes
  • Test on Android device (API 33+ for permission testing)
  • Test on iOS device
  • Implement backend token registration
  • Test notification delivery in all app states
  • Remove debug/test code before production release

This implementation provides a complete FCM notification system with proper permission handling, platform-specific optimizations, and comprehensive error handling.