1
votes

My stackblitz: https://stackblitz.com/edit/upload-image-ref-firestore?embed=1&file=src/app/app.component.html

I'm using AngularFire2 to upload images, I wonder how I can save that reference of the Firebase Storage image in a firestore document.

enter image description here

I'm trying but all I get is an empty field:

enter image description here

Any idea?

component.ts

import { Component, OnInit, ViewChild  } from '@angular/core';
import { finalize } from 'rxjs/operators';
import { AngularFireStorage } from 'angularfire2/storage';
import { Observable } from 'rxjs';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { FirebaseService } from './services/firebase.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit  {

  tests: Observable<any[]>;
 
  uploadPercent: Observable<number>;
  downloadURL: Observable<string>;

  forma: FormGroup;
  @ViewChild('f') form;

  constructor(fb: FormBuilder, private fs: FirebaseService, private storage: AngularFireStorage ) { 
    this.forma = fb.group ({
      imagenDestacada: [ '', Validators.required],

    })
  }

  ngOnInit() {
    this.tests = this.fs.getTests();
  }

  uploadFile(event) {
    const file = event.target.files[0];
    const filePath = `proyectos4/name1`;
    const fileRef = this.storage.ref(filePath);
    const task = this.storage.upload(filePath, file);

    // observe percentage changes
    this.uploadPercent = task.percentageChanges();
    // get notified when the download URL is available
    task.snapshotChanges().pipe(
        finalize(() => {
        this.downloadURL = fileRef.getDownloadURL()
        this.fs.addTest(this.forma.value)
        console.log( this.downloadURL ) 
      })    
    )
    .subscribe()

  }


}

html

<h2>Test upload ref save in firestore</h2>

<form #f="ngForm" [formGroup]="forma" (ngSubmit)="crearTest()" novalidate>
  <input type="file" (change)="uploadFile($event)" />
  <br>
  <br>
  <div>{{ uploadPercent | async }}</div>
  <br>
  <a [href]="downloadURL | async">{{ downloadURL | async }}</a>
  <br>
  <input type="text" formControlName="imagenDestacada" [value]="downloadURL | async" placeholder="url Image">
  <br>
  <br>
  <!-- <button type="submit" [disabled]="!forma.valid">Crear Test</button> -->
</form>

<hr>

<ul>
  <li *ngFor="let test of tests | async">Imagen: {{test.imagenDestacada}}</li>
</ul>
1
Please copy the relevant code inside the question instead of linking to some other place to view it. - Doug Stevenson
Okay, that's it. - Paco Zevallos

1 Answers

2
votes

Calling fileRef.getDownloadURL() doesn't return a download URL directly. Instead it returns a promise, that resolves when the download URL is available. This means that you need to wait for the promise to resolve before logging the download URL or writing it to the database:

task.snapshotChanges().pipe(
  finalize(() => {
    fileRef.getDownloadURL().then((url) => {
      this.downloadURL = url;
      this.fs.addTest(this.forma.value)
      console.log( this.downloadURL ) 
    });
  })    
)