# Troubleshooting Guide

This comprehensive troubleshooting guide covers common issues with the Milton Health Coach FCM Client SDK, push notifications, and polling functionality.

## Table of Contents

1. [Installation Issues](#installation-issues)
2. [Firebase Setup Issues](#firebase-setup-issues)
3. [Push Notification Issues](#push-notification-issues)
4. [Polling Issues](#polling-issues)
5. [Network and Connectivity Issues](#network-and-connectivity-issues)
6. [Offline Handling Issues](#offline-handling-issues)
7. [Performance Issues](#performance-issues)
8. [Platform-Specific Issues](#platform-specific-issues)
9. [Debug Tools and Commands](#debug-tools-and-commands)

## Installation Issues

### SDK Installation Fails

**Problem**: `npm install @milton/fcm-client-sdk` fails

**Solutions**:
```bash
# Clear npm cache
npm cache clean --force

# Delete node_modules and reinstall
rm -rf node_modules package-lock.json
npm install

# Try with yarn instead
yarn add @milton/fcm-client-sdk

# Check Node.js version (requires 14+)
node --version
```

### Firebase Dependencies Not Installing

**Problem**: Firebase packages fail to install or cause conflicts

**Solutions**:
```bash
# Install specific versions
npm install @react-native-firebase/app@18.6.2 @react-native-firebase/messaging@18.6.2

# For iOS, install pods
cd ios && pod install && cd ..

# Clean and reinstall
npx react-native clean
cd ios && rm -rf build && pod install && cd ..
```

### Metro Bundler Issues

**Problem**: Metro bundler fails to resolve SDK modules

**Solutions**:
```bash
# Reset Metro cache
npx react-native start --reset-cache

# Clear watchman cache
watchman watch-del-all

# Update metro.config.js
module.exports = {
  resolver: {
    assetExts: ['bin', 'txt', 'jpg', 'png', 'json'],
  },
};
```

## Firebase Setup Issues

### google-services.json Not Found (Android)

**Problem**: Build fails with "google-services.json not found"

**Solutions**:
1. Ensure file is in `android/app/google-services.json` (not `android/`)
2. Check file permissions: `chmod 644 android/app/google-services.json`
3. Verify Google Services plugin is applied:
   ```gradle
   // android/app/build.gradle
   apply plugin: 'com.google.gms.google-services'
   ```
4. Clean and rebuild:
   ```bash
   cd android && ./gradlew clean && cd ..
   npx react-native run-android
   ```

### GoogleService-Info.plist Not Found (iOS)

**Problem**: Build fails with "GoogleService-Info.plist not found"

**Solutions**:
1. Add file to Xcode project (not just file system):
   - Open Xcode
   - Right-click project → "Add Files to [ProjectName]"
   - Select `GoogleService-Info.plist`
   - Ensure "Add to target" is checked
2. Verify file is in target membership:
   - Select file in Xcode
   - Check "Target Membership" in File Inspector
3. Clean build folder: Product → Clean Build Folder

### Firebase Initialization Fails

**Problem**: `[FIRApp configure]` fails or Firebase not initialized

**Solutions**:

**Android**:
```java
// MainApplication.java
import io.invertase.firebase.app.ReactNativeFirebaseAppPackage;

@Override
protected List<ReactPackage> getPackages() {
  return Arrays.<ReactPackage>asList(
    new MainReactPackage(),
    new ReactNativeFirebaseAppPackage(), // Add this
    // ... other packages
  );
}
```

**iOS**:
```objc
// AppDelegate.m
#import <Firebase.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  [FIRApp configure]; // Add this line first
  // ... rest of code
}
```

## Push Notification Issues

### FCM Token Not Generated

**Problem**: `messaging().getToken()` returns null or fails

**Solutions**:
1. **Check permissions**:
   ```javascript
   const authStatus = await messaging().requestPermission();
   console.log('Permission status:', authStatus);
   ```

2. **Verify Firebase setup**:
   ```javascript
   import { firebase } from '@react-native-firebase/app';
   console.log('Firebase apps:', firebase.apps);
   ```

3. **Test on real device** (not simulator for iOS)

4. **Check Google Play Services** (Android):
   - Ensure device has Google Play Services
   - Update to latest version

### Push Notifications Not Received

**Problem**: Notifications sent but not received on device

**Solutions**:

**General**:
1. **Test with Firebase Console**:
   - Go to Firebase Console → Cloud Messaging
   - Send test message with your FCM token
   - Check if received

2. **Check notification permissions**:
   ```javascript
   import { check, PERMISSIONS, request } from 'react-native-permissions';
   
   const checkPermission = async () => {
     const result = await check(PERMISSIONS.ANDROID.POST_NOTIFICATIONS);
     console.log('Notification permission:', result);
   };
   ```

**Android Specific**:
1. **Battery optimization**:
   - Add app to battery optimization whitelist
   - Settings → Battery → Battery Optimization → [Your App] → Don't optimize

2. **Notification channels** (Android 8+):
   ```javascript
   import notifee from '@notifee/react-native';
   
   await notifee.createChannel({
     id: 'milton_notifications',
     name: 'Milton Notifications',
     importance: AndroidImportance.HIGH,
   });
   ```

3. **Background restrictions**:
   - Settings → Apps → [Your App] → Battery → Background Activity → Allow

**iOS Specific**:
1. **Check notification settings**:
   - Settings → [Your App] → Notifications → Allow Notifications

2. **APNs certificate/key**:
   - Verify APNs key is uploaded to Firebase
   - Check key permissions and Team ID

3. **Provisioning profile**:
   - Ensure push notifications capability is enabled
   - Regenerate provisioning profile if needed

### Background Notifications Not Working

**Problem**: Notifications work in foreground but not background

**Solutions**:

**Android**:
```xml
<!-- android/app/src/main/AndroidManifest.xml -->
<service
  android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService"
  android:exported="false">
  <intent-filter>
    <action android:name="com.google.firebase.MESSAGING_EVENT" />
  </intent-filter>
</service>
```

**iOS**:
1. **Enable Background Modes**:
   - Xcode → Target → Signing & Capabilities
   - Add "Background Modes"
   - Enable "Remote notifications"

2. **Handle background notifications**:
   ```objc
   // AppDelegate.m
   - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
   fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
     // Handle background notification
     completionHandler(UIBackgroundFetchResultNewData);
   }
   ```

### Notification Data Not Received

**Problem**: Notification received but data payload is empty

**Solutions**:
1. **Check data format**:
   ```javascript
   messaging().onMessage(async remoteMessage => {
     console.log('Full message:', remoteMessage);
     console.log('Data:', remoteMessage.data);
     console.log('Notification:', remoteMessage.notification);
   });
   ```

2. **Server payload format**:
   ```json
   {
     "to": "FCM_TOKEN",
     "data": {
       "request_id": "uuid",
       "type": "analysis_complete"
     },
     "notification": {
       "title": "Milton Health Coach",
       "body": "Your analysis is ready!"
     }
   }
   ```

## Polling Issues

### Polling Not Starting

**Problem**: SDK doesn't start polling after request submission

**Solutions**:
1. **Check request submission**:
   ```javascript
   const response = await client.submitUserMessage(request, {
     onProgress: (status) => {
       console.log('Polling progress:', status); // Should see this
     }
   });
   console.log('Request ID:', response.request_id);
   ```

2. **Verify network connectivity**:
   ```javascript
   import NetInfo from '@react-native-community/netinfo';
   
   NetInfo.fetch().then(state => {
     console.log('Connection type:', state.type);
     console.log('Is connected?', state.isConnected);
   });
   ```

3. **Check API endpoint**:
   ```javascript
   // Test status endpoint directly
   const status = await client.getRequestStatus('your-request-id');
   console.log('Status:', status);
   ```

### Polling Stops Prematurely

**Problem**: Polling stops before request completion

**Solutions**:
1. **Check app state handling**:
   ```javascript
   import { AppState } from 'react-native';
   
   AppState.addEventListener('change', (nextAppState) => {
     console.log('App state changed to:', nextAppState);
   });
   ```

2. **Verify polling configuration**:
   ```javascript
   const client = new MiltonAsyncClient({
     // ... other config
     pollingConfig: {
       intervals: [1, 2, 4, 8, 15, 30],
       maxAttempts: 6, // Increase if needed
       timeoutMs: 30000
     }
   });
   ```

3. **Check for errors**:
   ```javascript
   const response = await client.submitUserMessage(request, {
     onError: (error) => {
       console.error('Polling error:', error);
     }
   });
   ```

### Polling Continues After Push Notification

**Problem**: Polling doesn't stop when push notification is received

**Solutions**:
1. **Verify push notification data**:
   ```javascript
   messaging().onMessage(async remoteMessage => {
     console.log('Push data:', remoteMessage.data);
     // Should contain: { request_id: "uuid", type: "analysis_complete" }
   });
   ```

2. **Check notification handling**:
   ```javascript
   // SDK should automatically handle this, but you can debug:
   messaging().onMessage(async remoteMessage => {
     if (remoteMessage.data?.type === 'analysis_complete') {
       console.log('Completion notification received for:', remoteMessage.data.request_id);
     }
   });
   ```

## Network and Connectivity Issues

### API Connection Fails

**Problem**: SDK can't connect to Milton API

**Solutions**:
1. **Verify API URL and key**:
   ```javascript
   const client = new MiltonAsyncClient({
     baseUrl: 'https://api.milton.com', // Check this URL
     apiKey: 'your-actual-api-key', // Verify key is correct
   });
   ```

2. **Test API directly**:
   ```bash
   curl -H "Authorization: Bearer YOUR_API_KEY" https://api.milton.com/health
   ```

3. **Check network permissions** (Android):
   ```xml
   <!-- android/app/src/main/AndroidManifest.xml -->
   <uses-permission android:name="android.permission.INTERNET" />
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
   ```

### CORS Issues (Web/Debug)

**Problem**: CORS errors when testing in web environment

**Solutions**:
1. **Use device/emulator** instead of web browser
2. **Configure Metro for web** (if needed):
   ```javascript
   // metro.config.js
   module.exports = {
     resolver: {
       platforms: ['ios', 'android', 'native', 'web'],
     },
   };
   ```

### SSL/TLS Issues

**Problem**: SSL certificate errors

**Solutions**:
1. **Update certificates**:
   ```bash
   # Android
   cd android && ./gradlew clean && cd ..
   
   # iOS
   cd ios && pod install && cd ..
   ```

2. **Check system time** - ensure device time is correct

3. **Test with different network** (WiFi vs cellular)

## Offline Handling Issues

### Offline Queue Not Working

**Problem**: Requests not queued when offline

**Solutions**:
1. **Enable offline queue**:
   ```javascript
   const client = new MiltonAsyncClient({
     // ... other config
     offlineConfig: {
       enableOfflineQueue: true,
       maxQueueSize: 50,
       retryAttempts: 3
     }
   });
   ```

2. **Check storage permissions**:
   ```javascript
   import AsyncStorage from '@react-native-async-storage/async-storage';
   
   // Test AsyncStorage
   try {
     await AsyncStorage.setItem('test', 'value');
     const value = await AsyncStorage.getItem('test');
     console.log('AsyncStorage working:', value === 'value');
   } catch (error) {
     console.error('AsyncStorage error:', error);
   }
   ```

3. **Monitor queue status**:
   ```javascript
   const queueStatus = client.getOfflineQueueStatus();
   console.log('Queue status:', queueStatus);
   ```

### Offline Requests Not Processing

**Problem**: Queued requests don't process when back online

**Solutions**:
1. **Check network state detection**:
   ```javascript
   import NetInfo from '@react-native-community/netinfo';
   
   const unsubscribe = NetInfo.addEventListener(state => {
     console.log('Network state:', state);
   });
   ```

2. **Manually trigger queue processing**:
   ```javascript
   // Force process offline queue (for debugging)
   client.processOfflineQueue();
   ```

3. **Check app state handling**:
   ```javascript
   import { AppState } from 'react-native';
   
   AppState.addEventListener('change', (nextAppState) => {
     if (nextAppState === 'active') {
       console.log('App became active - should process offline queue');
     }
   });
   ```

## Performance Issues

### High Battery Usage

**Problem**: SDK drains battery quickly

**Solutions**:
1. **Enable battery optimization**:
   ```javascript
   const client = new MiltonAsyncClient({
     pollingConfig: {
       batteryOptimized: true,
       backgroundIntervals: [30, 60, 120, 300] // Longer intervals
     }
   });
   ```

2. **Reduce polling frequency**:
   ```javascript
   const client = new MiltonAsyncClient({
     pollingConfig: {
       intervals: [2, 5, 10, 30], // Less frequent polling
       maxAttempts: 4
     }
   });
   ```

3. **Use push notifications** instead of polling when possible

### Memory Leaks

**Problem**: App memory usage increases over time

**Solutions**:
1. **Dispose client properly**:
   ```javascript
   useEffect(() => {
     return () => {
       client.dispose(); // Clean up on unmount
     };
   }, []);
   ```

2. **Clear completed requests**:
   ```javascript
   // Periodically clear offline queue
   await client.clearOfflineQueue();
   ```

3. **Monitor active requests**:
   ```javascript
   const status = client.getOfflineQueueStatus();
   console.log('Active requests:', status.activePollingRequests);
   ```

### Slow Response Times

**Problem**: API requests are slow

**Solutions**:
1. **Increase timeout**:
   ```javascript
   const client = new MiltonAsyncClient({
     timeout: 60000, // 60 seconds
   });
   ```

2. **Check network quality**:
   ```javascript
   import NetInfo from '@react-native-community/netinfo';
   
   NetInfo.fetch().then(state => {
     console.log('Connection quality:', state.details);
   });
   ```

3. **Use appropriate polling intervals**:
   ```javascript
   const client = new MiltonAsyncClient({
     pollingConfig: {
       intervals: [1, 2, 4, 8, 15, 30], // Exponential backoff
     }
   });
   ```

## Platform-Specific Issues

### Android Issues

**Build Errors**:
```bash
# Clean everything
cd android && ./gradlew clean && cd ..
rm -rf node_modules && npm install
npx react-native run-android --reset-cache
```

**ProGuard Issues**:
```proguard
# android/app/proguard-rules.pro
-keep class io.invertase.firebase.** { *; }
-keep class com.google.firebase.** { *; }
```

**Multidex Issues**:
```gradle
// android/app/build.gradle
android {
    defaultConfig {
        multiDexEnabled true
    }
}

dependencies {
    implementation 'androidx.multidex:multidex:2.0.1'
}
```

### iOS Issues

**Pod Installation Fails**:
```bash
cd ios
rm -rf Pods Podfile.lock
pod cache clean --all
pod install
```

**Code Signing Issues**:
1. Check provisioning profile includes push notifications
2. Verify team ID matches Firebase configuration
3. Regenerate certificates if needed

**Simulator Issues**:
- Push notifications don't work on iOS Simulator
- Always test on real device
- Use Xcode device logs for debugging

## Debug Tools and Commands

### Enable Debug Logging

```javascript
// Enable console logging
console.log = (...args) => {
  // Your logging implementation
};

// Monitor SDK events
const client = new MiltonAsyncClient({
  // ... config
});

// Log all network requests
global.XMLHttpRequest = require('react-native/Libraries/Network/XMLHttpRequest');
```

### Useful Commands

```bash
# React Native
npx react-native doctor
npx react-native info
npx react-native clean

# Android
cd android && ./gradlew clean && cd ..
adb logcat | grep -i firebase
adb logcat | grep -i milton

# iOS
xcrun simctl list devices
xcrun simctl erase all
tail -f ~/Library/Logs/CoreSimulator/*/system.log

# Firebase
npx @react-native-firebase/app:android:generate-json
npx @react-native-firebase/app:ios:generate-plist

# Network debugging
adb shell dumpsys connectivity
```

### Debug Configuration

```javascript
// Debug client configuration
const debugClient = new MiltonAsyncClient({
  baseUrl: 'https://dev-api.milton.com',
  apiKey: 'debug-api-key',
  timeout: 10000, // Shorter timeout for debugging
  enablePushNotifications: true,
  pollingConfig: {
    intervals: [1, 2, 4], // Shorter intervals for debugging
    maxAttempts: 3
  }
});

// Add debug listeners
debugClient.submitUserMessage(request, {
  onProgress: (status) => {
    console.log(`[DEBUG] Progress: ${JSON.stringify(status)}`);
  },
  onComplete: (result) => {
    console.log(`[DEBUG] Complete: ${JSON.stringify(result)}`);
  },
  onError: (error) => {
    console.error(`[DEBUG] Error: ${error.message}`);
    console.error(`[DEBUG] Stack: ${error.stack}`);
  }
});
```

### Testing Checklist

Before reporting issues, verify:

- [ ] Firebase configuration files are correctly placed
- [ ] Push notification permissions are granted
- [ ] Network connectivity is available
- [ ] API key and endpoint are correct
- [ ] Device time is accurate
- [ ] App is tested on real device (not simulator for push notifications)
- [ ] Latest SDK version is installed
- [ ] Dependencies are up to date

### Getting Help

If issues persist:

1. **Check logs** for specific error messages
2. **Test with minimal example** to isolate the issue
3. **Verify Firebase setup** with Firebase Console test message
4. **Create GitHub issue** with:
   - SDK version
   - React Native version
   - Platform (iOS/Android)
   - Device/emulator details
   - Complete error logs
   - Minimal reproduction code

For support:
- Email: sanjay@joinmmnt.com