StacksGather
Implementing a Real-Time Chat Feature in React Native
Software development

Implementing a Real-Time Chat Feature in React Native

Muhammad

Muhammad Aamir Yameen

April 21, 2025

165 mint

Real-time chat is a critical feature for modern mobile applications, enabling seamless communication between users. This article explores how to build a real-time chat feature in a React Native application using Firebase as the backend for real-time messaging.

Prerequisites

  • Basic knowledge of React Native and JavaScript.
  • Node.js and npm installed.
  • A Firebase account for backend services.
  • React Native CLI or Expo CLI set up.

Step 1: Setting Up the React Native Project

First, create a new React Native project if you don’t already have one:

npx react-native init ChatApp
cd ChatApp
Install the necessary dependencies for Firebase and navigation:
npm install @react-navigation/native @react-navigation/stack react-native-gifted-chat firebase
npx pod-install ios

Step 2: Configuring Firebase

  1. Go to the Firebase Console and create a new project.
  2. Add an app to your Firebase project (select iOS or Android) and follow the setup instructions to download the configuration file (GoogleService-Info.plist for iOS or google-services.json for Android).
  3. Place the configuration file in the appropriate directory of your React Native project.
  4. Enable Firestore in the Firebase Console under "Build > Firestore Database" and create a new database.
In your project, initialize Firebase by creating a firebaseConfig.js file:

import firebase from 'firebase/app';
import 'firebase/firestore';
import 'firebase/auth';
const firebaseConfig = {
apiKey: 'YOUR_API_KEY',
authDomain: 'YOUR_AUTH_DOMAIN',
projectId: 'YOUR_PROJECT_ID',
storageBucket: 'YOUR_STORAGE_BUCKET',
messagingSenderId: 'YOUR_MESSAGING_SENDER_ID',
appId: 'YOUR_APP_ID',
};
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
}
export const db = firebase.firestore();
export const auth = firebase.auth();
export default firebase;
Replace the placeholders with your Firebase project’s configuration details.

Step 3: Setting Up Navigation

Set up navigation to switch between a login screen and the chat screen. Create a navigation folder and add a AppNavigator.js file:

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import LoginScreen from '../screens/LoginScreen';
import ChatScreen from '../screens/ChatScreen';
const Stack = createStackNavigator();
const AppNavigator = () => (
<NavigationContainer>
<Stack.Navigator initialRouteName="Login">
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Chat" component={ChatScreen} />
</Stack.Navigator>
</NavigationContainer>
);
export default AppNavigator;
Update App.js to use the navigator:
import React from 'react';
import AppNavigator from './navigation/AppNavigator';
export default function App() {
return <AppNavigator />;
}

Step 4: Creating the Login Screen
Create a screens folder and add LoginScreen.js to handle user authentication:
import React, { useState } from 'react';
import { View, TextInput, Button, StyleSheet } from 'react-native';
import { auth } from '../firebaseConfig';
const LoginScreen = ({ navigation }) => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleLogin = async () => {
try {
await auth.signInWithEmailAndPassword(email, password);
navigation.navigate('Chat');
} catch (error) {
console.error(error);
}
};
const handleSignUp = async () => {
try {
await auth.createUserWithEmailAndPassword(email, password);
navigation.navigate('Chat');
} catch (error) {
console.error(error);
}
};
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder="Email"
value={email}
onChangeText={setEmail}
/>
<TextInput
style={styles.input}
placeholder="Password"
value={password}
onChangeText={setPassword}
secureTextEntry
/>
<Button title="Login" onPress={handleLogin} />
<Button title="Sign Up" onPress={handleSignUp} />
</View>
);
};
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', padding: 16 },
input: { borderWidth: 1, padding: 8, marginBottom: 16 },
});
export default LoginScreen;

Step 5: Building the Chat Screen

Use the react-native-gifted-chat library to create a polished chat UI. Create ChatScreen.js in the screens folder:
import React, { useState, useEffect, useCallback } from 'react';
import { GiftedChat } from 'react-native-gifted-chat';
import { db, auth } from '../firebaseConfig';
const ChatScreen = () => {
const [messages, setMessages] = useState([]);
useEffect(() => {
const unsubscribe = db
.collection('messages')
.orderBy('createdAt', 'desc')
.onSnapshot((snapshot) => {
const messageList = snapshot.docs.map((doc) => ({
_id: doc.id,
text: doc.data().text,
createdAt: doc.data().createdAt.toDate(),
user: doc.data().user,
}));
setMessages(messageList);
});
return () => unsubscribe();
}, []);
const onSend = useCallback((newMessages = []) => {
const message = newMessages[0];
db.collection('messages').add({
text: message.text,
createdAt: new Date(),
user: {
_id: auth.currentUser.uid,
name: auth.currentUser.email,
},
});
}, []);
return (
<GiftedChat
messages={messages}
onSend={(newMessages) => onSend(newMessages)}
user={{
_id: auth.currentUser.uid,
name: auth.currentUser.email,
}}
/>
);
};
export default ChatScreen;

Step 6: Firestore Security Rules

To ensure only authenticated users can read and write messages, update your Firestore security rules in the Firebase Console:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /messages/{messageId} {
allow read, write: if request.auth != null;
}
}
}

Step 7: Running the App

Start the Metro bundler and run the app:
npx react-native run-android
# or
npx react-native run-ios

Additional Considerations

  • Performance: For large chat applications, consider paginating messages to reduce load times.
  • Security: Ensure all sensitive data is encrypted and validate user inputs to prevent injection attacks.
  • UI Customization: Customize the GiftedChat component’s appearance using its props to match your app’s design.
  • Push Notifications: Integrate Firebase Cloud Messaging (FCM) to notify users of new messages when the app is in the background.

Conclusion

By leveraging Firebase Firestore and react-native-gifted-chat, you can quickly implement a robust real-time chat feature in your React Native application. This setup provides a scalable foundation that you can extend with additional features like media sharing, typing indicators, or group chats.