Mobile App Deployment Guide
Deploy your FSS mobile application built with Expo and React Native to app stores.
Prerequisites
- Node.js 18+
- Expo CLI (
npm install -g expo-cli) - Expo Developer account (free at expo.dev)
- Apple Developer account (for iOS)
- Google Play Developer account (for Android)
Build Configuration
Environment Variables
Create .env file for your mobile app:
# API Configuration
NEXT_PUBLIC_API_URL=https://api.yourdomain.com
NEXT_PUBLIC_APP_URL=https://yourdomain.com
# Feature Flags
NEXT_PUBLIC_ENABLE_PUSH_NOTIFICATIONS=true
NEXT_PUBLIC_ENABLE_ANALYTICS=true
# Analytics (optional)
NEXT_PUBLIC_GA_TRACKING_ID=UA-XXXXXXXX-X
NEXT_PUBLIC_FIREBASE_API_KEY=your-api-key
app.json Configuration
Update app.json with your app details:
{
"expo": {
"name": "FSS App",
"slug": "fss-app",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "automatic",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.yourcompany.fssapp",
"buildNumber": "1",
"infoPlist": {
"NSCameraUsageDescription": "This app uses the camera for QR code scanning.",
"NSPhotoLibraryUsageDescription": "This app accesses your photos for profile images."
}
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
},
"package": "com.yourcompany.fssapp",
"versionCode": 1,
"permissions": ["CAMERA", "READ_EXTERNAL_STORAGE"]
},
"plugins": [
[
"expo-camera",
{
"cameraPermission": "Allow FSS to access your camera for QR code scanning."
}
]
]
}
}
Building for Production
Development Build
# Start development server
npx expo start
# Run on iOS simulator
npx expo run:ios
# Run on Android emulator
npx expo run:android
Production Build (Expo Application Services)
# Install EAS CLI
npm install -g eas-cli
# Login to Expo
eas login
# Configure build
eas build:configure
# Build for iOS
eas build --platform ios --profile production
# Build for Android
eas build --platform android --profile production
EAS Build Profile
Create eas.json:
{
"cli": {
"version": ">= 3.0.0"
},
"build": {
"development": {
"developmentClient": true,
"distribution": "internal",
"android": {
"buildType": "apk"
},
"ios": {
"simulator": true
}
},
"preview": {
"distribution": "internal",
"android": {
"buildType": "apk"
}
},
"production": {
"android": {
"buildType": "app-bundle"
},
"ios": {
"buildType": "release"
}
}
},
"submit": {
"production": {}
}
}
App Store Submission
iOS App Store
- Build the app (see above)
- Submit to App Store
eas submit --platform ios
-
Required Information:
- App name and description
- Screenshots (various sizes)
- Privacy policy URL
- App Store category
- Pricing (free or paid)
-
After Submission:
- Review typically takes 24-48 hours
- Respond to any App Store Review guidelines issues
Google Play Store
- Build the app (see above)
- Submit to Play Store
eas submit --platform android
-
Required Information:
- App name and description
- Screenshots and feature graphic
- Privacy policy URL
- Content rating questionnaire
- Target audience
-
After Submission:
- Review typically takes 1-3 days
- App goes to production after approval
Push Notifications
Setup FCM for Android
- Go to Firebase Console
- Create new project or select existing
- Add Android app with your package name
- Download
google-services.jsonand place in project root - Enable Cloud Messaging API in Google Cloud Console
Setup APNs for iOS
- Go to Apple Developer Console
- Create Push Notifications service for your app ID
- Create and download SSL certificate
- Convert certificate to PEM format:
# Export certificate from Keychain
openssl pkcs12 -in Certificates.p12 -out certificate.pem -nodes -clcerts
- Upload certificate to Expo:
eas credentials:manager
Push Notification Code
// notifications.ts
import * as Device from 'expo-device';
import * as Notifications from 'expo-notifications';
export async function registerForPushNotificationsAsync() {
if (!Device.isDevice) {
return null;
}
const { status: existingStatus } = await Notifications.getPermissionsAsync();
let finalStatus = existingStatus;
if (existingStatus !== 'granted') {
const { status } = await Notifications.requestPermissionsAsync();
finalStatus = status;
}
if (finalStatus !== 'granted') {
console.log('Failed to get push token for push notification!');
return;
}
const token = await Notifications.getExpoPushTokenAsync({
projectId: 'your-project-id',
});
return token.data;
}
Over-the-Air Updates (OTA)
FSS supports Expo OTA updates for instant app updates:
# Publish update
expo publish
# Publish with specific channel
expo publish --channel production
Configure Channels
{
"expo": {
"updates": {
"url": "https://u.expo.dev/your-project-id",
"enabled": true
},
"runtimeVersion": {
"policy": "appVersion"
}
}
}
Security Considerations
Secure Storage
import * as SecureStore from 'expo-secure-store';
// Store sensitive data
await SecureStore.setItemAsync('authToken', token);
// Retrieve data
const token = await SecureStore.getItemAsync('authToken');
// Delete data
await SecureStore.deleteItemAsync('authToken');
Certificate Pinning
import { AuthSession } from 'expo-auth';
const config = {
issuer: 'https://your-domain.com',
clientId: 'your-client-id',
scopes: ['openid', 'profile', 'email'],
redirectUri: AuthSession.makeRedirectUri('your-app'),
usePKCE: true,
};
Monitoring and Analytics
Crash Reporting (Sentry)
npm install @sentry/react-native
import * as Sentry from '@sentry/react-native';
Sentry.init({
dsn: 'https://[email protected]/xxx',
tracesSampleRate: 1.0,
});
const App = () => {
return <Sentry.Hub wrapperComponent={MainApp} />;
};
Analytics
import { useAnalytics } from '@react-native-firebase/analytics';
const analytics = useAnalytics();
const logEvent = async () => {
await analytics.logEvent('purchase', {
item_id: 'product_123',
value: 99.99,
currency: 'USD',
});
};
Troubleshooting
Build Errors
# Clear cache and try again
expo start -c
# Reset iOS simulator
xcrun simctl erase all
# Reset Android emulator
adb emu kill && emulator -avd <avd_name>
App Crashes
- Check Expo Dev Tools for logs
- Enable Crashlytics for production crash reports
- Test on physical devices, not just simulators
Related Documentation
- Docker Deployment - Backend deployment
- Security Best Practices - Mobile security
- Environment Variables - Configuration