【问题标题】:Flutter error with nested firebase GET requests嵌套 Firebase GET 请求的颤振错误
【发布时间】:2021-11-02 12:30:02
【问题描述】:

我正在从事一个健身项目,用户可以在其中进行“锻炼”,并且可以让其中一些锻炼成为最爱。用户的练习和收藏夹存储在 Firebase Firestore 的不同集合中。当我将练习加载到应用程序中时,当我加载它们时,我想检查每个练习,这些练习已被收藏。我想在加载练习的同时执行此操作。所以我创建了以下代码:

Future<void> fetchAndSetExercises() async {
    final List<Exercise> loadedExercises = [];

    final extracted = await _firestore.collection('exercises').get();

    extracted.docs.forEach(
      (exerciseData) async {
        print("EXERCISE DATA: ${exerciseData['title']}");

        // TODO: Get Favorite
        final checkFav = await _firestore
            .collection('favorites')
            .doc('${_firebaseAuth.currentUser.uid}')
            .collection('userFavorites')
            .doc(exerciseData.id)
            .get();
        if (checkFav.exists) {
          print('FOUND A RECORD');
        }

        loadedExercises.add(
          Exercise(
            id: exerciseData.id,
            title: exerciseData['title'],
            description: exerciseData['description'],
            imageUrl: exerciseData['imageUrl'],
            itemUrl: exerciseData['itemUrl'],
            minutes: exerciseData['minutes'],
          ),
        );
      }, // end for each function
    ); // end for each

    _exercises = loadedExercises.toList();

    notifyListeners();
}

在加载提取的练习时,我提出另一个获取请求。所以这段代码中有两个不同的get请求。当我在没有第二个 firebase 获取的情况下运行代码时,它可以正常工作,但是使用第二个获取它会给出错误:

RangeError (index): Invalid value: Valid value range is empty: 0

我还没有找到任何解决方案。也许无法将 Firebase 获取请求嵌套到不同的集合...

如果有人可以帮助澄清这一点或指出我该如何解决这个问题?

【问题讨论】:

  • 标题不要全部大写

标签: flutter dart flutter-dependencies


【解决方案1】:
extracted.docs.forEach(
  (exerciseData) async {

forEach 方法等待您的函数完成,但您的函数是async,这意味着它会立即完成并返回需要awaited 的Future&lt;&gt;。但你不awaitforEach 方法也没有 await 结果。

因此,将您使用 await 的代码从未等待的匿名方法中移出到您的代码主体中:

for(var exerciseData in extracted.docs) {
   print("EXERCISE DATA: ${exerciseData['title']}");

// TODO: Get Favorite
final checkFav = await _firestore
    .collection('favorites')
    .doc('${_firebaseAuth.currentUser.uid}')
    .collection('userFavorites')
    .doc(exerciseData.id)
    .get();
if (checkFav.exists) {
  print('FOUND A RECORD');
}

loadedExercises.add(
  Exercise(
    id: exerciseData.id,
    title: exerciseData['title'],
    description: exerciseData['description'],
    imageUrl: exerciseData['imageUrl'],
    itemUrl: exerciseData['itemUrl'],
    minutes: exerciseData['minutes'],
  ),
);
}

【讨论】: