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

Commit 819cd1b

Browse files
updated
1 parent dfc6b87 commit 819cd1b

File tree

4 files changed

+165
-134
lines changed

4 files changed

+165
-134
lines changed

body.txt

Lines changed: 90 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,128 +1,137 @@
11

2-
## Description of the Error
2+
## Description of the Problem
33

4-
Developers frequently encounter issues when storing large amounts of data within Firestore, particularly when dealing with rich text posts containing images or videos. Firestore has document size limits (currently 1 MB). Attempting to store a post exceeding this limit results in an error, preventing successful data persistence. This error usually manifests as a `FAILED_PRECONDITION` error in your Firebase console or client-side error logs. The error message might not explicitly mention the size limit but rather indicate a document being too large. This can lead to application crashes or data loss if not handled properly.
4+
A common challenge when using Firebase Firestore to store and retrieve posts, especially those containing images, is managing the size of the data. Storing large images directly in Firestore can lead to slow load times, exceed document size limits (1MB), and increase storage costs significantly. This document details how to handle this by storing images in Firebase Storage and only storing references in Firestore.
55

66

7-
## Fixing Step-by-Step
7+
## Fixing the Problem Step-by-Step
88

9-
This example demonstrates how to handle large posts by storing the main text content directly in Firestore, but storing media (images in this case) in Firebase Storage and only referencing them in Firestore.
9+
This solution uses Firebase Storage to store the images and only stores a reference (download URL) in Firestore.
1010

11+
**Step 1: Setting up Firebase Storage and Firestore**
1112

12-
**Step 1: Project Setup**
13+
Ensure you have properly initialized both Firebase Storage and Firestore in your project. You'll need the necessary SDKs installed and configured. Refer to the official Firebase documentation for guidance:
1314

14-
Ensure you have the Firebase Admin SDK and Firebase Storage SDK installed. If using client-side code (e.g., React, Angular, etc.), install the appropriate client SDKs.
15-
16-
```bash
17-
npm install firebase @firebase/storage
18-
```
15+
* [Firebase Storage Documentation](https://firebase.google.com/docs/storage)
16+
* [Firebase Firestore Documentation](https://firebase.google.com/docs/firestore)
1917

20-
**Step 2: Store Images in Firebase Storage**
18+
**Step 2: Uploading the Image to Firebase Storage**
2119

22-
This function uploads an image to Firebase Storage and returns the download URL.
20+
This code snippet demonstrates uploading an image to Firebase Storage and getting the download URL. Remember to replace `<your-storage-bucket>` with your actual storage bucket name.
2321

2422
```javascript
2523
import { getStorage, ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
2624

27-
async function uploadImage(image, postId) {
25+
async function uploadImage(image) {
2826
const storage = getStorage();
29-
const storageRef = ref(storage, `posts/${postId}/${image.name}`); // Organize images by post ID
27+
const storageRef = ref(storage, `images/${image.name}`); // Generate unique filenames
28+
3029
const uploadTask = uploadBytesResumable(storageRef, image);
3130

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-
reject(error); // Handle unsuccessful uploads
50-
},
51-
() => {
52-
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
53-
resolve(downloadURL);
54-
});
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+
switch (error.code) {
49+
case 'storage/unauthorized':
50+
// User doesn't have permission to access the object
51+
console.error("Unauthorized access to storage");
52+
break;
53+
case 'storage/canceled':
54+
// User canceled the upload
55+
console.error("Upload canceled");
56+
break;
57+
case 'storage/unknown':
58+
// Unknown error occurred, inspect error.serverResponse
59+
console.error("Unknown error: ", error);
60+
break;
5561
}
56-
);
57-
});
62+
},
63+
() => {
64+
// Handle successful uploads on complete
65+
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
66+
console.log('File available at', downloadURL);
67+
return downloadURL; //return the download url
68+
});
69+
}
70+
);
5871
}
59-
```
60-
6172

62-
**Step 3: Store Post Data in Firestore**
6373

64-
This function creates a Firestore document containing post metadata and image URLs.
74+
//Example usage:
75+
const file = document.getElementById('imageInput').files[0];
76+
uploadImage(file).then(url => {
77+
//Store the URL in Firestore
78+
console.log("Image URL:",url)
79+
}).catch(error => {
80+
console.error("Error uploading image:", error);
81+
});
6582

66-
```javascript
67-
import { getFirestore, collection, addDoc } from "firebase/firestore";
68-
69-
async function createPost(postData, imageURLs) {
70-
const db = getFirestore();
71-
const docRef = await addDoc(collection(db, "posts"), {
72-
title: postData.title,
73-
content: postData.content, // Main text content
74-
images: imageURLs, // Array of image URLs from Storage
75-
timestamp: new Date(), // Add a timestamp
76-
});
77-
console.log("Document written with ID: ", docRef.id);
78-
}
7983
```
8084

85+
**Step 3: Storing the Image URL in Firestore**
8186

82-
**Step 4: Integrate and Use the Functions**
83-
87+
After successfully uploading the image, store only the download URL in your Firestore post document.
8488

8589
```javascript
86-
// ... (Import necessary functions and modules) ...
90+
import { collection, addDoc } from "firebase/firestore"; //Import necessary functions
91+
import { db } from "./firebaseConfig"; // Your Firebase configuration
92+
8793

88-
async function handlePostCreation(postData, images) {
89-
const imageURLs = [];
94+
async function addPost(postTitle, imageUrl) {
9095
try {
91-
for (const image of images) {
92-
const url = await uploadImage(image, postData.id); // Assuming postData has an id
93-
imageURLs.push(url);
94-
}
95-
await createPost(postData, imageURLs);
96-
} catch (error) {
97-
console.error("Error creating post:", error);
98-
// Handle error appropriately (e.g., display an error message to the user)
96+
const docRef = await addDoc(collection(db, "posts"), {
97+
title: postTitle,
98+
imageUrl: imageUrl, // Store only the download URL
99+
//other post details...
100+
});
101+
console.log("Document written with ID: ", docRef.id);
102+
} catch (e) {
103+
console.error("Error adding document: ", e);
99104
}
100105
}
106+
```
101107

108+
**Step 4: Retrieving and Displaying the Image**
102109

103-
// Example usage:
104-
const postData = {
105-
id: 'uniquePostId', //Generate unique ID
106-
title: "My Awesome Post",
107-
content: "This is the main text content of my post.",
108-
};
110+
When retrieving posts, use the stored URL to display the image using an `<img>` tag.
109111

110-
const images = [ /* Array of File objects representing images */ ];
111112

112-
handlePostCreation(postData, images);
113+
```javascript
114+
//In your component, after retrieving the post data from Firestore:
113115

116+
<img src={post.imageUrl} alt={post.title} />
114117
```
115118

116119

117120
## Explanation
118121

119-
This solution leverages Firebase Storage to handle large files (images) separately from the main post data stored in Firestore. By referencing the image URLs in Firestore, we avoid exceeding the document size limits. This approach maintains data integrity and improves performance as Firestore only needs to retrieve smaller, metadata-rich documents.
122+
This approach significantly improves performance and reduces storage costs by:
123+
124+
* **Offloading storage:** Large images are stored in a service optimized for storing and serving binary data.
125+
* **Reduced document size:** Firestore documents remain small, leading to faster reads and writes.
126+
* **Scalability:** Firebase Storage handles scaling automatically, allowing for efficient handling of a large number of images.
127+
* **Better caching:** Browsers and CDNs can cache images efficiently.
128+
120129

121130
## External References
122131

123-
* [Firestore Data Storage Limits](https://firebase.google.com/docs/firestore/quotas)
124-
* [Firebase Storage Documentation](https://firebase.google.com/docs/storage)
125-
* [Firebase Admin SDK](https://firebase.google.com/docs/admin/setup)
132+
* [Firebase Storage Security Rules](https://firebase.google.com/docs/storage/security) - Important for securing your image storage.
133+
* [Firebase Storage Client Libraries](https://firebase.google.com/docs/storage/libraries) - Choose the appropriate client library for your platform.
134+
* [Firebase Firestore Data Model](https://firebase.google.com/docs/firestore/data-model) - Understand the structure of Firestore documents.
126135

127136

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

0 commit comments

Comments
 (0)