getDownloadURL — значение типа ‘Future’ не может быть присвоено переменной типа ‘String’

#firebase #flutter #firebase-storage

#firebase #flutter #firebase-хранилище

Вопрос:

Я следовал этому руководству https://www.youtube.com/watch?v=HCmAwk2fnZc и все заработало в отношении загрузки / обрезки / etc, Но мне нужно иметь возможность получить ImageUrl после завершения загрузки изображения. Я видел примеры онлайн, где вся загрузка выполняется асинхронно, а затем вы можете просто дождаться URL-адреса с приведенным ниже кодом, однако в этом примере загрузка не выполняется асинхронно… я новичок в этом, но я предполагаю, что это потому, что они показывают процент загрузки.

Я пытаюсь вызвать приведенное ниже, но я получаю сообщение об ошибке «Значение типа ‘Future’ не может быть присвоено переменной типа ‘String'».

   Future getImageURL() async {
    StorageReference ref = FirebaseStorage.instance.ref().child("/$docID");
    var url = (await ref.getDownloadURL()).toString();
    return url;
  }

String imageURL;
imageURL = getImageURL();
  

Загрузка запускается через:

   StorageUploadTask _uploadTask;

  void _startUpload(){
    String filePath = '$docID';

    setState(() {
      _uploadTask = _storage.ref().child(filePath).putFile(widget.file);
    });

  }
  

Затем есть StreamBuilder, который использует _uploadTask, который в рамках этого, в .IsComplete я хочу иметь возможность вызывать URL изображения.

 StreamBuilder<StorageTaskEvent>(
      stream: _uploadTask.events,
      builder: (context, snapshot) {
        var event = snapshot?.data?.snapshot;

        double progressPercent = event != null ? event.bytesTransferred / 
event.totalByteCount : 0;

        if (_uploadTask.isComplete){             

        }
  

Мне нужно знать, как вызвать функцию async после загрузки файла (_uploadTask.IsComplete), а затем дождаться получения downloadUrl.

Любой совет был бы замечательным!

Спасибо!

Ответ №1:

При использовании Futures для извлечения данных использование await перед функцией при ее вызове позволяет приложению узнать, что функция является асинхронной функцией, и оно должно дождаться ее завершения.

 String imageURL = await getImageURL();
  

Приведенный ниже код предназначен для доступа к URL-адресу загрузки в StreamBuilder

 StreamBuilder(
      stream: _uploadTask.events,
      builder: (BuildContext context, snapshot) {
          final StorageTaskEvent event = snapshot.data;
          final StorageTaskSnapshot snap = event.snapshot;
          double progressPercent = (event.bytesTransferred / event.totalByteCount) ?? 0;
          String downloadUrl = snap.ref.getDownloadURL();
        
      },
    );
  

Комментарии:

1. К сожалению, это не вариант, потому что загрузка выполняется не асинхронно, поэтому я не могу использовать await … загружаемая часть кода является void _startUpload(){ String filePath = ‘$docID’; setState(() { _uploadTask = _storage.ref().child(filePath).PutFile(widget.file); }); }

2. возможно, вы захотите добавить это к своему вопросу

3. оно есть… «Я видел примеры онлайн, где вся загрузка выполняется асинхронно, а затем вы можете просто дождаться URL-адреса с приведенным ниже кодом, однако в этом примере загрузка не выполняется асинхронно ..»

4. Я говорю, что вы должны добавить свой код _startUpload к своему вопросу. Независимо от того, была ли загрузка выполнена асинхронно или нет, ваш getImageURL() является Future , поэтому для этого требуется ожидание, как сказано в моем ответе

5. Спасибо за помощь, и я добавил больше из кода. Извините, я новичок в flutter и stackoverflow. Меня смущает то, как мне вызвать async getImageURL из построителя потоков?

Ответ №2:

Попробуйте это.

 StreamBuilder<StorageTaskEvent>(
      stream: _uploadTask.events,
      builder: (context, snapshot) {
        var event = snapshot?.data?.snapshot;

        double progressPercent = event != null ? event.bytesTransferred / event.totalByteCount : 0;

        if (_uploadTask.isComplete){
          String imageUrl = await getImageUrl();
        }