Learn Firebase Cloud Storage Quickly [Guide]
Firebase Storage is a great way to store all the asset files for your projects in a single place.
You can store pretty much any files such as:
- images,
- videos,
- audio,
- documents, etc
You can also create folders to organize other files or folders.
Uploading files and downloading file URLs are super easy and we can easily protect them using Firebase Storage Security Rules, which is very similar to Cloud Firestore Security Rules.
Table of Contents
- Setting Up Firebase Storage
- Choose An Image
- Upload An Image
- Multiple Storage Buckets
- Get An Image
- Upload Multiple Files
- Get All Images
- Delete A File
- Firebase Storage With Authentication Demo
Enable Firebase Storage
Enable Firebase Storage by clicking the Get Started button after logging into the Firebase account.

The default Cloud StorageSecurity Rule will be set to “only authenticated users can read and write data”,
Click next.

Then, it gives us a warning saying that once the Firebase Cloud Storage bucket is created, the physical location of it can’t be changed.

A Cloud Storage bucket stores all of our files and it ties up to a physical location. For example (us-central from the screenshot above)
Firebase storage allows us to create multiple buckets with different locations.
Click done.

Choose An Image
Choose an image file from a user by attaching a change event to the input element with the type attribute set to file.
HTML
<input type="file" onchange="uploadImage(e)" />
JavaScript
function uploadImage(e) {
const file = e.target.files[0]
console.log(file);
}
Then, we can have access to the actual file and its information using the event object e.target.files[0]

Upload An Image
To upload a file to the Firebase Cloud Storage, we need two pieces of information:
- The location path that we want to upload a file into, and
- The actual File
We can specify the location path as an argument to the ref()
method.
firebase
.storage()
.ref('images/' + file.name)
.put(file);
This will create a folder called images, if it could not find one, and store the actual file inside it with the file name mentioned in the location path after the slash (/).
Then, the put()
method uploads the file that is passed into as an argument to the given location path.
There is another way of specifying the file path, which is using child()
method.
firebase
.storage()
.ref('images')
.child(file.name)
.put(file);
The above code does exactly the same thing as the previous example.
This won’t work if you test it out at this point.
This is because…
By default, Firebase Cloud Storage has security rules in place that can ONLY allow logged-in users to read and write data. 🔒
Let’s change that.
Go to the Storage → Rules tab and change the line from
allow read, write: if request.auth.uid != null;
To
allow read, write: if true;
🛑 Warning: The above security is actually allowing anyone to read and write to the Cloud Storage bucket. I use this for demonstration purposes ONLY.
Multiple Storage Buckets
We can also create multiple buckets with different locations.
If you use multiple storage buckets, you will have to explicitly pass the bucket URL to the storage()
method as an argument.
firebase
.app()
.storage('gs://your-project-name.appspot.com/')
.ref('images')
.child(file.name)
.put(file);
To get the bucket URL, go to Storage → Files → URL (can be found at the top left).

Get An Image URL
To get a single file, specify the path with the folder and file names inside the ref()
method and run getdownloadURL()
method on it.
firebase
.storage()
.ref('images/golden-retriever.jpg')
.getDownloadURL()
.then(imgUrl => {
console.log(imgUrl);
});
The getDownloadURL()
method will return a promise, and the actual file URL will be returned to the then()
callback function specified in the parameter imgUrl
.
Upload Multiple Files
To upload multiple images at once, add the multiple
attribute to the input element.
HTML
<input type="file" onchange="uploadMultipleImages(e)" multiple />
Then, loop through the files object, which is a FileList
object not an actual JavaScript array. So I am using for of
to iterate over and upload it to the Cloud Storage.
forEach()
won’t work as they are not an acutal array and you can convert it to an array like this: Array.prototype.slice.call(files)
JavaScript
function uploadMultipleImages(e) {
let files = e.target.files;
for (const file of files) {
firebase
.storage()
.ref('images')
.child(file.name)
.put(file);
}
}
Get All Images
The listAll()
method will get all the file URLs in a given location path.
firebase
.storage()
.ref('images')
.listAll()
.then(snap => {
snap.items.forEach(itemRef => {
itemRef.getDownloadURL().then(imgUrl => {
console.log(imgUrl)
});
})
})
Inside the then()
callback function, loop through the items
array on the snapshot
object.
Then, call getDownloadURL()
method on the itemRef
object which returns the actual file URLs inside the then()
callback function again specified in the parameter imgUrl
.
Delete A File
Find the location path of a file and delete it using delete()
method.
firebase
.storage()
.ref('images/golden-retriever.jpg')
.delete()
.then(function() {
console.log('File deleted successfully');
}).catch(function(error) {
console.log('error occured');
});
Firebase Storage With Authentication Demo
In this section, you’re going to learn how to upload a profile image with Authentication.
To get this working, I am going to split this into FOUR parts
- Create A New Firebase Account
- Firebase Storage Structure & Security Rules
- Upload Logged-In User’s Profile Picture
- Get Logged-In User’s Profile Picture
Create A New User Account
Enable Email/Password sign-in method: Go to Authentication Tab → Sign-in Method → Choose Email/Password and Enable it.
Here is the simple signup form that has four inputs:
- email,
- password,
- file, and
- signup button
I also have an image element at the bottom to show the profile image once it’s uploaded to the Cloud Storage.
index.html
<!Doctype html>
<head>
<title>Learn Firebase Storage Quickly</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.0/semantic.min.css" />
</head>
<body>
<div class="ui two column middle aligned center aligned grid">
<div class="column">
<form class="ui large form">
<div class="ui stacked secondary segment" >
<div class="field">
<div class="ui left icon input large">
<i class="user icon"></i>
<input type="text" placeholder="E-mail address" id="email" />
</div>
</div>
<div class="field">
<div class="ui left icon input large">
<i class="lock icon"></i>
<input type="text" placeholder="Password" id="pword" />
</div>
</div>
<div class="field">
<div class="ui left icon input large">
<i class="image icon"></i>
<input type="file" id="fileUploader" />
</div>
</div>
<div class=" ui fluid large teal submit button" onclick="signUpUser()">Sign Up</div>
</div>
<div class="ui large image">
<img id="img">
</div>
</form>
</div>
</div>
<script src="https://www.gstatic.com/firebasejs/7.9.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.9.0/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.9.0/firebase-storage.js"></script>
<script src="app.js"></script>
</body>
</html>
I use the Semantic-UI CSS framework for this example.
At the bottom, make sure to add the following Firebase SDKs:
- App
- Authentication, and
- Storage.
⚠️ The latest version of Firebase SDK has some issues with CORS at least at the time of this writing. So make sure to use the Firebase SDK version of 7.9.0 to avoid a CORS issue.

In the JavaScript file, replace the firebaseConfig code with yours. You can find it at Firebase → Project Overview at the top ⚙ → Project Setting → Register App
app.js
var firebaseConfig = {
apiKey: "*****************",
authDomain: "*****************",
databaseURL: "*****************",
projectId: "*****************",
storageBucket: "*****************",
messagingSenderId: "*****************",
appId: "*****************",
measurementId: "*****************"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
const email = document.getElementById('email'),
pword = document.getElementById('pword'),
fileUploader = document.getElementById('fileUploader');
let file = {};
fileUploader.addEventListener('change', function (e) {
file = e.target.files[0];
})
function signUpUser() {
firebase.auth().createUserWithEmailAndPassword(email.value, pword.value).then(auth => {
console.log(auth)
}).catch(error => {
console.log(error.message)
})
}
Once a new user is created, an auth
object will be returned to the then()
callback function specified in the parameter auth
.
Firebase Storage Structure & Security Rules
Before uploading a file to the storage, let’s structure the files in a way that only authenticated users can read and write.
To do that, I am going to create a folder called users then create another folder using the user’s UID as a folder name. Then, store the file in there with the fixed name called profile.jpg.

Assuming I will be only uploading .jpg files just for the simplicity sake.
Go to Firebase Console → Storage Section → Choose Rules Tab from the top.
Then, add the following security rule code in there.
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /users/{uid}/{profileImage} {
allow read, write: if request.auth.uid == uid;
}
}
}
The Cloud Storage security rule below gives any user read and write permission to the location path ( /users/{uid}/{profileImage}
), as long as the logged-in user’s UID (request.auth.uid
) matches with the uid
which is referring to the place holder {uid}
mentioned in the location path.
Upload Logged-In User’s Profile Picture
Once a new user account is created, inside the then()
callback function, upload the profile picture with the user’s UID.
function signUpUser() {
firebase.auth().createUserWithEmailAndPassword(email.value, pword.value).then(auth => {
firebase
.storage()
.ref("users")
.child(auth.user.uid + "/profile.jpg")
.put(file);
}).catch(error => {
console.log(error.message)
})
}
And the file structure should be something like this in the Firebase Storage Dashboard.

Get Logged-In User’s Profile Picture
Invoke onAuthStateChange()
method to check if any user is logged in.
If there is a user, then get the profile picture by calling getDowloadURL()
method.
Inside the then()
callback function, the actual image URL specified in the parameter called imgURL
.
Then, set it to the img
element to display it on the browser.
const img = document.getElementById('img');
firebase.auth().onAuthStateChanged(user => {
if (user) {
firebase
.storage()
.ref("users")
.child(user.uid + "/profile.jpg")
.getDownloadURL()
.then(imgUrl => {
img.src = imgUrl;
});
console.log(user)
}
})

There you have it.
Find the full source code on Github.
If you have any suggestions, feedback or if anything is unclear in this article, please reach out to me by commenting below.
I am looking forward to hearing from you and Happy Coding!