Firebase Storage: putString возвращает нулевой URL

У меня проблема с восстановлением URL-адреса после putString в хранилище. Я хочу сохранить фотографию, сделанную пользователем, и сохранить некоторые метаданные, URL-адрес фотографии и идентификатор пользователя в моем bdd.

Мое приложение не выдает ошибку, изображение загружается в мое хранилище firebase, а моя модель сохраняется в fireBase, но восстановленный URL-адрес равен нулю.

Смотрите мой код: Моя служба хранения

    import * as firebase from 'firebase';

export class StorageService {

  public static readonly CHILD_PATH = '/photos/';
  public static readonly FORMAT = '.jpg';
  public static readonly BASE = 'base64';
  public static readonly CONTENT_TYPE = 'image/jpg';

  constructor() {}

  savePhoto(data: string): string{

    let fileName = new Date().getTime().toString();
    let downloadUrl: string = null;

    let baseReference = firebase.storage().ref();
    let childReference = baseReference.child(StorageService.CHILD_PATH + fileName + StorageService.FORMAT);
    let task = childReference.putString(data, StorageService.BASE, {contentType:StorageService.CONTENT_TYPE});
    task
      .then(snapshot => snapshot.ref.getDownloadURL())
      .then(url => downloadUrl = url)
      .catch(
      (error) => {
        throw new Error(error.toString());
      }
    );

    return downloadUrl;
  }
}

Мои изображения

import {Injectable} from "@angular/core";
import {Picture} from "../models/Picture.model";
import {Subject} from "rxjs";

import * as firebase from 'firebase';
import DataSnapshot = firebase.database.DataSnapshot;
import {Platform} from "ionic-angular";
import {StorageService} from "./Storage.service";

@Injectable()
export class PictureService {

  pictures: Picture[] = [];
  picturesSubject = new Subject<Picture[]>();

  constructor(private platform: Platform,
              private storageService: StorageService){

    this.platform.ready().then(() => {
      this.getPictures();
    });
  }

  emitPictures() {
    this.picturesSubject.next(this.pictures);
  }

  savePictures() {
    firebase.database().ref('/pictures').set(this.pictures);
  }

  getPictures() {
    firebase.database().ref('/pictures').on('value', (data: DataSnapshot) => {
      this.pictures = data.val() ? data.val() : [];
      this.emitPictures();
    });
  }

  createNewPicture(newPicture: Picture, data: string) {
    try{
      let  url = this.storageService.savePhoto(data);
      newPicture.setUrl(url);
      this.pictures.push(newPicture);
      this.savePictures();
      this.emitPictures();
    } catch (e) {
      throw new Error(e.toString());
    }
  }
}

Спасибо за вашу помощь.

putString является асинхронным и возвращает обещание, и все следующие блоки then также являются асинхронными. Это означает, что вы возвращаете URL-адрес загрузки до того, как вся работа будет завершена. Вам придется научиться правильно работать с обещаниями, возможно, используя async / await.
Doug Stevenson 30.10.2018 19:23

Да, Дуг Стивенсон, это асинхронный метод, но .then должен выполняться после обработки, нет?

Jeremy Caillié 30.10.2018 19:38

Да, и он также возвращает обещание с асинхронным разрешением. Каждый раз, когда вы получаете обещание, он отслеживает некоторую асинхронную работу. Правила не меняются.

Doug Stevenson 30.10.2018 20:21

Хорошо, прочитав статью, я понял свою ошибку. Я изменил свой код, чтобы вернуть обещание в моей службе хранилища, а не URL-адрес, который не готов. Это решит мою проблему. Спасибо, Дуг Стивенсон, за уделенное время.

Jeremy Caillié 30.10.2018 21:30
Интеграция Angular - Firebase Analytics
Интеграция Angular - Firebase Analytics
Узнайте, как настроить Firebase Analytics и отслеживать поведение пользователей в вашем приложении Angular.
0
4
15
0

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