#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();
}