Building a production-ready video calling application with secure authentication, real-time notifications, and scalable SFU architecture.
| Version | Description | Status | Demo |
|---|---|---|---|
| v1.0 | Basic P2P WebRTC 1:1 Calls | β Complete | πΉ Watch Demo |
| v2.0 | Auth + Notifications + UI/UX | β Complete | πΉ Watch Demo |
| v3.0 | Mediasoup SFU Architecture | π§ In Progress | Coming Soon |
β Production-Ready Components:
- Google OAuth Authentication with JWT
- Push Notifications (Foreground/Background/Quit)
- Complete UI Flow (Login β Home β Profile β Join β Prepare)
- Developer Debug Panel
- Real-time Socket.io Signaling
π§ Active Development:
- Upgrading from P2P WebRTC to Mediasoup SFU
- LiveMeetScreen with enhanced video layout
- Group call support (20+ participants)
π Note: WebRTC P2P implementation (v1.0) is preserved in codebase (useWebRTC hook) but being upgraded to Mediasoup for better scalability.
- β Google Sign-In - Firebase OAuth integration
- β JWT Tokens - Dual token system (Access + Refresh)
- β Auto Refresh - Seamless token renewal without logout
- β Secure Storage - MMKV for encrypted local storage
- β Socket.io Auth - Authenticated real-time connections
- β Foreground - Custom UI notifications when app is active
- β Background - System notifications when app minimized
- β Quit State - Notifications when app is closed
- β Navigation - Deep linking from notifications
- β Login Screen - Google Sign-In with Firebase
- β Home Screen - Create or join meeting options
- β Profile Screen - User info, settings, logout
- β Join Screen - Enter meeting code
- β Prepare Screen - Preview camera/mic before joining
- β Developer Panel - Debug tool (tap version 5x to access)
- π§ LiveMeet Screen - Upgrading from P2P to Mediasoup SFU
- β v1.0: WebRTC P2P - Direct peer-to-peer connections (1:1 calls)
- π§ v3.0: Mediasoup SFU - Selective Forwarding Unit for scalable group calls
- β Signaling - Socket.io for offer/answer/ICE exchange
- β Media Controls - Camera toggle, mute/unmute, camera switch
- β Hidden Debug Panel - Access by tapping version 5 times
- β Token Inspector - View/copy JWT tokens with expiry
- β Socket Monitor - Real-time connection status
- β FCM Dashboard - Device token and registration info
First Implementation: Basic peer-to-peer video calling with WebRTC
Features shown:
- 1:1 video call connection
- Camera and audio controls
- WebRTC offer/answer signaling
- ICE candidate exchange
Current Implementation: Authentication, Notifications, and Complete UI
{
"core": {
"framework": "React Native 0.80.2",
"language": "JavaScript (ES6+)",
"cli": "React Native CLI (not Expo)"
},
"navigation": {
"@react-navigation/native": "^6.1.6",
"@react-navigation/native-stack": "^7.3.22"
},
"state": {
"zustand": "State management"
},
"storage": {
"react-native-mmkv": "High-performance encrypted storage"
},
"authentication": {
"@react-native-firebase/auth": "^22.4.0",
"@react-native-firebase/app": "^22.4.0"
},
"notifications": {
"@react-native-firebase/messaging": "^22.4.0",
"@notifee/react-native": "^9.1.8"
},
"realtime": {
"socket.io-client": "^4.x",
"react-native-webrtc": "P2P implementation (preserved)"
},
"ui": {
"react-native-gesture-handler": "^2.27.2",
"react-native-safe-area-context": "^5.5.2",
"react-native-screens": "^4.13.1"
}
}{
"runtime": "Node.js 18+",
"framework": "Express.js",
"database": "MongoDB + Mongoose",
"auth": "JWT + Firebase Admin SDK",
"realtime": "Socket.io ^4.6.x",
"video": "Mediasoup SFU (In Progress)",
"notifications": "Firebase Cloud Messaging"
}sequenceDiagram
participant User
participant App
participant Firebase
participant Backend
participant MMKV
User->>App: Click "Sign in with Google"
App->>Firebase: Google OAuth Request
Firebase-->>App: Firebase ID Token
App->>Backend: POST /auth/google { idToken }
Backend->>Firebase: Verify ID Token with FCM register
Backend-->>App: { accessToken, refreshToken }
App->>MMKV: Store Tokens (Encrypted)
App->>Backend: Connect Socket.io (with accessToken)
Backend-->>App: Authenticated Connection
App->>User: Navigate to Home Screen
Auto Token Refresh:
API Request β 401 Error β Axios Interceptor β Use Refresh Token β Get New Access Token β Retry Request β Success
- Node.js >= 18
- React Native CLI
- Android Studio or Xcode
- Firebase Project
# 1. Clone
git clone https://github.com/soham444101/Twalky-Frontend.git
cd Twalky-Frontend
# 2. Install dependencies
npm install
# 3. iOS Setup (Mac only)
cd ios && pod install && cd ..
# 4. Add Firebase config files
# - android/app/google-services.json
# - ios/GoogleService-Info.plist
# 5. Create .env file
echo "API_URL=http://your-ip:5000" > .env
echo "SOCKET_URL=http://your-ip:5000" >> .env
# 6. Run
npm start
npm run android # or npm run ios// src/services/storageService.js
import { MMKV } from "react-native-mmkv";
export const storage = new MMKV(
{
id: "user-storage",
encryptionKey: "secure-key-is-sasa"
}
)
export const mmkvstorage = {
setItem: (key, value) => {
storage.set(key, value);
},
getItem:(key)=>{
const value = storage.getString(key)
return value ?? null;
}
,
removeItem: (key) => {
storage.delete(key);
}
}// src/services/api.js
import axios from 'axios';
import { getToken, setToken } from './storageService';
const api = axios.create({ baseURL: API_URL });
this.apiClient.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config;
console.log("Interceptors error calls", error)
console.log("Interceptors error calls", error?.message)
console.log("This.isRefereshing", this.isRefreshing)
if (error.response?.status === 401 && !originalRequest._retry && !originalRequest.url.includes('/auth/logout')) {
if (this.isRefreshing) {
// Wait for refresh to complete
return new Promise((resolve, reject) => {
this.refreshSubscribers.push((token, error) => {
if (error) {
return reject(error);
}
originalRequest.headers.Authorization = `Bearer ${token}`;
resolve(this.apiClient(originalRequest));
});
});
}
originalRequest._retry = true;
this.isRefreshing = true;
try {
const newAccessToken = await this.refreshAccessToken();
// Notify all waiting requests
this.refreshSubscribers.forEach((callback) => callback(newAccessToken));
this.refreshSubscribers = [];
// Retry original request
originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
return this.apiClient(originalRequest);
} catch (refreshError) {
// Refresh failed - logout user
this.refreshSubscribers.forEach((callback) => callback(null, refreshError));
this.refreshSubscribers = [];
this.handleLogout();
return Promise.reject(refreshError);
} finally {
this.isRefreshing = false;
}
}
return Promise.reject(error);
}
);// App.js
import messaging from '@react-native-firebase/messaging';
import notifee from '@notifee/react-native';
// Foreground
/// this we are using when the user app open and after click notification what happens
const unsubscribeF = notifee.onForegroundEvent(({ type, detail }) => {
if (type === EventType.PRESS) {
const { Screen } = detail.notification?.data;
if (typeof (Screen) == "string" && Screen.length > 0) {
// console.log("Inside If");
navigate(Screen);
}
console.log("Notification tapped", detail.notification?.data);
console.log("Types", type);
}
});
// Background (index.js)
// This when app is in background and we perform some thing when click on notification
const unsubscribeAppdiedState = messaging().onNotificationOpenedApp(() => {
console.log("Notification opened from background:", remoteMessage);
const screen = remoteMessage.data?.Screen;
if (screen) navigate(screen);
})
// Quit state
const checkInitialNotification = async () => {
const remoteMessage = await messaging().getInitialNotification();
if (remoteMessage) {
console.log("App opened from killed state via notification:", remoteMessage);
const screen = remoteMessage.data?.Screen;
if (screen) navigate(screen);
}
};
checkInitialNotification();// src/hooks/useWebRTC.js
// This hook is still present but being upgraded to Mediasoup
const useWebRTC = () => {
const {
sessionId,
participants,
micOn,
videoOn,
addParticipant,
removeParticipant,
updateParticipant,
setStreamURL,
toggle,
clear,
} = meetStore();
const { user } = useUserStore();
// P2P implementation preserved for reference
// Being replaced with Mediasoup producer/consumer pattern
};- WebRTC peer-to-peer 1:1 calls
- Offer/answer/ICE exchange via Socket.io
- Camera and audio controls
- Basic UI for video calls
- Google OAuth with Firebase
- JWT token management (Access + Refresh)
- Auto token refresh mechanism
- Push notifications (FCM + Notifee)
- Complete UI flow (Login β Home β Join β Prepare)
- Profile screen with settings
- Developer debug panel
- MMKV storage
- Mediasoup server setup
- Room and router management
- Producer/consumer implementation
- LiveMeetScreen with SFU architecture
- Multiple participant video layout
- Group calls (15+ participants)
- Network quality indicators
- Call history with Firestore
- User presence system
- Screen sharing
- In-call text chat
- Recording functionality
- Virtual backgrounds
π€ ββ π€ (2 participants = 1 connection)
Perfect for 1:1 calls
β Problem: Doesn't scale
π€ ββ π€
β β
π€ ββ π€ (4 participants = 6 connections)
N*(N-1)/2 connections = High bandwidth
π€ β π‘ β π€
β
π€ β π‘ β π€
(4 participants = 4 connections to server)
β
Scalable to 50+ participants
β
Lower client bandwidth
β
Better quality control
| Issue | Status | Solution |
|---|---|---|
| Dark mode toggle works but UI not fully themed | Known | Planned for v2.1 |
| Token refresh edge case on poor network | Minor | Added retry logic |
| WebRTC P2P limited to 1:1 | By Design | Upgrading to Mediasoup SFU |
- Backend: Twalky-Mediasoup-Backend
- Frontend: You are here
Soham Aswar
Full Stack & React Native Developer
- π§ Email: sohamaswar@gmail.com
- π GitHub: @soham444101
- πΌ LinkedIn: Soham Aswar
- π Location: Pune, Maharashtra, India
β
Google OAuth authentication flow
β
JWT token management with auto-refresh
β
Push notifications (all app states)
β
Complete UI flow from login to prepare screen
β
Developer panel for debugging
β
Socket.io real-time signaling
π§ Upgrading video calling from P2P to Mediasoup SFU
π§ Enhanced LiveMeetScreen UI
π§ Group call support
πΉ v1.0: Basic P2P video calling
πΉ v2.0: Current implementation (auth, notifications, UI)
For questions, collaboration, or opportunities:
- π§ sohamaswar@gmail.com
- πΌ LinkedIn Profile
β If you found this project useful, give it a star on GitHub! πΌ Back to top
Last Updated: November 2025

