Day 3: Implementing Real-Time Messaging with Firebase Firestore


Today, you’ll integrate Firebase Firestore to enable real-time messaging in your chat app. Messages will be sent, saved to Firestore, and dynamically displayed in the chat interface without requiring a manual refresh.

What You Will Do Today:

  1. Set up a Firestore collection for messages.
  2. Save new messages to Firestore.
  3. Retrieve and display messages in real-time.

Step 1: Set Up Firestore for Messages

  1. Open your Firebase Console.
  2. Go to Firestore Database > Data.
  3. Create a collection called messages with the following structure for each document:
    • text: String (the content of the message).
    • userId: String (the sender’s user ID).
    • userName: String (the sender’s name or email).
    • createdAt: Timestamp (the time the message was sent).

Step 2: Update ChatScreen to Send Messages to Firestore

  1. Modify ChatScreen.js to send messages to Firestore.
// screens/ChatScreen.js
import React, { useState, useEffect } from 'react';
import { View, TextInput, Button, FlatList, StyleSheet, Text } from 'react-native';
import firestore from '@react-native-firebase/firestore';
import auth from '@react-native-firebase/auth';

function ChatScreen() {
  const [messages, setMessages] = useState([]);
  const [text, setText] = useState('');

  // Fetch messages from Firestore
  useEffect(() => {
    const unsubscribe = firestore()
      .collection('messages')
      .orderBy('createdAt', 'desc')
      .onSnapshot((querySnapshot) => {
        const fetchedMessages = querySnapshot.docs.map((doc) => ({
          id: doc.id,
          ...doc.data(),
        }));
        setMessages(fetchedMessages);
      });

    return unsubscribe; // Clean up listener on unmount
  }, []);

  const sendMessage = async () => {
    if (text.trim()) {
      const { uid, email } = auth().currentUser;

      try {
        await firestore().collection('messages').add({
          text,
          userId: uid,
          userName: email,
          createdAt: firestore.FieldValue.serverTimestamp(),
        });
        setText(''); // Clear input after sending
      } catch (error) {
        console.error('Error sending message:', error);
      }
    }
  };

  const renderMessage = ({ item }) => (
    <View style={styles.messageContainer}>
      <Text style={styles.messageUser}>{item.userName}</Text>
      <Text style={styles.messageText}>{item.text}</Text>
      <Text style={styles.messageTimestamp}>
        {item.createdAt?.toDate().toLocaleTimeString()}
      </Text>
    </View>
  );

  return (
    <View style={styles.container}>
      <FlatList
        data={messages}
        renderItem={renderMessage}
        keyExtractor={(item) => item.id}
        inverted // Display newest messages at the top
      />
      <View style={styles.inputContainer}>
        <TextInput
          style={styles.input}
          placeholder="Type a message..."
          value={text}
          onChangeText={setText}
        />
        <Button title="Send" onPress={sendMessage} />
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f5f5f5',
  },
  messageContainer: {
    marginVertical: 8,
    padding: 10,
    backgroundColor: '#e1ffc7',
    borderRadius: 8,
    alignSelf: 'flex-start',
  },
  messageUser: {
    fontWeight: 'bold',
    marginBottom: 4,
  },
  messageText: {
    fontSize: 16,
  },
  messageTimestamp: {
    fontSize: 12,
    color: '#888',
    marginTop: 4,
    alignSelf: 'flex-end',
  },
  inputContainer: {
    flexDirection: 'row',
    padding: 10,
    borderTopWidth: 1,
    borderTopColor: '#ddd',
    backgroundColor: '#fff',
  },
  input: {
    flex: 1,
    borderWidth: 1,
    borderColor: '#ddd',
    borderRadius: 8,
    paddingHorizontal: 10,
    marginRight: 10,
  },
});

export default ChatScreen;

Step 3: Test Real-Time Messaging

  1. Run the app:
    • For Android: npx react-native run-android
    • For iOS: npx react-native run-ios
  2. Log in with a Firebase User:
    • Ensure you’re authenticated as a Firebase user (anonymous or email-based).
  3. Send a Message:
    • Type a message in the input box and press Send.
    • The message will be saved to Firestore and displayed in the chat interface.
  4. Test on Multiple Devices:
    • Run the app on two devices or simulators.
    • Messages sent from one device should appear in real-time on the other.
See also  Intel HAXM Troubleshooting: Conquering Emulator Lag with Command-Line Precision

Step 4: Verify Firestore Data

  1. Open the Firebase Console.
  2. Go to Firestore Database > messages.
  3. Verify that messages are being saved with the correct text, userId, userName, and createdAt fields.

Summary

Today, you integrated Firebase Firestore for real-time messaging. Messages are now sent, saved, and dynamically displayed in the chat app. This completes the core functionality of a real-time chat interface.

Tomorrow, you’ll add authentication for users to log in, allowing personalized messaging.


Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.