Mobile Developer for Real-Time Communication App

Job ID: 39298737

Budget: ₹1,500 – ₹12,500 INR

I am giving a code can plzz check it
name: flutter_webrtc_chat_app

description: A cross-platform app with video conferencing, chat, and file sharing using Flutter, WebRTC, and Firebase.

publish_to: 'none'

version: 1.0.0+1

environment:
sdk: '>=2.17.0 <3.0.0'

dependencies:
flutter:
sdk: flutter
flutter_webrtc: ^0.9.36
firebase_core: ^2.0.0
cloud_firestore: ^4.0.0
firebase_auth: ^5.0.0
firebase_storage: ^11.0.0
file_picker: ^6.0.0

flutter:
uses-material-design: true

# lib/main.dart
import 'package:flutter/material.dart';
import 'screens/chat_screen.dart';
import 'screens/call_screen.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter WebRTC Chat',
theme: ThemeData(primarySwatch: Colors.blue),
home: HomeScreen(),
);
}
}

class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Flutter WebRTC Chat')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
child: Text('Join Call'),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => CallScreen()),
),
),
ElevatedButton(
child: Text('Open Chat'),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => ChatScreen()),
),
),
],
),
),
);
}
}

// lib/utils/renderer_handler.dart
import 'package:flutter_webrtc/flutter_webrtc.dart';

class VideoRenderersHandler {
final RTCVideoRenderer localRenderer = RTCVideoRenderer();
final RTCVideoRenderer remoteRenderer = RTCVideoRenderer();

Future<void> initialize() async {
await localRenderer.initialize();
await remoteRenderer.initialize();
}

void dispose() {
localRenderer.dispose();
remoteRenderer.dispose();
}
}

// lib/screens/call_screen.dart
import 'package:flutter/material.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import '../utils/renderer_handler.dart';

class CallScreen extends StatefulWidget {
@override
_CallScreenState createState() => _CallScreenState();
}

class _CallScreenState extends State<CallScreen> {
final renderers = VideoRenderersHandler();

@override
void initState() {
super.initState();
initRenderers();
startCall();
}

Future<void> initRenderers() async {
await renderers.initialize();
}

Future<void> startCall() async {
final mediaConstraints = {
'audio': true,
'video': {'facingMode': 'user'}
};
MediaStream stream = await navigator.mediaDevices.getUserMedia(mediaConstraints);
renderers.localRenderer.srcObject = stream;

// Example placeholder for signaling logic using Firebase Firestore
// You should implement signaling via WebSocket, Firebase Realtime Database, or Firestore for production
// This would include exchanging offer, answer, and ICE candidates between peers
}

@override
void dispose() {
renderers.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
RTCVideoView(renderers.remoteRenderer),
Positioned(
right: 20,
top: 40,
child: Container(
width: 120,
height: 160,
child: RTCVideoView(renderers.localRenderer, mirror: true),
),
),
],
),
);
}
}

// lib/screens/chat_screen.dart
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:file_picker/file_picker.dart';

class ChatScreen extends StatefulWidget {
@override
_ChatScreenState createState() => _ChatScreenState();
}

class _ChatScreenState extends State<ChatScreen> {
final TextEditingController _controller = TextEditingController();

void sendMessage() {
FirebaseFirestore.instance.collection('messages').add({
'text': _controller.text,
'timestamp': FieldValue.serverTimestamp(),
});
_controller.clear();
}

Future<void> uploadFile() async {
final result = await FilePicker.platform.pickFiles();
if (result != null) {
final fileBytes = result.files.first.bytes;
final fileName = result.files.first.name;

try {
await FirebaseStorage.instance.ref('uploads/$fileName').putData(fileBytes!);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('File uploaded successfully')));
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Upload failed: \$e')));
}
}
}

@override
void dispose() {
_controller.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Chat'),
actions: [
IconButton(
icon: Icon(Icons.attach_file),
onPressed: uploadFile,
)
],
),
body: Column(
children: [
Expanded(
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('messages')
.orderBy('timestamp')
.snapshots(),
builder: (ctx, snapshot) {
if (!snapshot.hasData) return Center(child: CircularProgressIndicator());
final docs = snapshot.data!.docs;
return ListView.builder(
itemCount: docs.length,
itemBuilder: (ctx, i) => ListTile(
title: Text(docs[i]['text'] ?? ''),
),
);
},
),
),
Padding(
padding: EdgeInsets.all(8),
child: Row(
children: [
Expanded(child: TextField(controller: _controller)),
IconButton(icon: Icon(Icons.send), onPressed: sendMessage),
],
),
)
],
),
);
}
}
Related categories: PHP Mobile App Development iPhone Android PhoneGap