In today's lesson, I will show you how to use Angular 4 to easily upload files to Firebase Storage. Dealing with file uploads can be a developer nightmare, so using a Backend-as-a-Service (BaaS) can be a good choice to speed up development time.
Note: This lesson is adapted from the AngularFirebase File Upload Tutorial.
Lesson Checkpoints
Watch the Angular File Upload Screencast
Start by watching the file upload screencast for Angular 4 and Firebase. This will provide a high level overview of what is required to get your app up and running.
Generate the Service with the Angular CLI
We will handle uploads in the service layer, which will allow us to bootstrap these functions into any component. You can generate a service by running:
ng g service uploads/shared/service
We will also need the Firebase API in the service. Here's how to import the API into the app.
import * as firebase from 'firebase';
Create an Upload Task
The upload task will handle the bulk of uploading logic. It works by using creating a promise to put the file in storage. You can then monitor the progress of this promise to retrieve a snapshot of the bytes transferred. The function will also catch the error/success state of the promise.
@Injectable()
export class UploadService {
constructor(private af: AngularFire, private db: AngularFireDatabase) { }
private basePath:string = '/uploads';
private uploadTask: firebase.storage.UploadTask;
uploads: FirebaseListObservable;
pushUpload(upload: Upload) {
let storageRef = firebase.storage().ref();
this.uploadTask = storageRef.child(`${this.basePath}/${upload.file.name}`).put(upload.file);
this.uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED,
(snapshot) => {
// upload in progress
upload.progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
},
(error) => {
// upload failed
console.log(error)
},
() => {
// upload success
upload.url = this.uploadTask.snapshot.downloadURL
upload.name = upload.file.name
this.saveFileData(upload)
}
);
}
// Writes the file details to the realtime db
private saveFileData(upload: Upload) {
this.db.list(`${this.basePath}/`).push(upload);
}