Fetching User Data from Firebase Firestore - abhiram-shaji/Langroove GitHub Wiki

Prerequisites:

  • Firebase Firestore and Firebase Authentication must be configured and working.
  • Firestore must have a collection named users where user data is stored.

Fetching User Data Example

Here’s a step-by-step breakdown of how user data, including avatars, is fetched from Firestore using Firebase's SDK in a React Native app.

1. Fetching a Single User's Data

To fetch a single user’s data, you use Firestore’s getDoc() method. Below is an example of fetching user data by their user ID (UID).

import { doc, getDoc } from "firebase/firestore";
import { db } from "./firebase"; // Assuming you have firebase setup in a file

const fetchUserData = async (userId: string) => {
  try {
    const userDocRef = doc(db, "users", userId); // Reference to the user document
    const userDoc = await getDoc(userDocRef); // Fetch the document
    
    if (userDoc.exists()) {
      const userData = userDoc.data(); // Extract user data
      console.log("User Data:", userData);
      return userData; // Return or use the fetched data
    } else {
      console.log("No such user document!");
      return null; // Handle case where user document doesn't exist
    }
  } catch (error) {
    console.error("Error fetching user data:", error);
    return null; // Handle any errors
  }
};

2. Fetching Multiple Users’ Avatars in a Chat

When building a chat system, you might want to fetch avatars for multiple users in a chat. This can be done by querying the Firestore users collection for each unique sender in the chat. Here’s an example:

import { doc, getDoc } from "firebase/firestore";
import { db } from "./firebase"; // Assuming you have firebase setup

const fetchAvatars = async (senderIds: string[]) => {
  const avatars: { [key: string]: string } = {};

  await Promise.all(
    senderIds.map(async (senderId) => {
      try {
        const userDocRef = doc(db, "users", senderId);
        const userDoc = await getDoc(userDocRef);

        if (userDoc.exists()) {
          const userData = userDoc.data();
          avatars[senderId] = userData?.avatar || "https://default-avatar.png"; // Use avatar if available, otherwise default
        } else {
          console.log("No user found for ID:", senderId);
          avatars[senderId] = "https://default-avatar.png"; // Default avatar if user doc doesn't exist
        }
      } catch (error) {
        console.error("Error fetching avatar for user:", senderId, error);
        avatars[senderId] = "https://default-avatar.png"; // Default avatar on error
      }
    })
  );

  return avatars; // Return the avatar object
};

3. Real-Time Fetching of Messages with User Data

For a chat application, you can listen for real-time updates to messages and fetch the corresponding user data (such as avatars) as needed.

import { collection, query, orderBy, onSnapshot } from "firebase/firestore";
import { db } from "./firebase"; // Your firebase setup

const fetchChatMessages = (chatId: string, currentUserId: string) => {
  const chatRef = collection(db, "chats", chatId, "messages");
  const q = query(chatRef, orderBy("createdAt"));

  const unsubscribe = onSnapshot(q, (snapshot) => {
    const messages = snapshot.docs.map((doc) => {
      const data = doc.data();
      return {
        id: doc.id,
        text: data.text,
        senderId: data.sender,
        senderType: data.sender === currentUserId ? "me" : "other",
        createdAt: data.createdAt,
      };
    });

    console.log("Fetched Messages:", messages);
    return messages;
  });

  return unsubscribe; // To stop listening when needed
};