Как этот метод может возвращать наблюдаемое, на которое может быть подписан вызывающий метод?

#javascript #angular #firebase #rxjs #firebase-storage

#javascript #angular #firebase #rxjs #firebase-хранилище

Вопрос:

Я не очень разбираюсь в Angular и RxJS, и я схожу с ума, пытаясь подписаться на наблюдаемое.

Это мой код:

 createUser(user, file) {
  console.log(user);

  if (user.password != user.password_confirmation) {
    let passwordError: any = new Object();
    passwordError["message"] = "Inserted password and inserted password confirmation are different";
    this.eventAuthError.next(passwordError);
  }
  else {
    this.afAuth.auth.createUserWithEmailAndPassword(user.email, user.password)
      .then(userCredential => {

        console.log("INTO THEN !!!")
        this.newUser = user;
        console.log(userCredential);
        userCredential.user.updateProfile({
          displayName: user.firstName   ' '   user.lastName
        });

        console.log("PROFILE UPDATED !!!");

        this.uploadFileIntoFirebaseStore(file);
      })
  }
}

uploadFileIntoFirebaseStore(fileToBeUploaded) {
  var n = Date.now();
  const filePath = `user_avatar/${n}`;
  const fileRef = this.storage.ref(filePath);

  return this.storage.upload(`user_avatar/${n}`, fileToBeUploaded)
    .snapshotChanges().subscribe(refStatus => {
      console.log("FILE REF: ",
        fileRef.getDownloadURL().subscribe(urlStr => console.log("URL STR:", urlStr)));

      return fileRef.getDownloadURL();
    })
}
  

Как вы можете видеть, метод CreateUser() является моей точкой входа для создания нового пользователя в Firebase (в основном мне нужно создать пользователя по электронной почте и паролю, сохранить файл изображения (который пришел с моей пользовательской страницы формы регистрации пользователя) в хранилище Firebase, а затем создать новый объект в Firebase.FireStore (но в данный момент это не реализовано в этом коде).

Как вы можете видеть в конце моего метода CreateUser(), я выполняю свой метод uploadFileIntoFirebaseStore() с помощью:

 this.uploadFileIntoFirebaseStore(file);
  

Это работает нормально и правильно вставляет файл в хранилище Firebase.

И здесь происходит то, что я не могу понять.

Как вы можете видеть в этом методе, я просто подписываюсь на результат snapshotChanges (), применяемый при загрузке хранилища, который будет «срабатывать», когда загрузка моего файла будет завершена. В эту подписку я возвращаю fileRef.getDownloadURL(), который является Obaservable, который я могу использовать для получения URL-адреса загруженного файла после завершения загрузки.

Хорошо, теперь я должен извлечь это значение (URL загруженного файла) в предыдущий метод CreateUser() (который вызывал этот метод uploadFileIntoFirebaseStore ()), поэтому я попытался изменить это:

 this.uploadFileIntoFirebaseStore(file);
  

с помощью этого:

 this.uploadFileIntoFirebaseStore(file).subscribe( bla => console.log("DO SOMETHING"));
  

И здесь у меня проблема: я не могу подписаться на этот метод. Я думаю, потому что я возвращаю наблюдаемое во внутреннюю функцию со стрелкой, но мой метод ничего не возвращает.

Как я могу исправить эту ситуацию таким образом, чтобы uploadFileIntoFirebaseStore() возвращал наблюдаемое, которое может быть подписано в метод CreateUser() ?

Или я упускаю суть, и мои рассуждения неверны?

Ответ №1:

.subscribe это метод Observable .

 this.storage.upload(`user_avatar/${n}`, fileToBeUploaded).snapshotChanges()
  

Вышеуказанное возвращает Observable , так что вы смогли subscribe .

Но:

 this.storage.upload(`user_avatar/${n}`, fileToBeUploaded).snapshotChanges().subscribe()
  

Вышеуказанное возвращает Subscription , а не Observable так, что вы не можете подписаться.

Подписка — это объект, представляющий доступный ресурс, обычно выполнение наблюдаемого.

https://rxjs-dev.firebaseapp.com/guide/subscription

Решение

Вы можете использовать .pipe switchMap оператор and для обработки результата из Observable объекта snapshotchanges .

 return this.storage.upload(`user_avatar/${n}`, fileToBeUploaded)
    .snapshotChanges()
    .pipe(
        switchMap(refStatus => fileRef.getDownloadURL())
    );
  

https://www.learnrxjs.io/learn-rxjs/operators/transformation/switchmap