How to Upload Photo to Firebase Storage and Insert the Photo URL in Firestore?

My main goal in this module is to upload the profile picture of the user in Firebase Storage and store the Photo URL in the Firestore (Cloud Firestore).

Error Details:

  1. FirebaseError [code=invalid-argument]. DocumentReference.update() called with invalid data. Unsupported field value: undefined (found in field userPhoto in document user/id)

Note:

  1. The images I uploaded is in the JPG and PNG format only.
  2. This is Cross Platform Application with Ionic and Angular

I try the following scenario:

  1. I directly push the image in the Firestore without uploading it in Firebase Cloud Storage so the name of the image is converted into “data:image,base64” with long characters in it, I don’t know if this scenario is okay in my database or system because it runs perfectly, and the images is retrievable. I hope you can help me in this scenario.

This is the field of the user:
image

This is the error occur when I try to upload the image in Firebase Storage:

update-profile.component.ts

  userId: string;
  fname: string;
  studentId: string;


  @ViewChild('filePicker') filePickerRef: ElementRef<HTMLInputElement>;
  @Input() showPreview = true;

  //The Selected Image in the File Explorer
  selectedImage: any;

  //The variable that holds Photo URL
  uploadedImage: any;

   constructor(private auth: AuthService,
              private afs: AngularFirestore,
              private loadingCtrl: LoadingController,
              private toaster: ToastController,
              private storage: AngularFireStorage,
              private popOverCtrl: PopoverController) { }

  ngOnInit() {

    this.profileEditSub = this.auth.user$.subscribe(user => {
      this.userId = user.userId;
      this.fname = user.userName;
      this.studentId = user.userSchoolId;
      this.selectedImage = user.userPhoto;
    });

  }

  onSubmit(form: NgForm){

    const user = form.value.fname;
    const studentId = form.value.studentId;

    this.onUpdateUser(user, studentId);

  }//

  async onUpdateUser(name: string, studentNo: string){
    const loading = await this.loadingCtrl.create({
      message: 'Updating...',
      spinner: 'crescent',
      showBackdrop: true
    });

    //I call this method to upload the Image
    this.uploadUserPhoto();

    loading.present();

    this.afs.collection('user').doc(this.userId).update({
      'userName': name,
      'userSchoolId': studentNo,
      'userPhoto': this.uploadedImage, // Photo URL from Firebase Storage will be saved in here.
      'editedAt': Date.now()
    })
    .then(() => {
      loading.dismiss();
      this.toast('Update Success', 'success');
      this.closePopOver();
    })
    .catch(error => {
      loading.dismiss();
      this.toast(error.message, 'danger');
    })

  }//

  //The method for uploading the photo.
  uploadUserPhoto() {
    var filePath = `${this.userId}/${this.selectedImage.name}_${new Date().getTime()}`;
    const fileRef = this.storage.ref(filePath);
    this.storage.upload(filePath, this.selectedImage).snapshotChanges().pipe(
      finalize(() => {
        fileRef.getDownloadURL().subscribe((url) => {
          this.uploadedImage = url;
        })
      })
    ).subscribe();
  }

  onPickImage() {
    this.filePickerRef.nativeElement.click();
  }

  onFileChosen(event: Event) {
    const pickedFile = (event.target as HTMLInputElement).files[0];

    if (!pickedFile) {
      return;
    }

    const fr = new FileReader();
    fr.onload = () => {
      const dataUrl = fr.result.toString();
      this.selectedImage = dataUrl;
    
    };
    fr.readAsDataURL(pickedFile);
  }

update-profile.component.html

  <!-- For the Image -->
  <div class="picker">
    <img
      class="img"
      [src]="selectedImage"
      *ngIf="selectedImage && showPreview"
    >
  </div>
  <input type="file" accept=".jpg,.png" *ngIf="usePicker" #filePicker (change)="onFileChosen($event)"/>

  <ion-button class="image-btn" (click)="onPickImage()">
    <ion-icon name="camera" slot="icon-only"></ion-icon>
  </ion-button>

  <!-- Other Textual Information -->
  <form #f="ngForm" (ngSubmit)="onSubmit(f)">
    <ion-list lines="full">
      <ion-item>
        <ion-label position="floating">Full Name:</ion-label>
        <ion-input name="fname" required type="text" [(ngModel)]="fname" #userCtrl="ngModel"></ion-input>
      </ion-item>
      <ion-item>
        <ion-label position="floating">Student No:</ion-label>
        <ion-input name="studentId" required type="number" [(ngModel)]="studentId" #studentIds="ngModel"></ion-input>
      </ion-item>

      <ion-button class="ion-margin" type="submit" expand="block" shape="round" [disabled]="!f.valid">Edit User</ion-button>
    </ion-list>
  </form>

Hello,
I have the same problem.

I take a pic and i want to send to Firestore… impossible…
:frowning:

Try this, it works on my project.