Skip to content
This repository was archived by the owner on Sep 10, 2025. It is now read-only.

Commit d37ba7f

Browse files
updated
1 parent a6e5252 commit d37ba7f

File tree

4 files changed

+173
-145
lines changed

4 files changed

+173
-145
lines changed

body.txt

Lines changed: 95 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,117 @@
11

2-
This challenge focuses on creating a responsive image card using CSS. The card will feature a subtle hover effect, showcasing the power of CSS transitions and transforms. We'll use standard CSS3 for this example, but the principles can easily be adapted to frameworks like Tailwind CSS.
2+
## Description of the Error
3+
4+
Developers often encounter issues when storing large amounts of data, particularly rich media like images within their posts in Firestore. Firestore has document size limits (currently 1 MB). Attempting to store large images directly within a Firestore document for each post will lead to errors if the combined size of the post data and image(s) exceeds this limit. This results in a failure to write the document to Firestore, often manifesting as an error message indicating a document size exceeding the limit or a general write failure.
5+
6+
## Fixing the Problem: Step-by-Step Code
7+
8+
This solution uses Cloud Storage for images and stores only references to the images in Firestore.
9+
10+
**Step 1: Upload Images to Cloud Storage**
11+
12+
First, we'll use the Firebase Admin SDK to upload images to Cloud Storage. This code assumes you already have a Firebase project set up and the necessary credentials configured.
13+
14+
```javascript
15+
const { initializeApp } = require('firebase/app');
16+
const { getStorage, ref, uploadBytesResumable, getDownloadURL } = require('firebase/storage');
17+
18+
// Your Firebase configuration
19+
const firebaseConfig = {
20+
// ... your firebase config ...
21+
};
22+
23+
const app = initializeApp(firebaseConfig);
24+
const storage = getStorage(app);
25+
26+
async function uploadImage(file, postID) {
27+
const storageRef = ref(storage, `posts/${postID}/${file.name}`);
28+
const uploadTask = uploadBytesResumable(storageRef, file);
29+
30+
return new Promise((resolve, reject) => {
31+
uploadTask.on('state_changed',
32+
(snapshot) => {
33+
// Observe state change events such as progress, pause, and resume
34+
// Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
35+
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
36+
console.log('Upload is ' + progress + '% done');
37+
switch (snapshot.state) {
38+
case 'paused':
39+
console.log('Upload is paused');
40+
break;
41+
case 'running':
42+
console.log('Upload is running');
43+
break;
44+
}
45+
},
46+
(error) => {
47+
// Handle unsuccessful uploads
48+
reject(error);
49+
},
50+
() => {
51+
// Handle successful uploads on complete
52+
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
53+
resolve(downloadURL);
54+
});
55+
}
56+
);
57+
});
58+
}
359

4-
**Description of the Styling:**
560

6-
The card will contain an image, a title, and a short description. On hover, the card will subtly scale up and add a shadow, providing a visual cue to the user. The card will also be responsive, adjusting its size and layout gracefully across different screen sizes.
61+
//Example Usage
62+
const file = /* your image file */; //replace with actual file
63+
const postID = 'yourPostID'; // replace with your post ID
764

65+
uploadImage(file, postID).then((downloadURL) => {
66+
console.log('File available at', downloadURL);
67+
//Store downloadURL in Firestore
68+
}).catch((error) => {
69+
console.error('Upload failed:', error);
70+
});
871

9-
**Full Code:**
72+
```
1073

11-
```html
12-
<!DOCTYPE html>
13-
<html>
14-
<head>
15-
<title>Responsive Image Card</title>
16-
<style>
17-
.card {
18-
width: 300px;
19-
margin: 20px auto;
20-
border-radius: 8px;
21-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
22-
overflow: hidden;
23-
transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
24-
}
2574

26-
.card img {
27-
width: 100%;
28-
height: auto;
29-
display: block; /* Prevents extra space below image */
30-
}
75+
**Step 2: Store Image URLs in Firestore**
3176

32-
.card-content {
33-
padding: 15px;
34-
}
77+
After uploading, store only the Cloud Storage URLs in your Firestore documents. This keeps document sizes small.
3578

36-
.card-title {
37-
font-size: 1.2em;
38-
margin-bottom: 5px;
39-
}
79+
```javascript
80+
import { getFirestore, doc, setDoc } from "firebase/firestore";
81+
const db = getFirestore(app);
4082

41-
.card-description {
42-
font-size: 0.9em;
43-
color: #555;
83+
async function createPost(postID, text, imageUrl) {
84+
try {
85+
await setDoc(doc(db, "posts", postID), {
86+
text: text,
87+
imageUrl: imageUrl,
88+
// ... other post data
89+
});
90+
} catch (error) {
91+
console.error("Error adding document: ", error);
92+
}
4493
}
4594

46-
.card:hover {
47-
transform: scale(1.02);
48-
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
49-
cursor: pointer; /* Indicate interactivity */
50-
}
5195

52-
/* Responsive adjustments - adjust as needed for different breakpoints */
53-
@media (max-width: 768px) {
54-
.card {
55-
width: 90%;
56-
}
57-
}
58-
</style>
59-
</head>
60-
<body>
61-
62-
<div class="card">
63-
<img src="https://via.placeholder.com/300x200" alt="Placeholder Image">
64-
<div class="card-content">
65-
<h2 class="card-title">Card Title</h2>
66-
<p class="card-description">This is a sample card description. You can add more text here.</p>
67-
</div>
68-
</div>
69-
70-
</body>
71-
</html>
96+
//Example Usage:
97+
const postID = 'yourPostID';
98+
const text = "This is your post";
99+
const imageUrl = 'yourImageURL';
100+
101+
createPost(postID, text, imageUrl);
72102
```
73103

74-
**Explanation:**
75104

76-
* **`.card`:** This class styles the overall card container. `box-shadow` provides a subtle shadow, `border-radius` rounds the corners, and `transition` smoothly animates the hover effect.
77-
* **`.card img`:** Ensures the image fits the container's width while maintaining aspect ratio. `display: block` removes extra space below the image.
78-
* **`.card-content`:** Styles the text content within the card.
79-
* **`.card-title` and `.card-description`:** Styles the title and description.
80-
* **`.card:hover`:** This selector applies styles specifically when the card is hovered over, creating the scaling and shadow effect.
81-
* **`@media (max-width: 768px)`:** This media query applies responsive adjustments for smaller screens. You can add more media queries for other breakpoints.
105+
## Explanation
106+
107+
This approach leverages Cloud Storage's scalability to handle large files. Firestore is best suited for structured data and metadata, not large binary files. By separating image storage from your post data in Firestore, you avoid exceeding document size limits. The application fetches the images from Cloud Storage only when needed for display, optimizing performance and storage costs.
82108

83109

84-
**Links to Resources to Learn More:**
110+
## External References
85111

86-
* **CSS Transitions and Transforms:** [MDN Web Docs - CSS Transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/transition), [MDN Web Docs - CSS Transforms](https://developer.mozilla.org/en-US/docs/Web/CSS/transform)
87-
* **CSS Media Queries:** [MDN Web Docs - CSS Media Queries](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries)
88-
* **More CSS Challenges:** (Search for "CSS challenges" or "CSS grid challenges" on websites like Codewars, Frontend Mentor, or freeCodeCamp)
112+
* [Firestore Data Types and Limits](https://firebase.google.com/docs/firestore/quotas)
113+
* [Firebase Storage Documentation](https://firebase.google.com/docs/storage)
114+
* [Firebase Admin SDK](https://firebase.google.com/docs/admin/setup)
89115

90116

91117
Copyrights (c) OpenRockets Open-source Network. Free to use, copy, share, edit or publish.

errors/javascript/handling-firestore-data-limits-when-storing-large-posts-with-images/README.md

Lines changed: 76 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -3,115 +3,117 @@
33

44
## Description of the Error
55

6-
A common issue when using Firebase Firestore to store blog posts or similar content with images is exceeding Firestore's document size limits. Firestore documents have a maximum size of 1 MB. If you're storing large images directly within the document, or have a very large amount of text, you'll quickly hit this limit. This leads to errors during write operations, preventing your application from saving the post. The specific error message might vary, but it will generally indicate a data size exceeding the limit.
6+
Developers often encounter issues when storing large amounts of data, particularly rich media like images within their posts in Firestore. Firestore has document size limits (currently 1 MB). Attempting to store large images directly within a Firestore document for each post will lead to errors if the combined size of the post data and image(s) exceeds this limit. This results in a failure to write the document to Firestore, often manifesting as an error message indicating a document size exceeding the limit or a general write failure.
77

8-
## Fixing the Problem Step-by-Step
8+
## Fixing the Problem: Step-by-Step Code
99

10-
This solution involves storing images separately in Firebase Storage and referencing them in Firestore. This approach keeps your Firestore documents small and manageable while still allowing you to associate images with your posts.
10+
This solution uses Cloud Storage for images and stores only references to the images in Firestore.
1111

12-
**Step 1: Upload Images to Firebase Storage**
12+
**Step 1: Upload Images to Cloud Storage**
1313

14-
First, upload your images to Firebase Storage. This requires the Firebase Storage SDK. The following code snippet demonstrates uploading an image using the JavaScript SDK. Remember to replace placeholders like `<your-storage-bucket>` with your actual values.
14+
First, we'll use the Firebase Admin SDK to upload images to Cloud Storage. This code assumes you already have a Firebase project set up and the necessary credentials configured.
1515

1616
```javascript
17-
import { getStorage, ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
18-
19-
const storage = getStorage(); // Initialize Firebase Storage
20-
21-
async function uploadImage(image, postId) {
22-
const storageRef = ref(storage, `posts/${postId}/${image.name}`); // Create a reference to the image location
23-
24-
const uploadTask = uploadBytesResumable(storageRef, image); // Start uploading the image
25-
26-
uploadTask.on('state_changed',
27-
(snapshot) => {
28-
// Observe state change events such as progress, pause, and resume
29-
// Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
30-
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
31-
console.log('Upload is ' + progress + '% done');
32-
switch (snapshot.state) {
33-
case 'paused':
34-
console.log('Upload is paused');
35-
break;
36-
case 'running':
37-
console.log('Upload is running');
38-
break;
17+
const { initializeApp } = require('firebase/app');
18+
const { getStorage, ref, uploadBytesResumable, getDownloadURL } = require('firebase/storage');
19+
20+
// Your Firebase configuration
21+
const firebaseConfig = {
22+
// ... your firebase config ...
23+
};
24+
25+
const app = initializeApp(firebaseConfig);
26+
const storage = getStorage(app);
27+
28+
async function uploadImage(file, postID) {
29+
const storageRef = ref(storage, `posts/${postID}/${file.name}`);
30+
const uploadTask = uploadBytesResumable(storageRef, file);
31+
32+
return new Promise((resolve, reject) => {
33+
uploadTask.on('state_changed',
34+
(snapshot) => {
35+
// Observe state change events such as progress, pause, and resume
36+
// Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
37+
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
38+
console.log('Upload is ' + progress + '% done');
39+
switch (snapshot.state) {
40+
case 'paused':
41+
console.log('Upload is paused');
42+
break;
43+
case 'running':
44+
console.log('Upload is running');
45+
break;
46+
}
47+
},
48+
(error) => {
49+
// Handle unsuccessful uploads
50+
reject(error);
51+
},
52+
() => {
53+
// Handle successful uploads on complete
54+
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
55+
resolve(downloadURL);
56+
});
3957
}
40-
},
41-
(error) => {
42-
// Handle unsuccessful uploads
43-
console.error("Error uploading image:", error);
44-
},
45-
() => {
46-
// Handle successful uploads on complete
47-
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
48-
console.log('File available at', downloadURL);
49-
// Use the downloadURL to update your Firestore document
50-
return downloadURL;
51-
});
52-
}
53-
);
58+
);
59+
});
5460
}
5561

5662

57-
// Example Usage:
58-
const image = /* Your image file object */;
59-
const postId = 'yourPostId';
60-
61-
uploadImage(image, postId)
62-
.then(downloadURL => {
63-
//Now you can store this downloadURL in firestore
64-
})
65-
.catch(error => console.error("Error uploading and getting URL", error));
63+
//Example Usage
64+
const file = /* your image file */; //replace with actual file
65+
const postID = 'yourPostID'; // replace with your post ID
6666

67+
uploadImage(file, postID).then((downloadURL) => {
68+
console.log('File available at', downloadURL);
69+
//Store downloadURL in Firestore
70+
}).catch((error) => {
71+
console.error('Upload failed:', error);
72+
});
6773

6874
```
6975

70-
**Step 2: Update Firestore Document with Image URL**
7176

72-
Once the image is uploaded, retrieve the download URL and store it in your Firestore document. This URL acts as a reference to the image.
77+
**Step 2: Store Image URLs in Firestore**
78+
79+
After uploading, store only the Cloud Storage URLs in your Firestore documents. This keeps document sizes small.
7380

7481
```javascript
75-
import { collection, addDoc } from "firebase/firestore";
76-
import { db } from './firebaseConfig' //Import your Firestore instance
82+
import { getFirestore, doc, setDoc } from "firebase/firestore";
83+
const db = getFirestore(app);
7784

78-
async function addPostToFirestore(postData, imageUrl){
85+
async function createPost(postID, text, imageUrl) {
7986
try {
80-
const docRef = await addDoc(collection(db, "posts"), {
81-
title: postData.title,
82-
content: postData.content,
87+
await setDoc(doc(db, "posts", postID), {
88+
text: text,
8389
imageUrl: imageUrl,
8490
// ... other post data
8591
});
86-
console.log("Document written with ID: ", docRef.id);
87-
} catch (e) {
88-
console.error("Error adding document: ", e);
92+
} catch (error) {
93+
console.error("Error adding document: ", error);
8994
}
9095
}
9196

9297

93-
// Example Usage (after successful uploadImage call):
94-
const postData = {
95-
title: "My Awesome Post",
96-
content: "This is the content of my awesome post...",
97-
// ... other post data
98-
};
99-
100-
addPostToFirestore(postData, downloadURL); //Pass the download URL here.
101-
98+
//Example Usage:
99+
const postID = 'yourPostID';
100+
const text = "This is your post";
101+
const imageUrl = 'yourImageURL';
102102

103+
createPost(postID, text, imageUrl);
103104
```
104105

106+
105107
## Explanation
106108

107-
This solution follows a common pattern for handling large files in NoSQL databases like Firestore. By separating the image data from the document data, we avoid exceeding the size limits. Firestore is optimized for storing structured data, while Firebase Storage is ideal for storing unstructured binary data like images and videos. Using this approach, you maintain a clean, efficient data model and avoid potential errors related to exceeding document size limits.
109+
This approach leverages Cloud Storage's scalability to handle large files. Firestore is best suited for structured data and metadata, not large binary files. By separating image storage from your post data in Firestore, you avoid exceeding document size limits. The application fetches the images from Cloud Storage only when needed for display, optimizing performance and storage costs.
108110

109111

110112
## External References
111113

112-
* **Firebase Storage Documentation:** [https://firebase.google.com/docs/storage](https://firebase.google.com/docs/storage)
113-
* **Firebase Firestore Documentation:** [https://firebase.google.com/docs/firestore](https://firebase.google.com/docs/firestore)
114-
* **Firebase JavaScript SDK:** [https://firebase.google.com/docs/web/setup](https://firebase.google.com/docs/web/setup)
114+
* [Firestore Data Types and Limits](https://firebase.google.com/docs/firestore/quotas)
115+
* [Firebase Storage Documentation](https://firebase.google.com/docs/storage)
116+
* [Firebase Admin SDK](https://firebase.google.com/docs/admin/setup)
115117

116118

117119
Copyrights (c) OpenRockets Open-source Network. Free to use, copy, share, edit or publish.

0 commit comments

Comments
 (0)