Skip to content

soham444101/Twalky-Frontend

Repository files navigation

πŸŽ₯ Twalky - Real-Time Video Calling Platform

React Native Firebase Socket.io WebRTC

Building a production-ready video calling application with secure authentication, real-time notifications, and scalable SFU architecture.


πŸ“Š Project Evolution & Current Status

Version History

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

Current Status (v2.0)

βœ… 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.


✨ Features (v2.0 - Current)

πŸ” Authentication System

  • βœ… 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

πŸ”” Push Notifications (FCM + Notifee)

  • βœ… 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

πŸ“± User Interface (Complete Flow)

  • βœ… 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

πŸŽ₯ Video Calling Evolution

  • βœ… 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

πŸ”§ Developer Tools

  • βœ… 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

🎬 Demo Videos

v1.0 Demo - Basic WebRTC P2P

First Implementation: Basic peer-to-peer video calling with WebRTC

Video: signal-2025-11-05-115616

Features shown:

  • 1:1 video call connection
  • Camera and audio controls
  • WebRTC offer/answer signaling
  • ICE candidate exchange

v2.0 Demo - Current Features

Current Implementation: Authentication, Notifications, and Complete UI

Video:


πŸ› οΈ Tech Stack

Frontend

{
  "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"
  }
}

Backend

{
  "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"
}

πŸ” Authentication Flow

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
Loading

Auto Token Refresh:

API Request β†’ 401 Error β†’ Axios Interceptor β†’ Use Refresh Token β†’ Get New Access Token β†’ Retry Request β†’ Success

πŸš€ Quick Start

Prerequisites

  • Node.js >= 18
  • React Native CLI
  • Android Studio or Xcode
  • Firebase Project

Installation

# 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

πŸ”§ Key Implementation Details

1. MMKV Storage

// 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);
    }

}

2. Auto Token Refresh (Axios Interceptor)

// 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);
      }
    );

3. Push Notifications (All States)

// 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();

4. WebRTC Hook (v1.0 - Preserved)

// 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
};

πŸ“Š Development Roadmap

βœ… v1.0 - Basic WebRTC P2P (Complete)

  • WebRTC peer-to-peer 1:1 calls
  • Offer/answer/ICE exchange via Socket.io
  • Camera and audio controls
  • Basic UI for video calls

βœ… v2.0 - Authentication & Notifications (Complete)

  • 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

🚧 v3.0 - Mediasoup SFU (In Progress - 60% Complete)

  • 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

πŸ“‹ v3.5 - Enhanced Features (Planned)

  • Call history with Firestore
  • User presence system
  • Screen sharing
  • In-call text chat
  • Recording functionality
  • Virtual backgrounds

🎯 Why Upgrading from P2P to SFU?

WebRTC P2P (v1.0)

πŸ‘€ ←→ πŸ‘€  (2 participants = 1 connection)
Perfect for 1:1 calls

❌ Problem: Doesn't scale
πŸ‘€ ←→ πŸ‘€
 ↕     ↕
πŸ‘€ ←→ πŸ‘€  (4 participants = 6 connections)
N*(N-1)/2 connections = High bandwidth

Mediasoup SFU (v3.0)

πŸ‘€ β†’ πŸ“‘ β†’ πŸ‘€
     ↕
πŸ‘€ ← πŸ“‘ ← πŸ‘€
(4 participants = 4 connections to server)

βœ… Scalable to 50+ participants
βœ… Lower client bandwidth
βœ… Better quality control

πŸ› Known Issues & Solutions

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

πŸ”— Related Repositories


πŸ‘¨β€πŸ’» Author

Soham Aswar
Full Stack & React Native Developer


🎯 For Interviewers

What's Working Right Now:

βœ… 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

What's In Progress:

🚧 Upgrading video calling from P2P to Mediasoup SFU
🚧 Enhanced LiveMeetScreen UI
🚧 Group call support

Demo Available:

πŸ“Ή v1.0: Basic P2P video calling
πŸ“Ή v2.0: Current implementation (auth, notifications, UI)


πŸ“ž Contact

For questions, collaboration, or opportunities:


⭐ Show Your Support

⭐ If you found this project useful, give it a star on GitHub! πŸ”Ό Back to top


Last Updated: November 2025

About

Twalky : Real-time Meet app with React Native , WebRTC & Socket.io

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published