Day 3 of 5
⏱ ~60 minutes
Firebase in 5 Days — Day 3

Firebase Storage

Upload images, track progress, get download URLs, and write security rules.

Uploading Files

Upload with progress
import { getStorage, ref, uploadBytesResumable, getDownloadURL } from 'firebase/storage';
const storage = getStorage();

async function uploadImage(file, path) {
  const storageRef = ref(storage, path);
  const uploadTask = uploadBytesResumable(storageRef, file);

  return new Promise((resolve, reject) => {
    uploadTask.on(
      'state_changed',
      (snapshot) => {
        const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
        console.log(`Upload ${progress.toFixed(0)}%`);
      },
      reject,
      async () => {
        const url = await getDownloadURL(uploadTask.snapshot.ref);
        resolve(url);
      }
    );
  });
}

// Usage
const url = await uploadImage(file, `users/${user.uid}/avatar.jpg`);
await updateDoc(doc(db, 'users', user.uid), { avatarUrl: url });
Storage Security Rules
rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    // Users can read/write their own files
    match /users/{userId}/{allPaths=**} {
      allow read: if request.auth != null;
      allow write: if request.auth.uid == userId;
    }
    // Public images readable by all
    match /public/{allPaths=**} {
      allow read: if true;
      allow write: if request.auth != null;
    }
  }
}
📝 Day 3 Exercise
Build File Upload
  1. A
  2. d
  3. d
  4. i
  5. m
  6. a
  7. g
  8. e
  9. u
  10. p
  11. l
  12. o
  13. a
  14. d
  15. t
  16. o
  17. y
  18. o
  19. u
  20. r
  21. b
  22. l
  23. o
  24. g
  25. .
  26. W
  27. h
  28. e
  29. n
  30. a
  31. u
  32. s
  33. e
  34. r
  35. c
  36. r
  37. e
  38. a
  39. t
  40. e
  41. s
  42. a
  43. p
  44. o
  45. s
  46. t
  47. ,
  48. l
  49. e
  50. t
  51. t
  52. h
  53. e
  54. m
  55. u
  56. p
  57. l
  58. o
  59. a
  60. d
  61. a
  62. c
  63. o
  64. v
  65. e
  66. r
  67. i
  68. m
  69. a
  70. g
  71. e
  72. .
  73. S
  74. t
  75. o
  76. r
  77. e
  78. t
  79. h
  80. e
  81. d
  82. o
  83. w
  84. n
  85. l
  86. o
  87. a
  88. d
  89. U
  90. R
  91. L
  92. i
  93. n
  94. F
  95. i
  96. r
  97. e
  98. s
  99. t
  100. o
  101. r
  102. e
  103. w
  104. i
  105. t
  106. h
  107. t
  108. h
  109. e
  110. p
  111. o
  112. s
  113. t
  114. .
  115. D
  116. i
  117. s
  118. p
  119. l
  120. a
  121. y
  122. t
  123. h
  124. e
  125. i
  126. m
  127. a
  128. g
  129. e
  130. i
  131. n
  132. t
  133. h
  134. e
  135. p
  136. o
  137. s
  138. t
  139. l
  140. i
  141. s
  142. t
  143. .

Day 3 Summary

  • ref(storage, path)uploadBytesResumable(ref, file)getDownloadURL().
  • Use uploadBytesResumable over uploadBytes to track upload progress.
  • Storage rules match path segments. Use {userId} to match the authenticated user's folder.
  • Always store the download URL in Firestore, not the path — the URL is what you need to display images.
Finished this lesson?