Today, you’ll add functionality to your e-commerce app for product reviews and ratings. Users will be able to leave reviews for purchased products, and these reviews will be displayed on the product detail page. This feature enhances user engagement and helps other customers make informed decisions.
What You Will Do Today:
- Create a Firestore collection for storing reviews.
- Add a review submission form on the product detail page.
- Display reviews and ratings on the product detail page.
Step 1: Set Up Firestore Collection for Reviews
- Open your Firebase Console and go to Firestore Database.
- Create a new collection called
reviews
with the following structure for documents:
- productId: String (the ID of the product being reviewed).
- userId: String (the ID of the user leaving the review).
- userName: String (the user’s name or email).
- rating: Number (the user’s rating for the product, e.g., 4.5).
- review: String (the user’s review text).
- createdAt: Timestamp (when the review was created).
Step 2: Add a Review Form on the Product Detail Page
- Update
ProductDetail.js
to include a form for submitting reviews:
import React, { useState, useEffect } from 'react';
import { View, Text, TextInput, Button, StyleSheet, FlatList, Alert } from 'react-native';
import firestore from '@react-native-firebase/firestore';
import auth from '@react-native-firebase/auth';
function ProductDetail({ route }) {
const { productId } = route.params;
const [product, setProduct] = useState(null);
const [reviews, setReviews] = useState([]);
const [rating, setRating] = useState('');
const [reviewText, setReviewText] = useState('');
useEffect(() => {
// Fetch product details
const fetchProduct = async () => {
const doc = await firestore().collection('products').doc(productId).get();
if (doc.exists) setProduct({ id: doc.id, ...doc.data() });
};
// Fetch reviews for the product
const fetchReviews = async () => {
const snapshot = await firestore()
.collection('reviews')
.where('productId', '==', productId)
.orderBy('createdAt', 'desc')
.get();
const reviewList = snapshot.docs.map(doc => ({
id: doc.id,
...doc.data(),
}));
setReviews(reviewList);
};
fetchProduct();
fetchReviews();
}, [productId]);
const submitReview = async () => {
if (!rating || !reviewText) {
Alert.alert('Error', 'Please provide both a rating and a review.');
return;
}
const newReview = {
productId,
userId: auth().currentUser.uid,
userName: auth().currentUser.email,
rating: parseFloat(rating),
review: reviewText,
createdAt: firestore.FieldValue.serverTimestamp(),
};
try {
await firestore().collection('reviews').add(newReview);
Alert.alert('Success', 'Review submitted!');
setRating('');
setReviewText('');
// Refresh reviews
setReviews(prev => [newReview, ...prev]);
} catch (error) {
Alert.alert('Error', 'Failed to submit review.');
}
};
const renderReview = ({ item }) => (
<View style={styles.reviewItem}>
<Text style={styles.reviewUser}>{item.userName}</Text>
<Text style={styles.reviewRating}>Rating: {item.rating}/5</Text>
<Text>{item.review}</Text>
</View>
);
if (!product) {
return (
<View style={styles.container}>
<Text>Loading...</Text>
</View>
);
}
return (
<View style={styles.container}>
<Text style={styles.productName}>{product.name}</Text>
<Text style={styles.productPrice}>${product.price.toFixed(2)}</Text>
<Text style={styles.productDescription}>{product.description}</Text>
{/* Review Form */}
<View style={styles.reviewForm}>
<Text style={styles.reviewFormTitle}>Leave a Review</Text>
<TextInput
style={styles.input}
placeholder="Rating (1-5)"
keyboardType="numeric"
value={rating}
onChangeText={setRating}
/>
<TextInput
style={[styles.input, styles.textArea]}
placeholder="Write your review here..."
multiline
value={reviewText}
onChangeText={setReviewText}
/>
<Button title="Submit Review" onPress={submitReview} />
</View>
{/* Reviews List */}
<Text style={styles.reviewsTitle}>Reviews</Text>
<FlatList
data={reviews}
renderItem={renderReview}
keyExtractor={(item) => item.id}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 16,
},
productName: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 8,
},
productPrice: {
fontSize: 20,
color: '#888',
marginBottom: 8,
},
productDescription: {
fontSize: 16,
color: '#555',
},
reviewForm: {
marginVertical: 16,
},
reviewFormTitle: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 8,
},
input: {
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 8,
padding: 8,
marginBottom: 8,
},
textArea: {
height: 80,
},
reviewsTitle: {
fontSize: 18,
fontWeight: 'bold',
marginVertical: 16,
},
reviewItem: {
padding: 16,
backgroundColor: '#f9f9f9',
borderRadius: 8,
marginBottom: 8,
borderWidth: 1,
borderColor: '#ddd',
},
reviewUser: {
fontWeight: 'bold',
},
reviewRating: {
color: '#888',
},
});
export default ProductDetail;
Step 3: Testing Product Reviews and Ratings
- Submit a Review:
- Navigate to the product detail page.
- Enter a rating (1-5) and a review text, then submit the review.
- Verify Review in Firestore:
- Go to Firebase Console > Firestore Database.
- Check the
reviews
collection for the new review document.
- View Submitted Reviews:
- Refresh the product detail page to see the review displayed in the reviews section.
Summary
Today, you added functionality for product reviews and ratings to your e-commerce app. Users can now leave reviews and see ratings for products, enhancing user engagement and providing helpful feedback.
Tomorrow, you’ll wrap up the project by deploying the app and tracking analytics with Firebase.