Как загрузить фотографию в хранилище Firebase и вставить URL-адрес фотографии в Firestore?

Моя основная цель в этом модуле - загрузить изображение профиля пользователя в Firebase Storage и сохранить URL-адрес фотографии в Firestore (Cloud Firestore).

Примечание:

  1. Я загружал только изображения в формате JPG и PNG.
  2. Это кроссплатформенное приложение с Ionic и Angular

Я пробую следующий сценарий:

  1. Я напрямую отправить изображение в Firestore, не загружая его в Firebase Cloud Storage, поэтому имя изображения преобразуется в "данные: изображение, base64" с длинными символами в нем, я не знаю, подходит ли этот сценарий для моей базы данных или системы, потому что он работает отлично, и изображения можно восстановить. Надеюсь, вы поможете мне в этом сценарии.

Это поле пользователя:

Как загрузить фотографию в хранилище Firebase и вставить URL-адрес фотографии в Firestore?

Это ошибка возникает, когда я пытаюсь загрузить изображение в хранилище Firebase:

Как загрузить фотографию в хранилище Firebase и вставить URL-адрес фотографии в Firestore?

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>

Я считаю, что вам не нужно использовать FileReader. Вы можете загрузить его напрямую. Проверьте это: stackoverflow.com/questions/46988902/…

yazantahhan 04.04.2021 23:21

Спасибо тебе за это. Но я предполагаю, что проблема в том, что изображение не генерирует URL-адрес загрузки, потому что я проверяю переменную «uploadedImage» и ее значение undefined.

minalisa 05.04.2021 03:46

Но вы проверили, что он был загружен успешно? Вам всегда нужен обратный вызов ошибки, чтобы отловить ошибки в storage.upload.

yazantahhan 05.04.2021 10:56
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
3
29
0

Другие вопросы по теме