Estoy tratando de crear un servicio de almacenamiento Firebase desde un cliente angular, que cargará una imagen de perfil de usuario y devolverá los observables uploadProgress$ y DdownloadUrl$.
uploadProgress$ es un Observable que almacenará el valor percentChanges() y downloadUrl$ es un Observable que contendrá el valor getDownloadURL() .
Al vincular uploadProgress$ a angular usando la tubería [value] = "uploadProgress$ | async", devuelve NaN.
Puedo recibir el enlace de la imagen cuando finaliza la carga.
Mi código es el siguiente:
firebase-almacenamiento.servicio
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(), }; } }perfil-de-usuario.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); }); } }perfil-de-usuario.component.html
<div *ngIf="submitted"> <mat-progress-bar [value]="uploadProgress$ | async" mode="determinate"> </mat-progress-bar> </div>const { uploadProgress$, downloadUrl$ } es local. Solo está disponible dentro de la función. Debes crearlo fuera como public .