Cloud Storage
Cloud Storage holds binary files (images, video, PDFs). The SDK signs upload requests so users go DIRECT to Google’s servers; rules gate who can read / write.
Upload, download, list, security
EXAMPLE
import { initializeApp } from 'firebase/app';
import {
getStorage, ref, uploadBytes, uploadBytesResumable,
getDownloadURL, deleteObject, listAll,
} from 'firebase/storage';
const storage = getStorage(initializeApp(firebaseConfig));
// 1) Simple upload
async function uploadAvatar(uid, file) {
const r = ref(storage, \`avatars/${uid}/${file.name}\`);
const result = await uploadBytes(r, file, {
contentType: file.type,
customMetadata: { uploadedBy: uid },
});
return getDownloadURL(result.ref);
}
// 2) Resumable upload with progress + pause
function uploadWithProgress(uid, file, onProgress) {
const task = uploadBytesResumable(
ref(storage, \`uploads/${uid}/${crypto.randomUUID()}\`),
file,
);
task.on('state_changed',
(snap) => {
const pct = (snap.bytesTransferred / snap.totalBytes) * 100;
onProgress(pct);
},
(err) => console.error(err),
async () => {
const url = await getDownloadURL(task.snapshot.ref);
console.log('done', url);
},
);
return task; // task.pause() / task.resume() / task.cancel()
}
// 3) List + download URLs
async function listAvatars(uid) {
const r = ref(storage, \`avatars/${uid}/\`);
const { items, prefixes } = await listAll(r);
return Promise.all(items.map(i => getDownloadURL(i)));
}
// 4) Delete
await deleteObject(ref(storage, \`avatars/${uid}/old.png\`));
// 5) Security rules — enforce size / type / ownership
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /avatars/{uid}/{name=**} {
allow read: if true; // public read
allow write: if request.auth != null &&
request.auth.uid == uid &&
request.resource.size < 5 * 1024 * 1024 &&
request.resource.contentType.matches('image/.*');
}
match /private/{uid}/{name=**} {
allow read, write: if request.auth != null && request.auth.uid == uid;
}
}
}
// 6) Process on upload — Cloud Function trigger
export const onAvatarUpload = onObjectFinalized(
{ region: 'us-east1' },
async (event) => {
if (!event.data.name.startsWith('avatars/')) return;
// thumbnail it, scan for malware, etc.
},
);
Why it matters
Always validate contentType + size in rules. Without them, anyone with auth uploads 10 GB malware files to your bucket and you pay the bandwidth + storage bills.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
import { getStorage, ref, uploadBytes, getDownloadURL } from 'firebase/storage';
const storage = getStorage(app);
const r = ref(storage, 'avatars/' + uid + '.png');
await uploadBytes(r, file);
const url = await getDownloadURL(r);
Try it Yourself »
Discussion
Loading…