Tutorial: How to upload files using Firebase

Poyah
Poyah
Sep 2, 2018 · 4 min read

Introduction

Firebase uploads files to the Google Cloud Storage (part of the Google Cloud Platform. Unless configured otherwise, the files that are uploaded to Cloud Storage will also be accessible by App Engine; both pieces share the same buckets. Be sure to restrict access to your bucket when setting up authentication.

Getting Started

As usual, start by initializing firebase:

var config = {
apiKey: '<your-api-key>',
authDomain: '<your-auth-domain>',
databaseURL: '<your-database-url>',
storageBucket: '<your-storage-bucket>'
};
firebase.initializeApp(config);var storage = firebase.storage();

Then, with the storage ref, we can do the following

var storageRef = firebase.storage().ref();yiiRef = storageRef.child('yii-ah.jpg');
yiiRef2 = storageRef.child('images/yii-ah.jpg');
// You can access metadata about the file
yiiRef.name === yiiRef2.name
>>> true
yiiRef.fullPath === yiiRef2.fullPath
>>> false

Using File API

The put() method uploads the file; it takes files via a Javascript File or Blob API.

From MDN:

The File interface provides information about files and allows JavaScript in a web page to access their content.

File objects are generally retrieved from a FileList object returned as a result of a user selecting files using the <input> element, from a drag and drop operation's DataTransfer object, or from the mozGetAsFile() API on an HTMLCanvasElement. In Gecko, privileged code can create File objects representing any local file without user interaction (see Implementation notes for more information.)

A File object is a specific kind of a Blob, and can be used in any context that a Blob can. In particular, FileReader, URL.createObjectURL(), createImageBitmap(), and XMLHttpRequest.send() accept both Blobs and Files.

Uploading File

So we need to use the File API in between selecting the file using <input> and uploading it into Cloud Storage:

// Use File/Blob API:
var file = ...
firebase.storage().ref().put(file)
.then(snapshot => {
console.log('Uploaded.');
});

We can also include metadata while uploading:

var metadata = { contentType: 'image/jpeg'};var uploadTask = storageRef.child('images/yii.jpg').put(file, metadata)

Monitor Upload Progress

In firebase, we can also manage the upload process:

var uploadTask = storageRef.child('images/yii.jpg').put(file);uploadTask.pause();
uploadTask.resume();
uploadTask.cancel();

Reacting to Upload Events

While a file is uploading, events may be raised (in the state_changed observer). When an event occurs, a TaskSnapshot object is passed back.

running: fires when a task begins or resumes uploading; used in conjunction with the pause event.pause: fires when upload is paused.progress: fires any time data is uploaded; useful for showing upload progress indicator.

Example of registering an event handler:

var uploadTask = storageRef.child('images/rivers.jpg').put(file);uploadTask.on('state_changed', function(snap) {
var progress = (snap.bytesTransferred / snap.totalBytes) / 100;
switch (snap.state) {
case firebase.storage.TaskState.PAUSED:
console.log('Upload is paused');
break;
case firebase.storage.TaskState.RUNNING:
console.log('Upload is running');
}, function(err) {
switch (error.code) {
case 'storage/unauthorized':
// User doesn't have permission to access the object
break;

case 'storage/canceled':
// User canceled the upload
break;

...

case 'storage/unknown':
// Unknown error occurred, inspect error.serverResponse
break;
}
}, function() {
// handle successful upload on complete
// Example: get the download URL:
uploadTask.snapshot.ref.getDownloadUrl()
.then(function(download_url) {
console.log('File available at', downloadURL)
});
}
});

The TaskSnapshot object is an immutable view of the task at the time of the event, and contains the following information:

bytesTransferredNumber:
The total number of bytes that have been transferred when this snapshot was taken.
totalBytesNumber:
The total number of bytes expected to be uploaded.
statefirebase.storage.TaskState:
Current state of the upload.
metadatafirebaseStorage.Metadata:
Before upload completes, the metadata sent to the server. After upload completes, the metadata the server sent back.
taskfirebaseStorage.UploadTask:
The task this is a snapshot of, which can be used to `pause`, `resume`, or `cancel` the task.
reffirebaseStorage.Reference:
The reference this task came from.

Downloading Files

SRC: https://firebase.google.com/docs/storage/web/download-files

Firstly, we must create a reference to the file we wish to download. There are several ways to create a reference:

var storage = firebase.storage();// 1. Create a ref with an initial file path and name:
var pathRef = storage.ref('images/muimui.jpg');
// 2. Create a ref from Google Cloud Storage URI:
var gsRef = storage.refFromURL('gs://bucket/images/muimui.jpg');
// 3. Create a ref from HTTPS URL (Note: characters are escaped):
var httpsRef = storage.refFromURL('https://firebasestorage.googleapis.com/b/bucket/o/images%20muimui.jpg')

With a created reference, you can download the file:

storageRef.child('images/muimui.jpg').getDownloadURL()
.then(function(url) {
// The serving url can be inserted into an <img>
var img = document.getElementById('muimui');
img.src = url;
// or the file can be directly downloaded:
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function(event) {
var blob = xhr.response;
};
xhr.open('GET', url);
xhr.send();
})
.catch(function(err) {
// A full list of error codes is available at
// https://firebase.google.com/docs/storage/web/handle-errors
switch (error.code) {
case 'storage/object_not_found':
// File doesn't exist
break;
case 'storage/unauthorized':
// User doesn't have permission to access the object
break;
case 'storage/canceled':
// User canceled the upload
break;
...
case 'storage/unknown':
// Unknown error occurred, inspect the server response
break;
})

Deleting Files from Storage

To delete a file, first create a reference to that file. Then call the delete() method on that reference, which returns a Promise that resolves, or an error if the Promise rejects.

var deleteRef = storageRef.child('child/badmind.jpg');deleteRef.delete()
.then(function() {
// file deleted successfully
})
.catch(function(err) {
// handle error
})

Getting Metadata:

SRC: https://firebase.google.com/docs/storage/web/file-metadata

After uploading a file to Cloud Storage reference, you can also get or update the file metadata. By default, Cloud Storage buckets require Firebase Authentication to get and update metadata.

File metadata contains common properties such as name, size, and contentType (often referred to as MIME type) in addition to some less common ones like contentDisposition and timeCreated.

This metadata can be retrieved from a Cloud Storage reference using the getMetadata() method. getMetadata() returns a Promise containing the complete metadata, or an error if the Promise rejects.

var muiRef = storageRef.child('images/muimui.jpg');muiRef.getMetadata()
.then(function(metadata) {
console.log(metadata);
}).catch(function(err){
// handle errors
});

CORS Consideration

To download data directly in the browser, we must configure our Cloud Storage bucket for cross-origin access. This is done using the gsutil command line tool. More info here.

Handling Errors

More about handling errors here.

Poyah

Written by

Poyah

Picking up the pieces

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade