DEV Community

Cover image for Fetching and Loading User Profiles Using Firebase in My eCommerce Project šŸ”šŸ—ƒ
Datravous Odds
Datravous Odds

Posted on

Fetching and Loading User Profiles Using Firebase in My eCommerce Project šŸ”šŸ—ƒ

This morning, I spent time refactoring and implementing a couple of key features in my eCommerce project. In this blog post, Iā€™ll walk you through the process of fetching and loading user profiles from Firebase, including the challenges I faced and how I solved them. Iā€™ll also share code snippets and explanations to help you understand the implementation.

Fetching User Profiles

After debugging some errors and adding error-checking logic to the handleTabs()function, I shifted my focus to fetching user data from Firebase for my eCommerce project. This project is designed to cater to sneaker and vintage sellers, offering essential features like trading, buying, listing, and selling. Additionally, it includes some unique services tailored to this niche market.

For the backend, Iā€™m using Firebase, while the frontend is built with basic web technologies like HTML/CSS, JavaScript, Node.js, and Express.js. Firebaseā€™s real-time database and authentication capabilities make it an excellent choice for managing user profiles and product data.

Firebase Structure Implementation

In my Firebase setup, Iā€™ve structured the database to store three main types of data:

  1. Products: Items listed by users.

  2. User Profiles: Information about each user.

  3. Users: Authentication and access control data.

Each user has specific rules governing access to their documents, which store individual user information. Think of these documents as files in a file cabinetā€”each file contains specific data, and only authorized users can access them.

Iā€™ll provide resource links at the end of this post for those who want to learn more about Firebase documents and collections. For now, letā€™s focus on the problem-solving aspect of fetching and loading user information.

What Are Documents in Firebase?

In Firebase, documents are used to store user information and other project-related data. They are essentially key-value pairs (similar to JavaScript objects) that follow your applicationā€™s logic.

Hereā€™s how it works:

  1. You start by creating a collection, which is a group of related data.

  2. Each collection has a unique ID and contains one or more documents.

  3. Documents can store fields (key-value pairs) and can even have nested collections within them.

For example, in my project, the userProfiles collection contains documents for each user, with fields like email, username, and ratings.

Firebase also allows you to set rules to control access to collections and documents. For instance, you can restrict access so that only authenticated users can read or write their own data.

Fetching User Profile Information: Implementation

Since this implementation doesnā€™t involve modifying the client-side UI yet, my goal was to establish a connection to Firebase and retrieve the user data object.

I decided to place the code in the auth.js file because the user profile information should only be fetched after the user is authenticated. Hereā€™s how I approached it:

Firebase Rules Setup:

I started by setting up Firebase rules to allow read and write access to the userProfiles collection. These rules ensure that only authenticated users can access their own data.

Hereā€™s the rule I implemented:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /userProfiles/{email} {
     allow read: if request.auth != null && request.auth.token.email == email;

    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Letā€™s break this down:

  • match /userProfiles/{email}: This rule applies to the userProfiles collection, where each document is identified by the userā€™s email.

  • allow read: A user can only read their document if they are authenticated (request.auth != null) and their email matches the documentā€™s email (request.auth.token.email == email).

Authentication Flow:

I chose to authenticate users via email verification. Once the userā€™s email is verified, they gain access to their profile data in the userProfiles collection. While some developers might use the documentā€™s unique ID for this purpose, I opted for email-based authentication to save time, as I had already implemented it in an earlier stage of the project.

Code implementation

After setting up the rules for the database, I was ready to write the code to retrieve the user data object from Firebase. I started by importing the necessary modules: db, doc, getDoc, and onAuthStateChanged.

db: Provides access to the Firebase database.

doc: Allows interaction with documents in collections.

getDoc: Retrieves documents from the database.

onAuthStateChanged: Tracks the userā€™s authentication status, which is crucial because we canā€™t fetch user data without authentication.

Most of these modules are imported from the /.firebase-client.js file.

Hereā€™s the code I wrote to fetch the user profile:

// Fetch user profile
const fetchUserProfile = async (user) => {
  try {
    const docRef = doc(db, "userProfiles", user.email);
    console.log("Fetching user profile for email:", user.email);
    const docSnap = await getDoc(docRef);

    // Fetching user profile
    if (docSnap.exists()) {
      const userData = {
        uid: user.uid,
        email: user.email,
        ...docSnap.data()
      };
      console.log("User profile found:", userData);
      return userData;
    } else {
      console.log("No profile document exists for user:", user.email);
      return null;
    }
  } catch (error) {
    console.error("Error fetching user profile:", error);
    throw error; // Throw error to be caught by caller
  }
};
Enter fullscreen mode Exit fullscreen mode

Explanation of the Code

  1. Asynchronous Function:
    The fetchUserProfile function is asynchronous because it interacts with Firebase, which involves network requests.

  2. Document Reference:
    The docRef variable creates a reference to the document in the userProfiles collection using the userā€™s email as the identifier.

  3. Fetching Data:
    The getDoc function retrieves the document snapshot (docSnap). If the document exists, the userā€™s data is combined with their uid and email into a userData object.

  4. Error Handling:
    If an error occurs, itā€™s logged using console.error to distinguish it from regular logs. The error is also thrown to ensure itā€™s handled by the caller.

Testing and Results

After implementing the code, I tested it to ensure it worked as expected. Hereā€™s a screenshot of the console output:

The logs confirm that the user profile was successfully fetched and displayed in the console.

Summary

I really enjoyed working on this feature, as I learned a lot about structuring Firebase databases, capturing user information (such as passwords, auth tokens, and emails), and implementing authentication rules. It was challenging at first, but resources like The Net Ninjaā€™s Firebase tutorial and the Firebase documentation were incredibly helpful.

If youā€™re working on a similar project, I hope this post provides some useful insights. Feel free to reach out if you have any questions or suggestions!

Top comments (0)