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:
Products: Items listed by users.
User Profiles: Information about each user.
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:
You start by creating a collection, which is a group of related data.
Each collection has a unique ID and contains one or more documents.
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;
}
}
}
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
}
};
Explanation of the Code
Asynchronous Function:
ThefetchUserProfile
function is asynchronous because it interacts with Firebase, which involves network requests.Document Reference:
ThedocRef
variable creates a reference to the document in theuserProfiles
collection using the userās email as the identifier.Fetching Data:
ThegetDoc
function retrieves the document snapshot (docSnap
). If the document exists, the userās data is combined with theiruid
andemail
into auserData
object.Error Handling:
If an error occurs, itās logged usingconsole.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:
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)