Relaying upload progress engages user attention. Assembling a few Angular Material components and using Firebase storage, the UI can present the ability to start, pause, cancel, and display progress of a file upload.
If you recall the days before the SPA pattern (Single Page Applications) emerged, the traditional method for uploading files posted an entire form. The form wrote the file content to the request stream leaving the browser to appear hanging. There's no difference in the request today, but no simple method existed to relay the progress of the upload back to the user.
In this tutorial, you'll learn how to use Angular Material Components that upload files to Firebase.
1. Model a File Upload Interface and Upload Service Contract
2. Create a Firebase Upload Service
3. Implement a SCAM File Upload Component and Upload List Component
4. Configure the Upload Service Module and AngularFire for Firebase
5. Run the Application and Upload Files
To follow along in this tutorial, use the GumRoad link below.
Create a File Upload Interface and Service Contract
FileUpload contains information about the file chosen and the status of the HTTP request.
||A unique identifier for the file upload|
||Name of the chosen file|
||The percentage the upload is complete|
||The status of the file upload|
||The content type of the file e.g.
||Optional path value for where the file will be stored on the server|
FileUploadStatus enumerates the status of the file upload including
The upload service contract provides flexibility for choosing an implementation.
Firebase is specific to
Google Cloud, so changing to a different cloud provider, say
Amazon's S3 storage, would involve creating another
UploadService that implements the
UploadService implementations, swapping the dependency eases the pain of changing a specific reference as we can inject an
IFileuploadService interface. You'll learn to configure this in the Implement File Upload Components and the Configure Upload Service Module sections.
|Property / Method||Description|
||An observable property that keeps reference of files uploads by their id|
||Starts an upload by a specific
||Adds files to the object of
||Removes the file from the object of
Create Firebase Upload Service
FirebaseUploadService handles uploading files to
AngularFireStorage class injects into the constructor from the
AngularFireStorage handles the upload into
Firebase. Below, I explain the
methods of the
|Property Name||Access Modifier||Type||Description|
||Keeps track of the
||Keeps track of all the files|
||Readonly object of FileUploads|
||Transforms files to the
||Creates the task in
||Removes a file from the queue and cancels any tasks that may have been running.|
upload method finds the file by it's id in the
queuedFiles$ property. Using the
fileStorage creates an
AngularFireTask by calling the
upload method. The generated task appends to our
tasks property, and the
fileUpload's status updates to
task.snapshotChanges is an observable that emits the changes in state of the uploading file. The
filter operator in this case checks if the value is
notEmpty and primarily I added this for testing purposes. The
map operator transforms the value emitted to a
FileUpload. Once the observable completes, the
finalize operator removes the current task from the
Subscribing to changes invokes the upload. As values are emitted, the
queuedFiles$ property updates the
fileUpload in it's dictionary.
Implement File Upload Components
A couple of SCAM (Single Component Angular Module) modules drive consistency in display and upload service.
NgServeFileUploadModule imports the
MatProgressModule to support the
FileUploadComponent presentation component.
FileUploadComponent consumes one
fileUpload. It's responsible for displaying the progress, file name, and percentage upload to the user. The
mat-progress-bar reads the
fileUpload.percentageUploaded to reflect upload progress.
FileUploadListModule follows the same SCAM pattern. The
FileUploadListComponent depends on the
MatButtonModule and the
MatIconModule and are added to the
imports of the
FileUploadListModule provides flexibility for you to choose which implementation of the
IFileUploadService to consume in the
FileUploadListComponent. The static method
configure defines the
IFileUploadService to be injected into the
FileUploadListComponent orchestrates the user's actions having them choose files to upload, and start / remove uploads.
In the markup of the
FileUploadListComponent, a list of the files selected displays each file for upload using the
ng-serve-file-upload component. Underneath, two
mat-icon-buttons empower the user to start an upload or remove the file from the list.
Toward the bottom of the markup, styling the file input involves hiding the element and invoking the click method from an Angular Material button. On the
file input, notice the identifier
#fileListUpload. When the
Choose Files material button is clicked, the
#fileListUpload's click event invokes in the component typescript
fileListUpload property exposes an
ElementRef to the
#fileListUpload file input. So when the
Choose Files material button click event fires, the
chooseFiles method invokes the click event on the
#fileListUpload file input.
||Makes a reference to the file input in the component|
||A reference to the
||The files stored in state of the
||An event handler for the change in files from the
||Invokes the upload for a particular file|
||Removes the file state of the file upload service|
Configure Upload Service Module
Configuring the upload service empowers you to choose the implementation of a file upload service. Recall this pattern offers flexibility for you swap upload services that implement the
NgServeIoFeatureModule configures the
The application module lazy loads the
NgServeIoFeatureFormModule through route configuration via the
forms route. Ensure that the
AngularFireModule initializes the app with your
Firebase web configuration options. Below you'll find that the
Firebase configuration exists as a property in the environment for the
If you're unsure where to find the
Firebase configuration properties for your application, go the console, open your project and click the gear icon shown in the graphic below. Scroll down on that page, and the configuration should appear under the
SDK setup and configuration section.
Run the File Upload Application
If you were following along using the
Nx Starter Monorepo, start the application by running the command below.
npx nx serve ng-serve-io-ng-serve
Go to the path http://localhost:4200/forms/file-upload-list. You'll be able to add files, upload to Firebase, and remove files once completed.
Should you find a
403 error on upload, ensure the
read/write for your files. By default, requests made to storage deny unauthorized requests. For testing purposes, set the
allow read, write: if true;. Once you've completed testing, change the rule back to
request.auth != null to prevent unauthorized file uploads.
You learned how to create an upload component with Angular Material that uploads to
Firebase. Many options exist for unstructured file storage, so an abstraction using the
IFileUploadService interface allows different implementations based on requirements.