Learn how to create a real-time chat application using Flutter and Firebase, enabling users to send and receive messages instantly.
Welcome to an exciting project where you’ll learn to build a simple chat application using Flutter and Firebase. This app will allow users to send and receive messages in real-time, giving you a taste of how modern communication apps work. Let’s dive into the world of real-time messaging!
In this project, you’ll create a chat app that lets users type messages, send them, and see messages from others instantly. We’ll use Firebase as our backend to store and retrieve messages, ensuring they are synchronized across all devices in real-time.
Before we start coding, we need to set up Firebase, which will handle our app’s backend.
Create a Firebase Project:
Register Your Flutter App with Firebase:
AndroidManifest.xml
file.Download the google-services.json
File:
google-services.json
file and place it in the android/app
directory of your Flutter project.Add Firebase Dependencies:
Open your pubspec.yaml
file and add the following dependencies:
dependencies:
flutter:
sdk: flutter
firebase_core: latest_version
cloud_firestore: latest_version
Run flutter pub get
to install the dependencies.
Now that Firebase is set up, let’s initialize it in our Flutter app.
Open your main.dart
file and modify it as follows:
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(ChatApp());
}
class ChatApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Simple Chat App',
home: ChatHomePage(),
);
}
}
Let’s create a user-friendly interface for our chat app.
Create a new StatefulWidget
for the chat screen:
class ChatHomePage extends StatefulWidget {
@override
_ChatHomePageState createState() => _ChatHomePageState();
}
class _ChatHomePageState extends State<ChatHomePage> {
final TextEditingController messageController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Chat App'),
),
body: Column(
children: [
Expanded(
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('messages')
.orderBy('timestamp')
.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) return CircularProgressIndicator();
List<DocumentSnapshot> docs = snapshot.data!.docs;
List<Widget> messages = docs
.map((doc) => ListTile(
title: Text(doc['text']),
))
.toList();
return ListView(
children: messages,
);
},
),
),
Padding(
padding: EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: messageController,
decoration: InputDecoration(
hintText: 'Enter your message',
),
),
),
IconButton(
icon: Icon(Icons.send),
onPressed: sendMessage,
),
],
),
),
],
),
);
}
}
Let’s add functionality to send messages to Firestore.
Add the sendMessage
function in _ChatHomePageState
:
void sendMessage() {
if (messageController.text.isNotEmpty) {
FirebaseFirestore.instance.collection('messages').add({
'text': messageController.text,
'timestamp': FieldValue.serverTimestamp(),
});
messageController.clear();
}
}
We’ll use StreamBuilder
to listen for new messages in real-time.
StreamBuilder
in the build
method listens to the messages
collection and updates the UI whenever a new message is added.Differentiate between sent and received messages with styling.
ListTile
widget to change the alignment or color based on the message sender.Run the app on multiple devices or emulators to see real-time message synchronization.
Consider adding features like user authentication, timestamps on messages, or emojis to make the app more interactive.
Here’s the complete code for your simple chat app:
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(ChatApp());
}
class ChatApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Simple Chat App',
home: ChatHomePage(),
);
}
}
class ChatHomePage extends StatefulWidget {
@override
_ChatHomePageState createState() => _ChatHomePageState();
}
class _ChatHomePageState extends State<ChatHomePage> {
final TextEditingController messageController = TextEditingController();
void sendMessage() {
if (messageController.text.isNotEmpty) {
FirebaseFirestore.instance.collection('messages').add({
'text': messageController.text,
'timestamp': FieldValue.serverTimestamp(),
});
messageController.clear();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Chat App'),
),
body: Column(
children: [
Expanded(
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('messages')
.orderBy('timestamp')
.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) return CircularProgressIndicator();
List<DocumentSnapshot> docs = snapshot.data!.docs;
List<Widget> messages = docs
.map((doc) => ListTile(
title: Text(doc['text']),
))
.toList();
return ListView(
children: messages,
);
},
),
),
Padding(
padding: EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: messageController,
decoration: InputDecoration(
hintText: 'Enter your message',
),
),
),
IconButton(
icon: Icon(Icons.send),
onPressed: sendMessage,
),
],
),
),
],
),
);
}
}
Now that you’ve built your chat app, try these exercises:
To help you visualize the app, here are some screenshots:
graph TD; A[User 1] -->|Sends Message| B(Firebase Firestore); B -->|Stores Message| C[User 2]; C -->|Receives Message| A;
This diagram illustrates the flow of messages between users and Firebase Firestore.
Congratulations on building your first real-time chat app! This project has introduced you to the basics of using Firebase with Flutter, and there’s so much more you can explore. Keep experimenting and enhancing your app with new features and ideas. Happy coding!