I am trying to build a firebase storage service from an angular client, which will upload a user profile image and return uploadProgress$ and DdownloadUrl$ observables.
uploadProgress$
is a Observable which will store the percentChanges()
value and downloadUrl$
is a Observable which will contain the getDownloadURL()
value.
When binding the uploadProgress$ to angular using the [value] = "uploadProgress$ | async" pipe it returns NaN.
I am able to receive the image link when the upload has finished.
My code is as follows:
firebase-storage.service
import { Injectable } from '@angular/core';
import {
AngularFireStorage,
AngularFireUploadTask,
} from '@angular/fire/compat/storage';
import { finalize, from, Observable, switchMap } from 'rxjs';
import { imageFile } from '../models/file-upload';
interface FilesUploadMetadata {
downloadUrl$: Observable<string>;
uploadProgress$: Observable<number | undefined>;
}
@Injectable({
providedIn: 'root',
})
export class FirebaseStorageService {
constructor(private fireStorage: AngularFireStorage) {}
uploadFileAndGetMetadata(
fileToUpload: imageFile,
mediaFolderPath: string,
userName: string
): FilesUploadMetadata {
const filePath = `${mediaFolderPath}/${userName}_profileImage`;
const storageRef = this.fireStorage.ref(filePath);
const uploadTask: AngularFireUploadTask = this.fireStorage.upload(filePath, fileToUpload);
uploadTask
.snapshotChanges()
.pipe(
finalize(() => {
storageRef.getDownloadURL().subscribe((downloadURL) => {
fileToUpload.url = downloadURL;
fileToUpload.name = fileToUpload.file.name;
});
})
)
.subscribe();
return {
uploadProgress$: uploadTask.percentageChanges(),
downloadUrl$: storageRef.getDownloadURL(),
};
}
}
user-profile.component.ts
upload() {
this.submitted = true;
const file: File = this.selectedFile.item(0) as File;
this.currentFileUpload = new imageFile(file);
const userName = this.currentUser.username;
const mediaFolderPath = `Profile/${this.currentUser.email}/profileImage/`;
const { uploadProgress$, downloadUrl$ } =
this.firebaseService.uploadFileAndGetMetadata(
this.currentFileUpload,
mediaFolderPath,
userName
);
uploadProgress$.subscribe((percent) => {
console.log(typeof percent);
console.log(percent);
});
downloadUrl$.subscribe((downloadUrl) => {
console.log(downloadUrl);
});
}
}
user-profile.component.html
<div *ngIf="submitted">
<mat-progress-bar [value]="uploadProgress$ | async" mode="determinate">
</mat-progress-bar>
</div>
const { uploadProgress$, downloadUrl$ }
is local. It's only available inside the function. You must create it outside as public
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.