(Flutter / Dart) Извлекается из хранилища Firebase при извлечении из Firebase Firestore, асинхронно внутри async

#firebase #flutter #dart #google-cloud-firestore #async-await

# #firebase #флаттер #dart #google-cloud-firestore #асинхронный-ожидание

Вопрос:

Я пытаюсь извлечь изображение из хранилища Firebase на основе идентификатора документа, который извлекается из Firebase Firestore. Я сталкиваюсь с проблемой, потому что каждый из этих экземпляров возвращает Future и требует отдельного await / async.

Я не могу использовать Future.wait() , потому что мне нужна первая асинхронность из Firestore для второй асинхронности, но мне также нужна вторая асинхронность для запуска до завершения первой асинхронности (что, я знаю, не так, как работают асинхронные системы). Я попытался создать асинхронную функцию в асинхронной функции, которая просто вела себя как обычно (сначала выполнялась внешняя асинхронная синхронизация, внутренняя асинхронная запускалась второй).

 static Future<List<Recipe>> getFirebaseRecipes() async {
    CollectionReference recipesDatabase = FirebaseFirestore.instance.collection('recipes');

    List<Recipe> recipes = new List();
    recipesDatabase.get().then((querySnapshot) => querySnapshot.docs.map((doc) async {
      Reference ref = FirebaseStorage.instance.ref().child('recipeimages');
      String url = await ref.child(doc.id   '.jpg').getDownloadURL();
      recipes.add(Recipe.fromDBMap(doc.id, url, doc.data()));
    }));
        
    return recipes;
}
 

Вот как я надеялся, что смогу это сделать, но, очевидно, не могу его использовать, поскольку для второго нет асинхронной функции:

 static Future<String> getImageURL(String dbId) async {
    Reference ref = FirebaseStorage.instance.ref().child('recipeimages');
    return await ref.child(dbId   '.jpg').getDownloadURL();
  }

static Future<List<Recipe>> getFirebaseRecipes() async {
    CollectionReference recipesDatabase = FirebaseFirestore.instance.collection('recipes');

    return recipesDatabase.get().then((querySnapshot) => querySnapshot.docs.map((doc) => Recipe.fromDBMap(doc.id, await getImageURL(doc.id), doc.data), doc.data())).toList());
  }
 

Если у кого-нибудь есть какие-либо советы или другой способ, как извлечь объект из хранилища firebase (или даже как сохранить и отобразить в Firestore) Я был бы признателен за помощь!

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

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

2. почему вы не можете использовать первый фрагмент?

3. @PeterHaddad Я пытался его использовать, но он завершает выполнение до завершения второго ожидания, поэтому он добавляет объекты в список после возврата.

Ответ №1:

Попробуйте выполнить следующее:

 static Future<List<Recipe>> getFirebaseRecipes() async {
    CollectionReference recipesDatabase = FirebaseFirestore.instance.collection('recipes');

    List<Recipe> recipes = new List();
    var querySnapshot = await recipesDatabase.get();
      querySnapshot.docs.map((doc) async {
        Reference ref = FirebaseStorage.instance.ref().child('recipeimages');
        String url = await ref.child(doc.id   '.jpg').getDownloadURL();
        recipes.add(Recipe.fromDBMap(doc.id, url, doc.data()));
     }));   
    return recipes;
}
 

Вам нужно использовать await , чтобы дождаться, пока firestore извлечет все данные из базы данных, а затем вы можете использовать результат для получения downloadurl.

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

1. Хм, я пробовал это, он также не выполняет ожидание внутри. В итоге я просто подключил хранилище к Firestore, поэтому требуется только одна асинхронная функция.