From 000ced34956cd8088fdff4938f16896e63c25ddd Mon Sep 17 00:00:00 2001 From: millerm30 Date: Fri, 28 Nov 2025 10:39:50 -0330 Subject: [PATCH 01/28] initial setup for branch --- .gitignore | 8 + QUICK_START.md | 215 ++++++++ README.md | 407 ++++++++++++++ TESTING.md | 498 ++++++++++++++++++ android/build.gradle | 2 + .../rn/NotificationApiModule.kt | 62 ++- ios/NotificationApiModule-Bridging-Header.h | 7 + ios/NotificationApiModule.h | 7 + ios/NotificationApiModule.m | 173 ++++++ js/NativeNotificationApi.ts | 11 +- js/NotificationAPI.ts | 206 ++++++++ js/NotificationAPIService.ts | 230 ++++++++ js/events.ts | 46 ++ js/index.ts | 49 ++ js/models.ts | 137 +++++ package-lock.json | 4 + package.json | 30 +- tsconfig.json | 32 ++ 18 files changed, 2116 insertions(+), 8 deletions(-) create mode 100644 QUICK_START.md create mode 100644 README.md create mode 100644 TESTING.md create mode 100644 ios/NotificationApiModule-Bridging-Header.h create mode 100644 ios/NotificationApiModule.h create mode 100644 ios/NotificationApiModule.m create mode 100644 js/NotificationAPI.ts create mode 100644 js/NotificationAPIService.ts create mode 100644 js/events.ts create mode 100644 js/index.ts create mode 100644 js/models.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore index f778c2c..368e4e4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,12 @@ node_modules .DS_Store **/local.properties android/.gradle +android/build +android/app/build +ios/build +ios/Pods +ios/*.xcworkspace +ios/*.xcuserdata .history +dist +*.log diff --git a/QUICK_START.md b/QUICK_START.md new file mode 100644 index 0000000..43c2557 --- /dev/null +++ b/QUICK_START.md @@ -0,0 +1,215 @@ +# Quick Start Guide - Testing the SDK + +## Prerequisites Checklist + +### For iOS Testing (Physical iPhone) + +✅ **Required:** +- macOS computer (Xcode only works on Mac) +- Xcode installed (free from App Store) +- iPhone connected via USB +- Apple ID (free account works for development) +- React Native CLI installed: `npm install -g react-native-cli` + +✅ **Optional but Recommended:** +- CocoaPods: `sudo gem install cocoapods` +- Node.js and npm/yarn + +### For Android Testing (Easier to Start) + +✅ **Required:** +- Any OS (Windows, macOS, Linux) +- Android Studio installed +- Android emulator OR physical Android device +- React Native CLI + +## Easiest Path: Start with Android + +Android is easier to test because: +- Works on any OS (not just macOS) +- No Apple Developer account needed +- Emulator works without physical device +- Faster initial setup + +### Step 1: Create Test App + +```bash +npx react-native init NotificationAPITestApp +cd NotificationAPITestApp +``` + +### Step 2: Link SDK + +```bash +# From SDK directory +cd ../notificationapi-react-native-sdk +npm link + +# Back to test app +cd ../NotificationAPITestApp +npm link notificationapi-react-native-sdk +npm install +``` + +### Step 3: Add Test Code + +Copy the test code from `TESTING.md` into `App.tsx` + +### Step 4: Run on Android + +```bash +# Start Android emulator from Android Studio first, then: +npx react-native run-android +``` + +## For iOS Testing (macOS + iPhone) + +### Step 1: Same as Android (create app, link SDK) + +### Step 2: iOS-Specific Setup + +1. **Install CocoaPods** (if not installed): + ```bash + sudo gem install cocoapods + ``` + +2. **Install iOS dependencies**: + ```bash + cd ios + pod install + cd .. + ``` + +3. **Open in Xcode**: + ```bash + open ios/NotificationAPITestApp.xcworkspace + ``` + ⚠️ Important: Open `.xcworkspace`, NOT `.xcodeproj` + +4. **Configure Signing**: + - In Xcode, select your project in the left sidebar + - Select the target + - Go to "Signing & Capabilities" + - Check "Automatically manage signing" + - Select your Team (your Apple ID) + +5. **Enable Push Notifications**: + - Still in "Signing & Capabilities" + - Click "+ Capability" + - Add "Push Notifications" + +6. **Update AppDelegate** (for APN token): + - Open `ios/NotificationAPITestApp/AppDelegate.m` (or `.swift`) + - Add the token handling code (see TESTING.md) + +7. **Connect iPhone**: + - Connect via USB + - Trust the computer on iPhone if prompted + - In Xcode, select your iPhone from the device dropdown (top toolbar) + +8. **Run**: + ```bash + npx react-native run-ios --device + ``` + Or click the Play button in Xcode + +### Step 3: Trust Developer on iPhone + +First time running: +- On iPhone: Settings → General → VPN & Device Management +- Trust your developer certificate +- App will launch + +## Testing Checklist + +### Minimum to Test SDK Works: + +1. ✅ App builds and runs +2. ✅ SDK initializes (check console logs) +3. ✅ `isReady` returns `true` +4. ✅ Push token is retrieved +5. ✅ Permission can be requested + +### Full Testing: + +6. ✅ Send test notification from NotificationAPI dashboard +7. ✅ Notification received in foreground +8. ✅ Notification received in background +9. ✅ Tapping notification opens app + +## Quick Test Without Physical Device + +### iOS Simulator (macOS only): +- Can test most functionality +- **Cannot test push notifications** (simulator doesn't support APN) +- Good for: UI, initialization, API calls + +### Android Emulator: +- Can test everything including push notifications +- Full FCM support in emulator +- Good for: Complete testing + +## Troubleshooting + +### "Command not found: react-native" +```bash +npm install -g react-native-cli +``` + +### "No devices found" (iOS) +- Make sure iPhone is unlocked +- Trust the computer on iPhone +- Check USB cable +- In Xcode: Window → Devices and Simulators → Check if device appears + +### "Signing error" (iOS) +- Make sure you selected a Team in Xcode +- Free Apple ID works for development +- Bundle identifier might conflict - change it in Xcode + +### "Pod install failed" (iOS) +```bash +cd ios +pod deintegrate +pod install +cd .. +``` + +## Recommended Testing Order + +1. **Start with Android** (easier, works everywhere) + - Test all functionality + - Verify SDK works end-to-end + +2. **Then test iOS** (if you have Mac + iPhone) + - Verify iOS-specific code works + - Test APN integration + +## VSCode Setup + +You can absolutely use VSCode for editing! You'll just need: + +- **Terminal in VSCode** (or separate terminal) for running commands +- **Xcode** (for iOS) - only when building/running, not for editing +- **Android Studio** (for Android) - mainly for emulator, not required for editing + +VSCode extensions that help: +- React Native Tools +- ESLint +- TypeScript + +## Summary + +**For iOS:** +- ✅ VSCode for editing (yes!) +- ✅ Xcode for building/running (required) +- ✅ iPhone connected (for real push notifications) +- ✅ Apple ID (free account works) + +**For Android:** +- ✅ VSCode for editing (yes!) +- ✅ Android Studio for emulator (or use physical device) +- ✅ No special accounts needed + +**Easiest path:** Start with Android emulator to verify everything works, then test on iOS if needed. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..36896b8 --- /dev/null +++ b/README.md @@ -0,0 +1,407 @@ +# NotificationAPI React Native SDK + +A React Native SDK for integrating [NotificationAPI](https://notificationapi.com) push notifications into your mobile app. + +## Features + +- **Cross-platform push notifications**: Full support for Android (FCM) and iOS (APN) +- **One-call setup**: Simple `setup()` method handles initialization, user identification, and permission requests +- **Automatic token syncing**: Push tokens are automatically synced with NotificationAPI backend +- **Event handling**: Listen to notification received and opened events +- **Device information**: Automatic device information collection +- **Region support**: Support for US, EU, and CA regions + +## Installation + +```bash +npm install notificationapi-react-native-sdk +# or +yarn add notificationapi-react-native-sdk +``` + +### iOS Setup + +1. **Install CocoaPods dependencies** (if using CocoaPods): + ```bash + cd ios && pod install && cd .. + ``` + +2. **Enable Push Notifications capability** in Xcode: + - Open your project in Xcode + - Select your target + - Go to "Signing & Capabilities" + - Click "+ Capability" and add "Push Notifications" + +3. **Configure APN**: + - You need an Apple Developer account + - Create an APN key in Apple Developer Console + - Configure your NotificationAPI account with the APN key + +4. **Update AppDelegate** (if needed): + The SDK handles most of the setup, but you may need to ensure your `AppDelegate.m` or `AppDelegate.swift` properly handles APN token registration: + + ```swift + // Swift + import UserNotifications + + func application(_ application: UIApplication, + didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { + let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined() + UserDefaults.standard.set(token, forKey: "apns_token") + } + ``` + + ```objc + // Objective-C + - (void)application:(UIApplication *)application + didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { + NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet: + [NSCharacterSet characterSetWithCharactersInString:@"<>"]]; + token = [token stringByReplacingOccurrencesOfString:@" " withString:@""]; + [[NSUserDefaults standardUserDefaults] setObject:token forKey:@"apns_token"]; + } + ``` + +### Android Setup + +1. **Add Firebase to your project**: + - Create a Firebase project at [Firebase Console](https://console.firebase.google.com/) + - Add your Android app to the project + - Download `google-services.json` and place it in `android/app/` + +2. **Update `android/build.gradle`**: + ```gradle + buildscript { + dependencies { + classpath 'com.google.gms:google-services:4.3.15' + } + } + ``` + +3. **Update `android/app/build.gradle`**: + ```gradle + apply plugin: 'com.google.gms.google-services' + + dependencies { + implementation platform('com.google.firebase:firebase-bom:32.0.0') + implementation 'com.google.firebase:firebase-messaging' + } + ``` + +4. **Update `AndroidManifest.xml`** (usually in `android/app/src/main/AndroidManifest.xml`): + ```xml + + + ``` + +## Quick Start + +### 1. Setup (One Line!) + +```typescript +import NotificationAPI from 'notificationapi-react-native-sdk'; + +// That's it! This handles initialization, user identification, and permission requests +await NotificationAPI.setup({ + clientId: 'your_client_id_here', + userId: 'user123', + autoRequestPermission: true, // automatically request push permissions + region: 'us', // 'us' (default), 'eu', or 'ca' +}); +``` + +### 2. Listen to Notifications (Optional) + +```typescript +import { getEventEmitter, Events } from 'notificationapi-react-native-sdk'; + +const eventEmitter = getEventEmitter(); + +// Listen to notifications received while app is open +eventEmitter.addListener(Events.NOTIFICATION_RECEIVED, (notification) => { + console.log('Received notification:', notification.title); +}); + +// Listen to notifications that opened the app +eventEmitter.addListener(Events.NOTIFICATION_ON_CLICK, (notification) => { + console.log('App opened from notification:', notification.title); + // Handle deep linking or navigation +}); + +// Listen to push token updates +eventEmitter.addListener(Events.PUSH_TOKEN_RECEIVED, (event) => { + console.log('Push token received:', event.token); +}); +``` + +### 3. Check Status + +```typescript +// Check if SDK is ready +if (NotificationAPI.isReady) { + console.log('NotificationAPI is ready!'); +} + +// Get the current user +const userId = NotificationAPI.currentUser; + +// Get push token +const token = await NotificationAPI.getPushToken(); +``` + +## Complete Example + +```typescript +import React, { useEffect } from 'react'; +import { View, Button, Alert } from 'react-native'; +import NotificationAPI, { getEventEmitter, Events } from 'notificationapi-react-native-sdk'; + +function App() { + useEffect(() => { + // Setup NotificationAPI + NotificationAPI.setup({ + clientId: 'your_client_id', + userId: 'user123', + autoRequestPermission: true, + }).catch((error) => { + console.error('Failed to setup NotificationAPI:', error); + }); + + // Listen for notifications + const eventEmitter = getEventEmitter(); + + const receivedListener = eventEmitter.addListener( + Events.NOTIFICATION_RECEIVED, + (notification) => { + Alert.alert('New Notification', notification.title); + } + ); + + const clickListener = eventEmitter.addListener( + Events.NOTIFICATION_ON_CLICK, + (notification) => { + Alert.alert('Notification Clicked', notification.title); + // Handle navigation or deep linking + } + ); + + return () => { + receivedListener.remove(); + clickListener.remove(); + }; + }, []); + + const handleRequestPermission = async () => { + const granted = await NotificationAPI.requestPermission(); + Alert.alert( + 'Permission', + granted ? 'Permission granted' : 'Permission denied' + ); + }; + + return ( + +