more package declarations
This commit is contained in:
389
docs/MOBILE_PUSH_INTEGRATION.md
Normal file
389
docs/MOBILE_PUSH_INTEGRATION.md
Normal file
@@ -0,0 +1,389 @@
|
||||
# Push Notifications - Mobile App Quick Start
|
||||
|
||||
This guide helps you integrate push notifications into the ShieldAI React Native mobile app.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before starting, ensure:
|
||||
- ✅ Backend push notification infrastructure is deployed
|
||||
- ✅ Firebase project is set up (for Android)
|
||||
- ✅ Apple Developer account is active (for iOS)
|
||||
- ✅ Environment variables are configured on the backend
|
||||
|
||||
## Step 1: Install Dependencies
|
||||
|
||||
```bash
|
||||
npm install @react-native-firebase/app @react-native-firebase/messaging
|
||||
```
|
||||
|
||||
## Step 2: Android Setup
|
||||
|
||||
### 2.1 Add Firebase to Android Project
|
||||
|
||||
1. Go to [Firebase Console](https://console.firebase.google.com)
|
||||
2. Select your ShieldAI project
|
||||
3. Add Android app with package name: `com.shieldai.mobile`
|
||||
4. Download `google-services.json`
|
||||
5. Place it in `android/app/google-services.json`
|
||||
|
||||
### 2.2 Update Build Configuration
|
||||
|
||||
In `android/build.gradle`:
|
||||
```gradle
|
||||
buildscript {
|
||||
dependencies {
|
||||
classpath 'com.google.gms:google-services:4.4.0'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In `android/app/build.gradle`:
|
||||
```gradle
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
```
|
||||
|
||||
### 2.3 Request Permissions
|
||||
|
||||
In `AndroidManifest.xml`:
|
||||
```xml
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
```
|
||||
|
||||
## Step 3: iOS Setup
|
||||
|
||||
### 3.1 Enable Push Notifications
|
||||
|
||||
1. Open Xcode project
|
||||
2. Select your app target
|
||||
3. Go to "Signing & Capabilities"
|
||||
4. Click "+ Capability"
|
||||
5. Add "Push Notifications"
|
||||
6. Add "Background Modes" and check "Remote notifications"
|
||||
|
||||
### 3.2 Configure Firebase
|
||||
|
||||
1. Download `GoogleService-Info.plist` from Firebase Console
|
||||
2. Add it to your Xcode project (drag to project folder)
|
||||
3. Ensure "Copy items if needed" is checked
|
||||
|
||||
### 3.3 Add Import in AppDelegate.swift
|
||||
|
||||
```swift
|
||||
import FirebaseMessaging
|
||||
import UserNotifications
|
||||
|
||||
@main
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
|
||||
|
||||
func application(_ application: UIApplication,
|
||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
FirebaseApp.configure()
|
||||
Messaging.messaging().delegate = self
|
||||
return true
|
||||
}
|
||||
|
||||
// Request permission
|
||||
func requestAuthorization() {
|
||||
UNUserNotificationCenter.current().delegate = self
|
||||
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
|
||||
UNUserNotificationCenter.current().requestAuthorization(
|
||||
options: authOptions,
|
||||
completionHandler: { granted, error in
|
||||
if granted {
|
||||
DispatchQueue.main.async {
|
||||
UIApplication.shared.registerForRemoteNotifications()
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// Handle token refresh
|
||||
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
|
||||
print("FCM token refreshed: \(fcmToken)")
|
||||
// Send new token to backend
|
||||
registerDeviceToken(fcmToken)
|
||||
}
|
||||
|
||||
// Handle foreground notifications
|
||||
func userNotificationCenter(_ center: UNUserNotificationCenter,
|
||||
willPresent notification: UNNotification,
|
||||
withCompletionHandler completionHandler:
|
||||
@escaping (UNNotificationPresentationOptions) -> Void) {
|
||||
let userInfo = notification.request.content.userInfo
|
||||
print("Foreground notification: \(userInfo)")
|
||||
completionHandler([.banner, .sound, .badge])
|
||||
}
|
||||
|
||||
// Handle notification tap
|
||||
func userNotificationCenter(_ center: UNUserNotificationCenter,
|
||||
didReceive response: UNNotificationResponse,
|
||||
withCompletionHandler completionHandler: @escaping () -> Void) {
|
||||
let userInfo = response.notification.request.content.userInfo
|
||||
print("Notification tapped: \(userInfo)")
|
||||
completionHandler()
|
||||
}
|
||||
}
|
||||
|
||||
extension AppDelegate: MessagingDelegate {
|
||||
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
|
||||
print("FCM token received: \(fcmToken ?? "none")")
|
||||
if let token = fcmToken {
|
||||
registerDeviceToken(token)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to register with backend
|
||||
func registerDeviceToken(_ token: String) {
|
||||
// Call your API to register the device
|
||||
// POST /api/v1/devices/register
|
||||
// Body: { userId, platform: "ios", token, deviceType: "mobile" }
|
||||
}
|
||||
```
|
||||
|
||||
## Step 4: React Native Integration
|
||||
|
||||
### 4.1 Create Notification Service
|
||||
|
||||
Create `src/services/NotificationService.ts`:
|
||||
|
||||
```typescript
|
||||
import messaging from '@react-native-firebase/messaging';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import axios from 'axios';
|
||||
|
||||
const API_BASE_URL = 'https://api.shieldai.com/api/v1';
|
||||
|
||||
export class NotificationService {
|
||||
private static instance: NotificationService;
|
||||
private userId: string | null = null;
|
||||
|
||||
private constructor() {}
|
||||
|
||||
static getInstance(): NotificationService {
|
||||
if (!NotificationService.instance) {
|
||||
NotificationService.instance = new NotificationService();
|
||||
}
|
||||
return NotificationService.instance;
|
||||
}
|
||||
|
||||
setUserId(userId: string) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
async requestPermission(): Promise<boolean> {
|
||||
try {
|
||||
const authStatus = await messaging().requestPermission();
|
||||
const enabled =
|
||||
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
|
||||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
|
||||
|
||||
if (enabled) {
|
||||
console.log('Push notification permission granted');
|
||||
await this.registerDevice();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (error) {
|
||||
console.error('Failed to request permission:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async registerDevice(): Promise<void> {
|
||||
if (!this.userId) {
|
||||
console.warn('User ID not set, cannot register device');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const token = await messaging().getToken();
|
||||
const platform = Platform.OS === 'ios' ? 'ios' : 'android';
|
||||
|
||||
const response = await axios.post(`${API_BASE_URL}/devices/register`, {
|
||||
userId: this.userId,
|
||||
platform,
|
||||
token,
|
||||
deviceType: 'mobile',
|
||||
appName: 'ShieldAI Mobile',
|
||||
appVersion: '1.0.0',
|
||||
});
|
||||
|
||||
console.log('Device registered:', response.data);
|
||||
} catch (error) {
|
||||
console.error('Failed to register device:', error);
|
||||
}
|
||||
}
|
||||
|
||||
setupListeners() {
|
||||
// Foreground messages
|
||||
messaging().onMessage(async (remoteMessage) => {
|
||||
console.log('Foreground message received:', remoteMessage);
|
||||
// Show local notification
|
||||
this.showLocalNotification(remoteMessage);
|
||||
});
|
||||
|
||||
// Background messages
|
||||
messaging().setBackgroundMessageHandler(async (remoteMessage) => {
|
||||
console.log('Background message received:', remoteMessage);
|
||||
});
|
||||
|
||||
// Notification opened
|
||||
messaging().onNotificationOpenedApp((remoteMessage) => {
|
||||
console.log('Notification opened app:', remoteMessage);
|
||||
// Navigate to relevant screen
|
||||
this.handleNotificationTap(remoteMessage);
|
||||
});
|
||||
|
||||
// Check if app was opened from notification
|
||||
messaging()
|
||||
.getInitialNotification()
|
||||
.then((remoteMessage) => {
|
||||
if (remoteMessage) {
|
||||
console.log('App opened from notification:', remoteMessage);
|
||||
this.handleNotificationTap(remoteMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private showLocalNotification(message: any) {
|
||||
// Use react-native-push-notification or similar
|
||||
console.log('Show notification:', message.notification?.title);
|
||||
}
|
||||
|
||||
private handleNotificationTap(message: any) {
|
||||
// Navigate to relevant screen based on notification data
|
||||
const { alertId, type } = message.data || {};
|
||||
if (alertId) {
|
||||
// Navigate to alert detail
|
||||
console.log('Navigate to alert:', alertId);
|
||||
}
|
||||
}
|
||||
|
||||
async deregisterDevice(): Promise<void> {
|
||||
if (!this.userId) return;
|
||||
|
||||
try {
|
||||
const token = await messaging().getToken();
|
||||
await axios.post(`${API_BASE_URL}/devices/deregister`, {
|
||||
token,
|
||||
userId: this.userId,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to deregister device:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 Initialize in App Component
|
||||
|
||||
```typescript
|
||||
// App.tsx
|
||||
import React, { useEffect } from 'react';
|
||||
import { NotificationService } from './src/services/NotificationService';
|
||||
|
||||
const notificationService = NotificationService.getInstance();
|
||||
|
||||
function App() {
|
||||
useEffect(() => {
|
||||
// Initialize push notifications
|
||||
notificationService.setupListeners();
|
||||
}, []);
|
||||
|
||||
// When user logs in
|
||||
const handleLogin = async (userId: string) => {
|
||||
notificationService.setUserId(userId);
|
||||
await notificationService.requestPermission();
|
||||
};
|
||||
|
||||
// When user logs out
|
||||
const handleLogout = async () => {
|
||||
await notificationService.deregisterDevice();
|
||||
notificationService.setUserId('');
|
||||
};
|
||||
|
||||
return (
|
||||
// Your app components
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Step 5: Testing
|
||||
|
||||
### Android Emulator
|
||||
|
||||
1. Start Android emulator with Google Play Services
|
||||
2. Install and run app
|
||||
3. Trigger a test notification from backend
|
||||
4. Check notification appears
|
||||
|
||||
### iOS Device (Required)
|
||||
|
||||
iOS Simulator does not support push notifications. Use a real device.
|
||||
|
||||
### Backend Test
|
||||
|
||||
```bash
|
||||
# Test notification API
|
||||
curl -X POST https://api.shieldai.com/api/v1/notifications/send \
|
||||
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"userId": "user-uuid",
|
||||
"channel": "push",
|
||||
"subject": "Test Alert",
|
||||
"body": "This is a test notification from ShieldAI",
|
||||
"priority": "high",
|
||||
"metadata": {
|
||||
"alertId": "alert-uuid",
|
||||
"type": "darkweb_exposure"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Android Issues
|
||||
|
||||
**Problem**: Token not received
|
||||
- Check `google-services.json` is in correct location
|
||||
- Verify Firebase project ID matches
|
||||
- Check internet connection on emulator
|
||||
|
||||
**Problem**: Notifications not showing
|
||||
- Ensure notification permissions granted
|
||||
- Check battery optimization settings
|
||||
- Verify notification channel is created
|
||||
|
||||
### iOS Issues
|
||||
|
||||
**Problem**: Token not received
|
||||
- Verify Push Notifications capability is enabled
|
||||
- Check APNs key configuration in backend
|
||||
- Ensure device is not in development mode if using production certs
|
||||
|
||||
**Problem**: Notifications not showing
|
||||
- Check notification permissions granted
|
||||
- Verify APNs configuration on backend
|
||||
- Ensure proper certificate/key is used
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. ✅ Set up Firebase project
|
||||
2. ✅ Configure APNs on Apple Developer Portal
|
||||
3. ✅ Implement notification handling in app
|
||||
4. ✅ Test on Android device/emulator
|
||||
5. ✅ Test on iOS device
|
||||
6. ✅ Integrate with DarkWatch and SpamShield alerts
|
||||
7. ✅ Add notification preferences UI
|
||||
8. ✅ Implement deep linking from notifications
|
||||
|
||||
## Resources
|
||||
|
||||
- [Firebase Cloud Messaging Docs](https://firebase.google.com/docs/cloud-messaging)
|
||||
- [React Native Firebase Messaging](https://rnfirebase.io/messaging/usage)
|
||||
- [Apple Push Notification Service](https://developer.apple.com/documentation/usernotifications)
|
||||
Reference in New Issue
Block a user