Take a second to think about this
Instead of practicing Storage, Query, and Security Rules — the later chapters of this tutorial — one at a time, this lesson has you combine all of them into a single real app flow. At this stage, it's important to know how to upload a file, save its Storage URL back into a Firestore document, and combine query filters using where/orderBy. What makes this harder than earlier lessons is that you'll be designing the entire data flow end-to-end on your own. You'll also need to write Security Rules that restrict editing and deleting to the owner only.
Exercises
Task 1 — Upload a user's profile avatar image to Storage, then use the URL you get back from getDownloadURL to update the avatarUrl field on that user's document in the users collection. Task 2 — Create a posts collection and add a bunch of post documents that each include authorId and createdAt fields. Then write a query that combines where('authorId','==',uid) with orderBy('createdAt','desc'). Task 3 — Write Firestore Security Rules so that only the post's owner can update/delete a post document, then verify that a non-owner trying to edit it gets back a permission-denied error. Task 4 (Bonus) — Add a restriction in your Storage Rules using request.resource.size so uploads are rejected if the image is bigger than 2MB.
Code Example
// Task skeleton — ကိုယ်တိုင်ဖြည့်စွက်ရန်
import { storage, db } from "./firebase-config";
import { ref, uploadBytes, getDownloadURL } from "firebase/storage";
import {
collection,
doc,
updateDoc,
query,
where,
orderBy,
getDocs,
} from "firebase/firestore";
// Task 1: Avatar upload
async function uploadAvatar(uid, file) {
const avatarRef = ref(storage, `avatars/${uid}.jpg`);
await uploadBytes(avatarRef, file);
const url = await getDownloadURL(avatarRef);
// TODO: users/{uid} document ထဲ avatarUrl update လုပ်ပါ
}
// Task 2: Compound query
async function getMyPosts(uid) {
const q = query(
collection(db, "posts"),
where("authorId", "==", uid),
orderBy("createdAt", "desc")
);
const snap = await getDocs(q);
return snap.docs.map((d) => ({ id: d.id, ...d.data() }));
}
// Task 3: Security Rules (firestore.rules ဖိုင်ထဲရေးရန်)
// match /posts/{postId} {
// allow update, delete: if request.auth.uid == resource.data.authorId;
// }The avatar image gets uploaded and shows up on the profile; the query returns only the user's own posts, sorted correctly; and if someone who isn't the post owner tries to edit it, Firestore sends back a permission-denied error.Try It in 5 Minutes
In the next 5 minutes, take the single Security Rules line from Task 3 into the Firebase Console Rules Playground, simulate a request with a mismatched owner uid, and check whether it actually gets denied.
A Quick Word of Caution
If you skip adding a file size limit to your Storage Rules, users can upload huge files and your storage costs can climb higher than you'd expect — keep that in mind.